mirror of
				https://gitlab.com/Kwoth/nadekobot.git
				synced 2025-11-04 00:34:26 -05:00 
			
		
		
		
	Cleaned up some unused/commented code
- Small amount of refactoring - Separated imagesharp extension to ImageSharpExtensions.cs - Using .join Ienumerable extension instead of string.join in some places
This commit is contained in:
		@@ -158,7 +158,7 @@ namespace {namespaceName}
 | 
				
			|||||||
        {{
 | 
					        {{
 | 
				
			||||||
            return new {classSymbol.Name}
 | 
					            return new {classSymbol.Name}
 | 
				
			||||||
            {{
 | 
					            {{
 | 
				
			||||||
{string.Join($",{Environment.NewLine}", fieldAssignmentsCodeFast)}
 | 
					{string.Join(",\n", fieldAssignmentsCodeFast)}
 | 
				
			||||||
            }};
 | 
					            }};
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -174,7 +174,7 @@ namespace {namespaceName}
 | 
				
			|||||||
            referenceChain.Push(this);
 | 
					            referenceChain.Push(this);
 | 
				
			||||||
            var result = new {classSymbol.Name}
 | 
					            var result = new {classSymbol.Name}
 | 
				
			||||||
            {{
 | 
					            {{
 | 
				
			||||||
{string.Join($",{Environment.NewLine}", fieldAssignmentsCodeSafe)}
 | 
					{string.Join($",\n", fieldAssignmentsCodeSafe)}
 | 
				
			||||||
            }};
 | 
					            }};
 | 
				
			||||||
            referenceChain.Pop();
 | 
					            referenceChain.Pop();
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,57 +96,6 @@ public class CmdAttribute : System.Attribute
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // private static void GenerateFileFromModel(in SourceProductionContext ctx, IGrouping<string, DataModel> @group)
 | 
					 | 
				
			||||||
    // {
 | 
					 | 
				
			||||||
    //     using var sw = new StringWriter();
 | 
					 | 
				
			||||||
    //     using var tw = new IndentedTextWriter(sw);
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    //     foreach (var model in group)
 | 
					 | 
				
			||||||
    //     {
 | 
					 | 
				
			||||||
    //         tw.WriteLine($"public partial {model.ReturnType} {model.MethodName}({string.Join(", ", model.Params)});");
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    //     GenerateFileFromModel(ctx, sw.ToString(), group.Key, group.AsEnumerable());
 | 
					 | 
				
			||||||
    //     
 | 
					 | 
				
			||||||
    //     
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // private static void GenerateFileFromModel(SourceProductionContext ctx, string innerContent, string groupName, IEnumerable<DataModel> modelsEnum)
 | 
					 | 
				
			||||||
    // {
 | 
					 | 
				
			||||||
    //     using var sw = new StringWriter();
 | 
					 | 
				
			||||||
    //     using var tw = new IndentedTextWriter(sw);
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    //     var models = modelsEnum.ToList();
 | 
					 | 
				
			||||||
    //     var referenceModel = models.First();
 | 
					 | 
				
			||||||
    //     tw.WriteLine($"namespace {referenceModel.Namespace};");
 | 
					 | 
				
			||||||
    //     
 | 
					 | 
				
			||||||
    //     foreach (var className in referenceModel.ClassNames.Reverse().ToList())
 | 
					 | 
				
			||||||
    //     {
 | 
					 | 
				
			||||||
    //         tw.WriteLine($"public partial class {className}");
 | 
					 | 
				
			||||||
    //         tw.WriteLine("{");
 | 
					 | 
				
			||||||
    //         tw.WriteLine();
 | 
					 | 
				
			||||||
    //         tw.Indent ++;
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //     
 | 
					 | 
				
			||||||
    //     foreach (var model in models)
 | 
					 | 
				
			||||||
    //     {
 | 
					 | 
				
			||||||
    //         tw.WriteLine($"public partial {model.ReturnType} {model.MethodName}({string.Join(", ", model.Params)});");
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //     
 | 
					 | 
				
			||||||
    //     foreach (var _ in referenceModel.ClassNames)
 | 
					 | 
				
			||||||
    //     {
 | 
					 | 
				
			||||||
    //         tw.Indent --;
 | 
					 | 
				
			||||||
    //         tw.WriteLine("}");
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //     
 | 
					 | 
				
			||||||
    //     // tw.Indent--;
 | 
					 | 
				
			||||||
    //     // tw.WriteLine("}");
 | 
					 | 
				
			||||||
    //     tw.Flush();
 | 
					 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    //     ctx.AddSource($"{groupName}.qwertyus.g.cs",
 | 
					 | 
				
			||||||
    //         SourceText.From(sw.ToString(), Encoding.UTF8));
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static string GetSourceText(FileModel model)
 | 
					    private static string GetSourceText(FileModel model)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        using var sw = new StringWriter();
 | 
					        using var sw = new StringWriter();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
using System.Security.Cryptography;
 | 
					using System.Security.Cryptography;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Common;
 | 
					namespace NadekoBot.Common;
 | 
				
			||||||
// todo minby maxby
 | 
					
 | 
				
			||||||
public class NadekoRandom : Random
 | 
					public class NadekoRandom : Random
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private readonly RandomNumberGenerator _rng;
 | 
					    private readonly RandomNumberGenerator _rng;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ using NadekoBot.Db;
 | 
				
			|||||||
namespace NadekoBot.Modules.Administration.Services;
 | 
					namespace NadekoBot.Modules.Administration.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// todo dateonly timeonly
 | 
					// todo dateonly timeonly
 | 
				
			||||||
// todo new apis
 | 
					// todo timer
 | 
				
			||||||
public class GameVoiceChannelService : INService
 | 
					public class GameVoiceChannelService : INService
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public ConcurrentHashSet<ulong> GameVoiceChannels { get; }
 | 
					    public ConcurrentHashSet<ulong> GameVoiceChannels { get; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,6 +41,7 @@ public partial class Administration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if (!result)
 | 
					            if (!result)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            await _service.ClearAllOverrides(ctx.Guild.Id);
 | 
					            await _service.ClearAllOverrides(ctx.Guild.Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await ReplyConfirmLocalizedAsync(strs.perm_override_all);
 | 
					            await ReplyConfirmLocalizedAsync(strs.perm_override_all);
 | 
				
			||||||
@@ -66,8 +67,8 @@ public partial class Administration
 | 
				
			|||||||
                    if (thisPageOverrides.Count == 0)
 | 
					                    if (thisPageOverrides.Count == 0)
 | 
				
			||||||
                        eb.WithDescription(GetText(strs.perm_override_page_none));
 | 
					                        eb.WithDescription(GetText(strs.perm_override_page_none));
 | 
				
			||||||
                    else
 | 
					                    else
 | 
				
			||||||
                        eb.WithDescription(string.Join("\n",
 | 
					                        eb.WithDescription(thisPageOverrides.Select(ov => $"{ov.Command} => {ov.Perm.ToString()}")
 | 
				
			||||||
                            thisPageOverrides.Select(ov => $"{ov.Command} => {ov.Perm.ToString()}")));
 | 
					                                                            .Join("\n"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return eb;
 | 
					                    return eb;
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,66 +1,64 @@
 | 
				
			|||||||
#nullable disable
 | 
					#nullable disable
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using NadekoBot.Common.ModuleBehaviors;
 | 
				
			||||||
using NadekoBot.Services.Database.Models;
 | 
					using NadekoBot.Services.Database.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.Administration.Services;
 | 
					namespace NadekoBot.Modules.Administration.Services;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public sealed class PlayingRotateService : INService
 | 
					public sealed class PlayingRotateService : INService, IReadyExecutor
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private readonly Timer _t;
 | 
					 | 
				
			||||||
    private readonly BotConfigService _bss;
 | 
					    private readonly BotConfigService _bss;
 | 
				
			||||||
    private readonly SelfService _selfService;
 | 
					    private readonly SelfService _selfService;
 | 
				
			||||||
    private readonly Replacer _rep;
 | 
					    private readonly Replacer _rep;
 | 
				
			||||||
    private readonly DbService _db;
 | 
					    private readonly DbService _db;
 | 
				
			||||||
    private readonly Bot _bot;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public PlayingRotateService(
 | 
					    public PlayingRotateService(
 | 
				
			||||||
        DiscordSocketClient client,
 | 
					        DiscordSocketClient client,
 | 
				
			||||||
        DbService db,
 | 
					        DbService db,
 | 
				
			||||||
        Bot bot,
 | 
					 | 
				
			||||||
        BotConfigService bss,
 | 
					        BotConfigService bss,
 | 
				
			||||||
        IEnumerable<IPlaceholderProvider> phProviders,
 | 
					        IEnumerable<IPlaceholderProvider> phProviders,
 | 
				
			||||||
        SelfService selfService)
 | 
					        SelfService selfService)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        _db = db;
 | 
					        _db = db;
 | 
				
			||||||
        _bot = bot;
 | 
					 | 
				
			||||||
        _bss = bss;
 | 
					        _bss = bss;
 | 
				
			||||||
        _selfService = selfService;
 | 
					        _selfService = selfService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (client.ShardId == 0)
 | 
					        if (client.ShardId == 0)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            _rep = new ReplacementBuilder().WithClient(client).WithProviders(phProviders).Build();
 | 
					            _rep = new ReplacementBuilder().WithClient(client).WithProviders(phProviders).Build();
 | 
				
			||||||
 | 
					 | 
				
			||||||
            _t = new(RotatingStatuses, new TimerState(), TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private async void RotatingStatuses(object objState)
 | 
					    public async Task OnReadyAsync()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try
 | 
					        var timer = new PeriodicTimer(TimeSpan.FromMinutes(1));
 | 
				
			||||||
 | 
					        var index = 0;
 | 
				
			||||||
 | 
					        while (await timer.WaitForNextTickAsync())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var state = (TimerState)objState;
 | 
					            try
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!_bss.Data.RotateStatuses) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
 | 
					 | 
				
			||||||
            await using (var uow = _db.GetDbContext())
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                rotatingStatuses = uow.RotatingStatus.AsNoTracking().OrderBy(x => x.Id).ToList();
 | 
					                if (!_bss.Data.RotateStatuses) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                IReadOnlyList<RotatingPlayingStatus> rotatingStatuses;
 | 
				
			||||||
 | 
					                await using (var uow = _db.GetDbContext())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    rotatingStatuses = uow.RotatingStatus.AsNoTracking().OrderBy(x => x.Id).ToList();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (rotatingStatuses.Count == 0)
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var playingStatus = index >= rotatingStatuses.Count
 | 
				
			||||||
 | 
					                    ? rotatingStatuses[index = 0]
 | 
				
			||||||
 | 
					                    : rotatingStatuses[index++];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var statusText = _rep.Replace(playingStatus.Status);
 | 
				
			||||||
 | 
					                await _selfService.SetGameAsync(statusText, playingStatus.Type);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (Exception ex)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Log.Warning(ex, "Rotating playing status errored: {ErrorMessage}", ex.Message);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (rotatingStatuses.Count == 0)
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var playingStatus = state.Index >= rotatingStatuses.Count
 | 
					 | 
				
			||||||
                ? rotatingStatuses[state.Index = 0]
 | 
					 | 
				
			||||||
                : rotatingStatuses[state.Index++];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var statusText = _rep.Replace(playingStatus.Status);
 | 
					 | 
				
			||||||
            await _selfService.SetGameAsync(statusText, playingStatus.Type);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        catch (Exception ex)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Log.Warning(ex, "Rotating playing status errored: {ErrorMessage}", ex.Message);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -100,9 +98,4 @@ public sealed class PlayingRotateService : INService
 | 
				
			|||||||
        using var uow = _db.GetDbContext();
 | 
					        using var uow = _db.GetDbContext();
 | 
				
			||||||
        return uow.RotatingStatus.AsNoTracking().ToList();
 | 
					        return uow.RotatingStatus.AsNoTracking().ToList();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private class TimerState
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public int Index { get; set; }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -40,7 +40,9 @@ public partial class Administration
 | 
				
			|||||||
                                     }
 | 
					                                     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                     var role = (IRole)roleResult.BestMatch;
 | 
					                                     var role = (IRole)roleResult.BestMatch;
 | 
				
			||||||
                                     if (role.Position > ((IGuildUser)ctx.User).GetRoles().Select(r => r.Position).Max()
 | 
					                                     if (role.Position > ((IGuildUser)ctx.User).GetRoles()
 | 
				
			||||||
 | 
					                                                                               .Select(r => r.Position)
 | 
				
			||||||
 | 
					                                                                               .Max()
 | 
				
			||||||
                                         && ctx.User.Id != ctx.Guild.OwnerId)
 | 
					                                         && ctx.User.Id != ctx.Guild.OwnerId)
 | 
				
			||||||
                                         return null;
 | 
					                                         return null;
 | 
				
			||||||
                                     var emote = x.Last().ToIEmote();
 | 
					                                     var emote = x.Last().ToIEmote();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace NadekoBot.Modules.NadekoExpressions;
 | 
					namespace NadekoBot.Modules.NadekoExpressions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// todo string.join to .Join(", ")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[Name("Expressions")]
 | 
					[Name("Expressions")]
 | 
				
			||||||
public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
 | 
					public partial class NadekoExpressions : NadekoModule<NadekoExpressionsService>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +1,6 @@
 | 
				
			|||||||
#nullable disable
 | 
					#nullable disable
 | 
				
			||||||
namespace NadekoBot.Modules.Gambling.Common;
 | 
					namespace NadekoBot.Modules.Gambling.Common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class QuadDeck : Deck
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    protected override void RefillPool()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        CardPool = new(52 * 4);
 | 
					 | 
				
			||||||
        for (var j = 1; j < 14; j++)
 | 
					 | 
				
			||||||
        for (var i = 1; i < 5; i++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            CardPool.Add(new((CardSuit)i, j));
 | 
					 | 
				
			||||||
            CardPool.Add(new((CardSuit)i, j));
 | 
					 | 
				
			||||||
            CardPool.Add(new((CardSuit)i, j));
 | 
					 | 
				
			||||||
            CardPool.Add(new((CardSuit)i, j));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public class Deck
 | 
					public class Deck
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public enum CardSuit
 | 
					    public enum CardSuit
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/NadekoBot/Modules/Gambling/~Shared/Decks/QuadDeck.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/NadekoBot/Modules/Gambling/~Shared/Decks/QuadDeck.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					namespace NadekoBot.Modules.Gambling.Common;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class QuadDeck : Deck
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    protected override void RefillPool()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        CardPool = new(52 * 4);
 | 
				
			||||||
 | 
					        for (var j = 1; j < 14; j++)
 | 
				
			||||||
 | 
					        for (var i = 1; i < 5; i++)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            CardPool.Add(new((CardSuit)i, j));
 | 
				
			||||||
 | 
					            CardPool.Add(new((CardSuit)i, j));
 | 
				
			||||||
 | 
					            CardPool.Add(new((CardSuit)i, j));
 | 
				
			||||||
 | 
					            CardPool.Add(new((CardSuit)i, j));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -49,7 +49,6 @@
 | 
				
			|||||||
    <PackageReference Include="Scrutor" Version="3.3.0" />
 | 
					    <PackageReference Include="Scrutor" Version="3.3.0" />
 | 
				
			||||||
    <PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
 | 
					    <PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
 | 
				
			||||||
    <PackageReference Include="Serilog.Sinks.Seq" Version="5.1.0" />
 | 
					    <PackageReference Include="Serilog.Sinks.Seq" Version="5.1.0" />
 | 
				
			||||||
    <PackageReference Include="SerilogAnalyzer" Version="0.15.0" />
 | 
					 | 
				
			||||||
    <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
 | 
					    <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
 | 
				
			||||||
    <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0010" />
 | 
					    <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta0010" />
 | 
				
			||||||
    <PackageReference Include="StackExchange.Redis" Version="2.2.88" />
 | 
					    <PackageReference Include="StackExchange.Redis" Version="2.2.88" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,19 +1,9 @@
 | 
				
			|||||||
using Humanizer.Localisation;
 | 
					using Humanizer.Localisation;
 | 
				
			||||||
using SixLabors.Fonts;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp.Drawing;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp.Drawing.Processing;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp.Formats;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp.Formats.Png;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp.PixelFormats;
 | 
					 | 
				
			||||||
using SixLabors.ImageSharp.Processing;
 | 
					 | 
				
			||||||
using System.Globalization;
 | 
					using System.Globalization;
 | 
				
			||||||
using System.Net.Http.Headers;
 | 
					using System.Net.Http.Headers;
 | 
				
			||||||
using System.Text.Json;
 | 
					using System.Text.Json;
 | 
				
			||||||
using System.Text.RegularExpressions;
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
using Color = Discord.Color;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// todo imagesharp extensions
 | 
					 | 
				
			||||||
namespace NadekoBot.Extensions;
 | 
					namespace NadekoBot.Extensions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public static class Extensions
 | 
					public static class Extensions
 | 
				
			||||||
@@ -65,45 +55,7 @@ public static class Extensions
 | 
				
			|||||||
    public static IEmote ToIEmote(this string emojiStr)
 | 
					    public static IEmote ToIEmote(this string emojiStr)
 | 
				
			||||||
        => Emote.TryParse(emojiStr, out var maybeEmote) ? maybeEmote : new Emoji(emojiStr);
 | 
					        => Emote.TryParse(emojiStr, out var maybeEmote) ? maybeEmote : new Emoji(emojiStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // https://github.com/SixLabors/Samples/blob/master/ImageSharp/AvatarWithRoundedCorner/Program.cs
 | 
					 | 
				
			||||||
    public static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        var size = ctx.GetCurrentSize();
 | 
					 | 
				
			||||||
        var corners = BuildCorners(size.Width, size.Height, cornerRadius);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        ctx.SetGraphicsOptions(new GraphicsOptions
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Antialias = true,
 | 
					 | 
				
			||||||
            // enforces that any part of this shape that has color is punched out of the background
 | 
					 | 
				
			||||||
            AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (var c in corners) ctx = ctx.Fill(SixLabors.ImageSharp.Color.Red, c);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return ctx;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // first create a square
 | 
					 | 
				
			||||||
        var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // then cut out of the square a circle so we are left with a corner
 | 
					 | 
				
			||||||
        var cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // corner is now a corner shape positions top left
 | 
					 | 
				
			||||||
        //lets make 3 more positioned correctly, we can do that by translating the original around the center of the image
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1;
 | 
					 | 
				
			||||||
        var bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // move it across the width of the image - the width of the shape
 | 
					 | 
				
			||||||
        var cornerTopRight = cornerTopLeft.RotateDegree(90).Translate(rightPos, 0);
 | 
					 | 
				
			||||||
        var cornerBottomLeft = cornerTopLeft.RotateDegree(-90).Translate(0, bottomPos);
 | 
					 | 
				
			||||||
        var cornerBottomRight = cornerTopLeft.RotateDegree(180).Translate(rightPos, bottomPos);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return new PathCollection(cornerTopLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					    /// <summary>
 | 
				
			||||||
    ///     First 10 characters of teh bot token.
 | 
					    ///     First 10 characters of teh bot token.
 | 
				
			||||||
@@ -139,9 +91,6 @@ public static class Extensions
 | 
				
			|||||||
        return embed.WithFooter(curPage.ToString());
 | 
					        return embed.WithFooter(curPage.ToString());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static Color ToDiscordColor(this Rgba32 color)
 | 
					 | 
				
			||||||
        => new(color.R, color.G, color.B);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static IEmbedBuilder WithOkColor(this IEmbedBuilder eb)
 | 
					    public static IEmbedBuilder WithOkColor(this IEmbedBuilder eb)
 | 
				
			||||||
        => eb.WithColor(EmbedColor.Ok);
 | 
					        => eb.WithColor(EmbedColor.Ok);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -215,47 +164,6 @@ public static class Extensions
 | 
				
			|||||||
    public static string ToJson<T>(this T any, JsonSerializerOptions? options = null)
 | 
					    public static string ToJson<T>(this T any, JsonSerializerOptions? options = null)
 | 
				
			||||||
        => JsonSerializer.Serialize(any, options);
 | 
					        => JsonSerializer.Serialize(any, options);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// <summary>
 | 
					 | 
				
			||||||
    ///     Adds fallback fonts to <see cref="TextOptions" />
 | 
					 | 
				
			||||||
    /// </summary>
 | 
					 | 
				
			||||||
    /// <param name="opts"><see cref="TextOptions" /> to which fallback fonts will be added to</param>
 | 
					 | 
				
			||||||
    /// <param name="fallback">List of fallback Font Families to add</param>
 | 
					 | 
				
			||||||
    /// <returns>The same <see cref="TextOptions" /> to allow chaining</returns>
 | 
					 | 
				
			||||||
    public static TextOptions WithFallbackFonts(this TextOptions opts, List<FontFamily> fallback)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        foreach (var ff in fallback) opts.FallbackFonts.Add(ff);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return opts;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// <summary>
 | 
					 | 
				
			||||||
    ///     Adds fallback fonts to <see cref="TextGraphicsOptions" />
 | 
					 | 
				
			||||||
    /// </summary>
 | 
					 | 
				
			||||||
    /// <param name="opts"><see cref="TextGraphicsOptions" /> to which fallback fonts will be added to</param>
 | 
					 | 
				
			||||||
    /// <param name="fallback">List of fallback Font Families to add</param>
 | 
					 | 
				
			||||||
    /// <returns>The same <see cref="TextGraphicsOptions" /> to allow chaining</returns>
 | 
					 | 
				
			||||||
    public static TextGraphicsOptions WithFallbackFonts(this TextGraphicsOptions opts, List<FontFamily> fallback)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        opts.TextOptions.WithFallbackFonts(fallback);
 | 
					 | 
				
			||||||
        return opts;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static MemoryStream ToStream(this Image<Rgba32> img, IImageFormat? format = null)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        var imageStream = new MemoryStream();
 | 
					 | 
				
			||||||
        if (format?.Name == "GIF")
 | 
					 | 
				
			||||||
            img.SaveAsGif(imageStream);
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            img.SaveAsPng(imageStream,
 | 
					 | 
				
			||||||
                new()
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    ColorType = PngColorType.RgbWithAlpha, CompressionLevel = PngCompressionLevel.BestCompression
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        imageStream.Position = 0;
 | 
					 | 
				
			||||||
        return imageStream;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static Stream ToStream(this IEnumerable<byte> bytes, bool canWrite = false)
 | 
					    public static Stream ToStream(this IEnumerable<byte> bytes, bool canWrite = false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        var ms = new MemoryStream(bytes as byte[] ?? bytes.ToArray(), canWrite);
 | 
					        var ms = new MemoryStream(bytes as byte[] ?? bytes.ToArray(), canWrite);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,8 +84,9 @@ public static class MessageChannelExtensions
 | 
				
			|||||||
        Func<T, string> howToPrint,
 | 
					        Func<T, string> howToPrint,
 | 
				
			||||||
        int columns = 3)
 | 
					        int columns = 3)
 | 
				
			||||||
        => ch.SendMessageAsync($@"{seed}```css
 | 
					        => ch.SendMessageAsync($@"{seed}```css
 | 
				
			||||||
{string.Join("\n", items.Chunk(columns)
 | 
					{items.Chunk(columns)
 | 
				
			||||||
                        .Select(ig => string.Concat(ig.Select(howToPrint))))}
 | 
					      .Select(ig => string.Concat(ig.Select(howToPrint)))
 | 
				
			||||||
 | 
					      .Join("\n")}
 | 
				
			||||||
```");
 | 
					```");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static Task<IUserMessage> SendTableAsync<T>(
 | 
					    public static Task<IUserMessage> SendTableAsync<T>(
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										98
									
								
								src/NadekoBot/_Extensions/ImagesharpExtensions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/NadekoBot/_Extensions/ImagesharpExtensions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,98 @@
 | 
				
			|||||||
 | 
					using SixLabors.Fonts;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp.Drawing;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp.Drawing.Processing;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp.Formats;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp.Formats.Png;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp.PixelFormats;
 | 
				
			||||||
 | 
					using SixLabors.ImageSharp.Processing;
 | 
				
			||||||
 | 
					using Color = Discord.Color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace NadekoBot.Extensions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public static class ImagesharpExtensions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    ///     Adds fallback fonts to <see cref="TextOptions" />
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="opts"><see cref="TextOptions" /> to which fallback fonts will be added to</param>
 | 
				
			||||||
 | 
					    /// <param name="fallback">List of fallback Font Families to add</param>
 | 
				
			||||||
 | 
					    /// <returns>The same <see cref="TextOptions" /> to allow chaining</returns>
 | 
				
			||||||
 | 
					    public static TextOptions WithFallbackFonts(this TextOptions opts, List<FontFamily> fallback)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        foreach (var ff in fallback) opts.FallbackFonts.Add(ff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return opts;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// <summary>
 | 
				
			||||||
 | 
					    ///     Adds fallback fonts to <see cref="TextGraphicsOptions" />
 | 
				
			||||||
 | 
					    /// </summary>
 | 
				
			||||||
 | 
					    /// <param name="opts"><see cref="TextGraphicsOptions" /> to which fallback fonts will be added to</param>
 | 
				
			||||||
 | 
					    /// <param name="fallback">List of fallback Font Families to add</param>
 | 
				
			||||||
 | 
					    /// <returns>The same <see cref="TextGraphicsOptions" /> to allow chaining</returns>
 | 
				
			||||||
 | 
					    public static TextGraphicsOptions WithFallbackFonts(this TextGraphicsOptions opts, List<FontFamily> fallback)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        opts.TextOptions.WithFallbackFonts(fallback);
 | 
				
			||||||
 | 
					        return opts;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // https://github.com/SixLabors/Samples/blob/master/ImageSharp/AvatarWithRoundedCorner/Program.cs
 | 
				
			||||||
 | 
					    public static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext ctx, float cornerRadius)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var size = ctx.GetCurrentSize();
 | 
				
			||||||
 | 
					        var corners = BuildCorners(size.Width, size.Height, cornerRadius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ctx.SetGraphicsOptions(new GraphicsOptions
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Antialias = true,
 | 
				
			||||||
 | 
					            // enforces that any part of this shape that has color is punched out of the background
 | 
				
			||||||
 | 
					            AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var c in corners) ctx = ctx.Fill(SixLabors.ImageSharp.Color.Red, c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ctx;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // first create a square
 | 
				
			||||||
 | 
					        var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // then cut out of the square a circle so we are left with a corner
 | 
				
			||||||
 | 
					        var cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // corner is now a corner shape positions top left
 | 
				
			||||||
 | 
					        //lets make 3 more positioned correctly, we can do that by translating the original around the center of the image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1;
 | 
				
			||||||
 | 
					        var bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // move it across the width of the image - the width of the shape
 | 
				
			||||||
 | 
					        var cornerTopRight = cornerTopLeft.RotateDegree(90).Translate(rightPos, 0);
 | 
				
			||||||
 | 
					        var cornerBottomLeft = cornerTopLeft.RotateDegree(-90).Translate(0, bottomPos);
 | 
				
			||||||
 | 
					        var cornerBottomRight = cornerTopLeft.RotateDegree(180).Translate(rightPos, bottomPos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return new PathCollection(cornerTopLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    public static Color ToDiscordColor(this Rgba32 color)
 | 
				
			||||||
 | 
					        => new(color.R, color.G, color.B);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static MemoryStream ToStream(this Image<Rgba32> img, IImageFormat? format = null)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var imageStream = new MemoryStream();
 | 
				
			||||||
 | 
					        if (format?.Name == "GIF")
 | 
				
			||||||
 | 
					            img.SaveAsGif(imageStream);
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            img.SaveAsPng(imageStream,
 | 
				
			||||||
 | 
					                new()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    ColorType = PngColorType.RgbWithAlpha, CompressionLevel = PngCompressionLevel.BestCompression
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        imageStream.Position = 0;
 | 
				
			||||||
 | 
					        return imageStream;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -45,7 +45,7 @@ public static class StringExtensions
 | 
				
			|||||||
            tokens[i] = token[..1].ToUpperInvariant() + token[1..];
 | 
					            tokens[i] = token[..1].ToUpperInvariant() + token[1..];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return string.Join(" ", tokens).Replace(" Of ", " of ").Replace(" The ", " the ");
 | 
					        return tokens.Join(" ").Replace(" Of ", " of ").Replace(" The ", " the ");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //http://www.dotnetperls.com/levenshtein
 | 
					    //http://www.dotnetperls.com/levenshtein
 | 
				
			||||||
@@ -124,7 +124,7 @@ public static class StringExtensions
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static string GetInitials(this string txt, string glue = "")
 | 
					    public static string GetInitials(this string txt, string glue = "")
 | 
				
			||||||
        => string.Join(glue, txt.Split(' ').Select(x => x.FirstOrDefault()));
 | 
					        => txt.Split(' ').Select(x => x.FirstOrDefault()).Join(glue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static bool IsAlphaNumeric(this string txt)
 | 
					    public static bool IsAlphaNumeric(this string txt)
 | 
				
			||||||
        => txt.All(c => _lettersAndDigits.Contains(c));
 | 
					        => txt.All(c => _lettersAndDigits.Contains(c));
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user