mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	Base for 4.3 work. Split Nadeko.Common into a separate project
This commit is contained in:
		@@ -1,45 +0,0 @@
 | 
			
		||||
using System.Buffers;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
// made for expressions because they almost never get added
 | 
			
		||||
// and they get looped through constantly
 | 
			
		||||
public static class ArrayExtensions
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Create a new array from the old array + new element at the end
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="input">Input array</param>
 | 
			
		||||
    /// <param name="added">Item to add to the end of the output array</param>
 | 
			
		||||
    /// <typeparam name="T">Type of the array</typeparam>
 | 
			
		||||
    /// <returns>A new array with the new element at the end</returns>
 | 
			
		||||
    public static T[] With<T>(this T[] input, T added)
 | 
			
		||||
    {
 | 
			
		||||
        var newExprs = new T[input.Length + 1];
 | 
			
		||||
        Array.Copy(input, 0, newExprs, 0, input.Length);
 | 
			
		||||
        newExprs[input.Length] = added;
 | 
			
		||||
        return newExprs;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Creates a new array by applying the specified function to every element in the input array
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="arr">Array to modify</param>
 | 
			
		||||
    /// <param name="f">Function to apply</param>
 | 
			
		||||
    /// <typeparam name="TIn">Orignal type of the elements in the array</typeparam>
 | 
			
		||||
    /// <typeparam name="TOut">Output type of the elements of the array</typeparam>
 | 
			
		||||
    /// <returns>New array with updated elements</returns>
 | 
			
		||||
    public static TOut[] Map<TIn, TOut>(this TIn[] arr, Func<TIn, TOut> f)
 | 
			
		||||
        => Array.ConvertAll(arr, x => f(x));
 | 
			
		||||
 | 
			
		||||
    public static TOut[] Map<TIn, TOut>(this IReadOnlyCollection<TIn> col, Func<TIn, TOut> f)
 | 
			
		||||
    {
 | 
			
		||||
        var toReturn = new TOut[col.Count];
 | 
			
		||||
        
 | 
			
		||||
        var i = 0;
 | 
			
		||||
        foreach (var item in col)
 | 
			
		||||
            toReturn[i++] = f(item);
 | 
			
		||||
 | 
			
		||||
        return toReturn;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,109 +0,0 @@
 | 
			
		||||
using NadekoBot.Common.Collections;
 | 
			
		||||
using NadekoBot.Services.Database.Models;
 | 
			
		||||
using System.Security.Cryptography;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
public static class EnumerableExtensions
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Concatenates the members of a collection, using the specified separator between each member.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="data">Collection to join</param>
 | 
			
		||||
    /// <param name="separator">
 | 
			
		||||
    ///     The character to use as a separator. separator is included in the returned string only if
 | 
			
		||||
    ///     values has more than one element.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="func">Optional transformation to apply to each element before concatenation.</param>
 | 
			
		||||
    /// <typeparam name="T">The type of the members of values.</typeparam>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    ///     A string that consists of the members of values delimited by the separator character. -or- Empty if values has
 | 
			
		||||
    ///     no elements.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    public static string Join<T>(this IEnumerable<T> data, char separator, Func<T, string>? func = null)
 | 
			
		||||
        => string.Join(separator, data.Select(func ?? (x => x?.ToString() ?? string.Empty)));
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Concatenates the members of a collection, using the specified separator between each member.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="data">Collection to join</param>
 | 
			
		||||
    /// <param name="separator">
 | 
			
		||||
    ///     The string to use as a separator.separator is included in the returned string only if values
 | 
			
		||||
    ///     has more than one element.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <param name="func">Optional transformation to apply to each element before concatenation.</param>
 | 
			
		||||
    /// <typeparam name="T">The type of the members of values.</typeparam>
 | 
			
		||||
    /// <returns>
 | 
			
		||||
    ///     A string that consists of the members of values delimited by the separator character. -or- Empty if values has
 | 
			
		||||
    ///     no elements.
 | 
			
		||||
    /// </returns>
 | 
			
		||||
    public static string Join<T>(this IEnumerable<T> data, string separator, Func<T, string>? func = null)
 | 
			
		||||
        => string.Join(separator, data.Select(func ?? (x => x?.ToString() ?? string.Empty)));
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Randomize element order by performing the Fisher-Yates shuffle
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <typeparam name="T">Item type</typeparam>
 | 
			
		||||
    /// <param name="items">Items to shuffle</param>
 | 
			
		||||
    public static IReadOnlyList<T> Shuffle<T>(this IEnumerable<T> items)
 | 
			
		||||
    {
 | 
			
		||||
        using var provider = RandomNumberGenerator.Create();
 | 
			
		||||
        var list = items.ToList();
 | 
			
		||||
        var n = list.Count;
 | 
			
		||||
        while (n > 1)
 | 
			
		||||
        {
 | 
			
		||||
            var box = new byte[(n / byte.MaxValue) + 1];
 | 
			
		||||
            int boxSum;
 | 
			
		||||
            do
 | 
			
		||||
            {
 | 
			
		||||
                provider.GetBytes(box);
 | 
			
		||||
                boxSum = box.Sum(b => b);
 | 
			
		||||
            } while (!(boxSum < n * (byte.MaxValue * box.Length / n)));
 | 
			
		||||
 | 
			
		||||
            var k = boxSum % n;
 | 
			
		||||
            n--;
 | 
			
		||||
            (list[k], list[n]) = (list[n], list[k]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Initializes a new instance of the <see cref="ConcurrentDictionary{TKey,TValue}" /> class
 | 
			
		||||
    ///     that contains elements copied from the specified <see cref="IEnumerable{T}" />
 | 
			
		||||
    ///     has the default concurrency level, has the default initial capacity,
 | 
			
		||||
    ///     and uses the default comparer for the key type.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="dict">
 | 
			
		||||
    ///     The <see cref="IEnumerable{T}" /> whose elements are copied to the new
 | 
			
		||||
    ///     <see cref="ConcurrentDictionary{TKey,TValue}" />.
 | 
			
		||||
    /// </param>
 | 
			
		||||
    /// <returns>A new instance of the <see cref="ConcurrentDictionary{TKey,TValue}" /> class</returns>
 | 
			
		||||
    public static ConcurrentDictionary<TKey, TValue> ToConcurrent<TKey, TValue>(
 | 
			
		||||
        this IEnumerable<KeyValuePair<TKey, TValue>> dict)
 | 
			
		||||
        where TKey : notnull
 | 
			
		||||
        => new(dict);
 | 
			
		||||
 | 
			
		||||
    public static IndexedCollection<T> ToIndexed<T>(this IEnumerable<T> enumerable)
 | 
			
		||||
        where T : class, IIndexed
 | 
			
		||||
        => new(enumerable);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Creates a task that will complete when all of the <see cref="Task{TResult}" /> objects in an enumerable
 | 
			
		||||
    ///     collection have completed
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="tasks">The tasks to wait on for completion.</param>
 | 
			
		||||
    /// <typeparam name="TResult">The type of the completed task.</typeparam>
 | 
			
		||||
    /// <returns>A task that represents the completion of all of the supplied tasks.</returns>
 | 
			
		||||
    public static Task<TResult[]> WhenAll<TResult>(this IEnumerable<Task<TResult>> tasks)
 | 
			
		||||
        => Task.WhenAll(tasks);
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    ///     Creates a task that will complete when all of the <see cref="Task" /> objects in an enumerable
 | 
			
		||||
    ///     collection have completed
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="tasks">The tasks to wait on for completion.</param>
 | 
			
		||||
    /// <returns>A task that represents the completion of all of the supplied tasks.</returns>
 | 
			
		||||
    public static Task WhenAll(this IEnumerable<Task> tasks)
 | 
			
		||||
        => Task.WhenAll(tasks);
 | 
			
		||||
}
 | 
			
		||||
@@ -5,6 +5,7 @@ using System.Globalization;
 | 
			
		||||
using System.Net.Http.Headers;
 | 
			
		||||
using System.Text.Json;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
@@ -145,20 +146,6 @@ public static class Extensions
 | 
			
		||||
    public static IEmbedBuilder WithErrorColor(this IEmbedBuilder eb)
 | 
			
		||||
        => eb.WithColor(EmbedColor.Error);
 | 
			
		||||
 | 
			
		||||
    public static HttpClient AddFakeHeaders(this HttpClient http)
 | 
			
		||||
    {
 | 
			
		||||
        AddFakeHeaders(http.DefaultRequestHeaders);
 | 
			
		||||
        return http;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void AddFakeHeaders(this HttpHeaders dict)
 | 
			
		||||
    {
 | 
			
		||||
        dict.Clear();
 | 
			
		||||
        dict.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
 | 
			
		||||
        dict.Add("User-Agent",
 | 
			
		||||
            "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static IMessage DeleteAfter(this IUserMessage msg, int seconds, ILogCommandService? logService = null)
 | 
			
		||||
    {
 | 
			
		||||
        Task.Run(async () =>
 | 
			
		||||
@@ -203,23 +190,6 @@ public static class Extensions
 | 
			
		||||
    public static IEnumerable<IRole> GetRoles(this IGuildUser user)
 | 
			
		||||
        => user.RoleIds.Select(r => user.Guild.GetRole(r)).Where(r => r is not null);
 | 
			
		||||
 | 
			
		||||
    public static bool IsImage(this HttpResponseMessage msg)
 | 
			
		||||
        => IsImage(msg, out _);
 | 
			
		||||
 | 
			
		||||
    public static bool IsImage(this HttpResponseMessage msg, out string? mimeType)
 | 
			
		||||
    {
 | 
			
		||||
        mimeType = msg.Content.Headers.ContentType?.MediaType;
 | 
			
		||||
        if (mimeType is "image/png" or "image/jpeg" or "image/gif")
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static long GetContentLength(this HttpResponseMessage msg)
 | 
			
		||||
        => msg.Content.Headers.ContentLength is long length
 | 
			
		||||
            ? length
 | 
			
		||||
            : long.MaxValue;
 | 
			
		||||
 | 
			
		||||
    public static void Lap(this Stopwatch sw, string checkpoint)
 | 
			
		||||
    {
 | 
			
		||||
        Log.Information("Checkpoint {CheckPoint}: {Time}ms", checkpoint, sw.Elapsed.TotalMilliseconds);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,5 @@
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
public static class MessageChannelExtensions
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public delegate TOut PipeFunc<TIn, out TOut>(in TIn a);
 | 
			
		||||
public delegate TOut PipeFunc<TIn1, TIn2, out TOut>(in TIn1 a, in TIn2 b);
 | 
			
		||||
 | 
			
		||||
public static class PipeExtensions
 | 
			
		||||
{
 | 
			
		||||
    public static TOut Pipe<TIn, TOut>(this TIn a, Func<TIn, TOut> fn)
 | 
			
		||||
        => fn(a);
 | 
			
		||||
    
 | 
			
		||||
    public static TOut Pipe<TIn, TOut>(this TIn a, PipeFunc<TIn, TOut> fn)
 | 
			
		||||
        => fn(a);
 | 
			
		||||
    
 | 
			
		||||
    public static TOut Pipe<TIn1, TIn2, TOut>(this (TIn1, TIn2) a, PipeFunc<TIn1, TIn2, TOut> fn)
 | 
			
		||||
        => fn(a.Item1, a.Item2);
 | 
			
		||||
 | 
			
		||||
    public static (TIn, TExtra) With<TIn, TExtra>(this TIn a, TExtra b)
 | 
			
		||||
        => (a, b);
 | 
			
		||||
    
 | 
			
		||||
    public static async Task<TOut> Pipe<TIn, TOut>(this Task<TIn> a, Func<TIn, TOut> fn)
 | 
			
		||||
        => fn(await a);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
// // Copyright (c) .NET Foundation. All rights reserved.
 | 
			
		||||
// // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 | 
			
		||||
// // https://github.com/aspnet/Common/blob/dev/shared/Microsoft.Extensions.Process.Sources/ProcessHelper.cs
 | 
			
		||||
//
 | 
			
		||||
// using System.Diagnostics;
 | 
			
		||||
// using System.Runtime.InteropServices;
 | 
			
		||||
//
 | 
			
		||||
// namespace NadekoBot.Extensions;
 | 
			
		||||
//
 | 
			
		||||
// public static class ProcessExtensions
 | 
			
		||||
// {
 | 
			
		||||
//     private static readonly bool _isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
 | 
			
		||||
//     private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(10);
 | 
			
		||||
//
 | 
			
		||||
//     public static void KillTree(this Process process)
 | 
			
		||||
//         => process.KillTree(_defaultTimeout);
 | 
			
		||||
//
 | 
			
		||||
//     public static void KillTree(this Process process, TimeSpan timeout)
 | 
			
		||||
//     {
 | 
			
		||||
//         if (_isWindows)
 | 
			
		||||
//             RunProcessAndWaitForExit("taskkill", $"/T /F /PID {process.Id}", timeout, out _);
 | 
			
		||||
//         else
 | 
			
		||||
//         {
 | 
			
		||||
//             var children = new HashSet<int>();
 | 
			
		||||
//             GetAllChildIdsUnix(process.Id, children, timeout);
 | 
			
		||||
//             foreach (var childId in children)
 | 
			
		||||
//                 KillProcessUnix(childId, timeout);
 | 
			
		||||
//
 | 
			
		||||
//             KillProcessUnix(process.Id, timeout);
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
//
 | 
			
		||||
//     private static void GetAllChildIdsUnix(int parentId, ISet<int> children, TimeSpan timeout)
 | 
			
		||||
//     {
 | 
			
		||||
//         var exitCode = RunProcessAndWaitForExit("pgrep", $"-P {parentId}", timeout, out var stdout);
 | 
			
		||||
//
 | 
			
		||||
//         if (exitCode == 0 && !string.IsNullOrEmpty(stdout))
 | 
			
		||||
//         {
 | 
			
		||||
//             using var reader = new StringReader(stdout);
 | 
			
		||||
//             while (true)
 | 
			
		||||
//             {
 | 
			
		||||
//                 var text = reader.ReadLine();
 | 
			
		||||
//                 if (text is null)
 | 
			
		||||
//                     return;
 | 
			
		||||
//
 | 
			
		||||
//                 if (int.TryParse(text, out var id))
 | 
			
		||||
//                 {
 | 
			
		||||
//                     children.Add(id);
 | 
			
		||||
//                     // Recursively get the children
 | 
			
		||||
//                     GetAllChildIdsUnix(id, children, timeout);
 | 
			
		||||
//                 }
 | 
			
		||||
//             }
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
//
 | 
			
		||||
//     private static void KillProcessUnix(int processId, TimeSpan timeout)
 | 
			
		||||
//         => RunProcessAndWaitForExit("kill", $"-TERM {processId}", timeout, out _);
 | 
			
		||||
//
 | 
			
		||||
//     private static int RunProcessAndWaitForExit(
 | 
			
		||||
//         string fileName,
 | 
			
		||||
//         string arguments,
 | 
			
		||||
//         TimeSpan timeout,
 | 
			
		||||
//         out string? stdout)
 | 
			
		||||
//     {
 | 
			
		||||
//         stdout = null;
 | 
			
		||||
//
 | 
			
		||||
//         var startInfo = new ProcessStartInfo
 | 
			
		||||
//         {
 | 
			
		||||
//             FileName = fileName,
 | 
			
		||||
//             Arguments = arguments,
 | 
			
		||||
//             RedirectStandardOutput = true,
 | 
			
		||||
//             UseShellExecute = false
 | 
			
		||||
//         };
 | 
			
		||||
//
 | 
			
		||||
//         using var process = Process.Start(startInfo);
 | 
			
		||||
//
 | 
			
		||||
//         if (process is null)
 | 
			
		||||
//             return -1;
 | 
			
		||||
//
 | 
			
		||||
//         if (process.WaitForExit((int)timeout.TotalMilliseconds))
 | 
			
		||||
//             stdout = process.StandardOutput.ReadToEnd();
 | 
			
		||||
//         else
 | 
			
		||||
//             process.Kill();
 | 
			
		||||
//
 | 
			
		||||
//         return process.ExitCode;
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
@@ -1,4 +1,6 @@
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
public static class SocketMessageComponentExtensions
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ using NadekoBot.Common.Yml;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using Nadeko.Common;
 | 
			
		||||
 | 
			
		||||
namespace NadekoBot.Extensions;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user