diff --git a/.dockerignore b/.dockerignore index e7f155a0..ca4e8683 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,21 +1,26 @@ -**/.dockerignore +**/.dockerignore **/.env **/.git **/.gitignore +**/.project +**/.settings +**/.toolstarget **/.vs **/.vscode +**/.idea **/*.*proj.user +**/*.dbmdl +**/*.jfm **/azds.yaml -**/charts **/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log **/obj -**/Dockerfile -**/Dockerfile.develop -**/docker-compose.yml -**/docker-compose.*.yml -**/*.dbmdl -**/*.jfm **/secrets.dev.yaml **/values.dev.yaml -**/.toolstarget +LICENSE +README.md /Hanekawa/Properties/launchSettings.json \ No newline at end of file diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..7e44f145 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,46 @@ + +[*.cs] +indent_style = space +indent_size = 4 +tab_width = 2 + +[*] + +# Microsoft .NET properties +csharp_new_line_before_members_in_object_initializers = false +csharp_preferred_modifier_order = internal, protected, private, public, file, new, static, sealed, virtual, abstract, override, readonly, extern, unsafe, volatile, async, required:suggestion +csharp_preserve_single_line_blocks = true +csharp_space_after_cast = true +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none +dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none + +# ReSharper properties +resharper_arguments_skip_single = true +resharper_blank_lines_after_block_statements = 0 +resharper_blank_lines_around_auto_property = 0 +resharper_blank_lines_around_single_line_invocable = 0 +resharper_blank_lines_around_single_line_type = 0 +resharper_braces_for_for = required +resharper_braces_for_ifelse = not_required_for_both +resharper_braces_for_using = not_required +resharper_braces_redundant = false +resharper_continuous_indent_multiplier = 1 +resharper_csharp_blank_lines_around_field = 0 +resharper_csharp_blank_lines_around_invocable = 0 +resharper_csharp_max_line_length = 135 +resharper_csharp_remove_blank_lines_near_braces_in_declarations = false +resharper_csharp_wrap_ternary_expr_style = wrap_if_long +resharper_instance_members_qualify_declared_in = +resharper_keep_existing_enum_arrangement = false +resharper_max_initializer_elements_on_line = 2 +resharper_parentheses_non_obvious_operations = none, shift, bitwise_and, bitwise_exclusive_or, bitwise_inclusive_or, bitwise +resharper_parentheses_redundancy_style = remove +resharper_parentheses_same_type_operations = true +resharper_place_expr_method_on_single_line = if_owner_is_single_line +resharper_place_simple_embedded_statement_on_same_line = if_owner_is_single_line +resharper_wrap_after_primary_constructor_declaration_lpar = false +resharper_wrap_arguments_style = wrap_if_long +resharper_wrap_chained_binary_expressions = wrap_if_long +resharper_wrap_object_and_collection_initializer_style = chop_if_long +resharper_wrap_primary_constructor_parameters_style = wrap_if_long diff --git a/.github/workflows/dockerpublish.yml b/.github/workflows/dockerpublish.yml index 70a3dfd4..e24d2bfe 100644 --- a/.github/workflows/dockerpublish.yml +++ b/.github/workflows/dockerpublish.yml @@ -29,9 +29,9 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: '5.0.100' + dotnet-version: '9.0.x' - name: Build with dotnet - run: dotnet build --configuration Release + run: dotnet build Hanekawa.Bot --configuration Release # Push image to GitHub Packages. # See also https://docs.docker.com/docker-hub/builds/ @@ -46,7 +46,7 @@ jobs: - uses: actions/checkout@v2 - name: Build image - run: docker build . --file Hanekawa/Dockerfile --tag image + run: docker build . --file Hanekawa.Bot/Dockerfile --tag image - name: Log into registry run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin diff --git a/.gitignore b/.gitignore index 72d1724d..c610ff64 100644 --- a/.gitignore +++ b/.gitignore @@ -260,4 +260,4 @@ paket-files/ __pycache__/ *.pyc /Hanekawa/Properties/launchSettings.json -/Hanekawa.Web/Properties/launchSettings.json +/Hanekawa.Bot/Properties/launchSettings.json diff --git a/Hanekawa.AnimeSimulCast/Events/AsyncEvents.cs b/Hanekawa.AnimeSimulCast/Events/AsyncEvents.cs deleted file mode 100644 index e9201a03..00000000 --- a/Hanekawa.AnimeSimulCast/Events/AsyncEvents.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; - -namespace Hanekawa.AnimeSimulCast.Events -{ - public delegate Task AsyncEvent(T1 arg1); - - public delegate Task AsyncEvent(T1 arg1, T2 arg2); - - public delegate Task AsyncEvent(T1 arg1, T2 arg2, T3 arg3); - - public delegate Task AsyncEvent(T1 arg1, T2 arg2, T3 arg3, T4 arg4); - - public static class AsyncEvents - { - public static Task InvokeAsync(this AsyncEvent asyncEvent, T1 arg1) - { - if (asyncEvent == null) - return Task.CompletedTask; - - var events = asyncEvent.GetInvocationList().Cast>(); - var eventTasks = events.Select(it => it.Invoke(arg1)); - - return Task.WhenAll(eventTasks); - } - - public static Task InvokeAsync(this AsyncEvent asyncEvent, T1 arg1, T2 arg2) - { - if (asyncEvent == null) - return Task.CompletedTask; - - var events = asyncEvent.GetInvocationList().Cast>(); - var eventTasks = events.Select(it => it.Invoke(arg1, arg2)); - - return Task.WhenAll(eventTasks); - } - - public static Task InvokeAsync(this AsyncEvent asyncEvent, T1 arg1, T2 arg2, T3 arg3) - { - if (asyncEvent == null) - return Task.CompletedTask; - - var events = asyncEvent.GetInvocationList().Cast>(); - var eventTasks = events.Select(it => it.Invoke(arg1, arg2, arg3)); - - return Task.WhenAll(eventTasks); - } - - public static Task InvokeAsync(this AsyncEvent asyncEvent, T1 arg1, T2 arg2, - T3 arg3, T4 arg4) - { - if (asyncEvent == null) - return Task.CompletedTask; - - var events = asyncEvent.GetInvocationList().Cast>(); - var eventTasks = events.Select(it => it.Invoke(arg1, arg2, arg3, arg4)); - - return Task.WhenAll(eventTasks); - } - } -} \ No newline at end of file diff --git a/Hanekawa.AnimeSimulCast/Extensions/StringExtensions.cs b/Hanekawa.AnimeSimulCast/Extensions/StringExtensions.cs deleted file mode 100644 index 280c443c..00000000 --- a/Hanekawa.AnimeSimulCast/Extensions/StringExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Text.RegularExpressions; - -namespace Hanekawa.AnimeSimulCast.Extensions -{ - public static class StringExtensions - { - private static readonly Regex Season = new Regex(@"(S([1-9]{1,4}))", - RegexOptions.IgnoreCase | RegexOptions.Compiled); - - private static readonly Regex Episode = - new Regex(@"( - Episode ([\w]{1,4}))", RegexOptions.IgnoreCase | RegexOptions.Compiled); - - public static string GetSeason(this string content) => !Season.IsMatch(content) ? null : content.Remove(0, 1); - - public static string GetEpisode(this string content) - { - var fullString = Episode.Match(content).Value; - return fullString.Remove(0, 11); - } - - public static string Filter(this string content) - { - var filt = Episode.Replace(content, ""); - return Season.IsMatch(filt) ? Season.Replace(filt, "") : filt; - } - } -} \ No newline at end of file diff --git a/Hanekawa.AnimeSimulCast/Hanekawa.AnimeSimulCast.csproj b/Hanekawa.AnimeSimulCast/Hanekawa.AnimeSimulCast.csproj deleted file mode 100644 index 1d27c1b9..00000000 --- a/Hanekawa.AnimeSimulCast/Hanekawa.AnimeSimulCast.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - netcoreapp3.1 - 8 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Hanekawa.Application/Contracts/Discord/Common/Ban.cs b/Hanekawa.Application/Contracts/Discord/Common/Ban.cs new file mode 100644 index 00000000..cb35be8f --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Common/Ban.cs @@ -0,0 +1,15 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Contracts.Discord.Common; + +public record Ban : IMessageSqs +{ + public ulong GuildId { get; init; } + public ulong UserId { get; init; } + public ulong ModeratorId { get; init; } + public string Reason { get; init; } = string.Empty; + public int Days { get; init; } = 7; + + public ProviderSource Source { get; init; } = ProviderSource.Discord; +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Common/Kick.cs b/Hanekawa.Application/Contracts/Discord/Common/Kick.cs new file mode 100644 index 00000000..408b96cb --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Common/Kick.cs @@ -0,0 +1,14 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Contracts.Discord.Common; + +public class Kick : IMessageSqs +{ + public ulong GuildId { get; init; } + public ulong UserId { get; init; } + public ulong ModeratorId { get; init; } + public string Reason { get; init; } = string.Empty; + + public ProviderSource Source { get; init; } = ProviderSource.Discord; +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Common/Mute.cs b/Hanekawa.Application/Contracts/Discord/Common/Mute.cs new file mode 100644 index 00000000..e9f3d9cc --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Common/Mute.cs @@ -0,0 +1,15 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Contracts.Discord.Common; + +public class Mute : IMessageSqs +{ + public ulong GuildId { get; init; } + public ulong UserId { get; init; } + public ulong ModeratorId { get; init; } + public string Reason { get; init; } = string.Empty; + public TimeSpan Duration { get; init; } = TimeSpan.Zero; + + public ProviderSource Source { get; init; } = ProviderSource.Discord; +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Common/Prune.cs b/Hanekawa.Application/Contracts/Discord/Common/Prune.cs new file mode 100644 index 00000000..25122d21 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Common/Prune.cs @@ -0,0 +1,15 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Contracts.Discord.Common; + +public class Prune : IMessageSqs +{ + public ulong GuildId { get; init; } + public ulong UserId { get; init; } + public ulong ModeratorId { get; init; } + public string Reason { get; init; } = string.Empty; + public int Days { get; init; } = 7; + + public ProviderSource Source { get; init; } = ProviderSource.Discord; +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Common/Unban.cs b/Hanekawa.Application/Contracts/Discord/Common/Unban.cs new file mode 100644 index 00000000..261c16fb --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Common/Unban.cs @@ -0,0 +1,14 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Contracts.Discord.Common; + +public class Unban : IMessageSqs +{ + public ulong GuildId { get; init; } + public ulong UserId { get; init; } + public ulong ModeratorId { get; init; } + public string Reason { get; init; } = string.Empty; + + public ProviderSource Source { get; init; } = ProviderSource.Discord; +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Common/Unmute.cs b/Hanekawa.Application/Contracts/Discord/Common/Unmute.cs new file mode 100644 index 00000000..9eb72a03 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Common/Unmute.cs @@ -0,0 +1,14 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Contracts.Discord.Common; + +public class Unmute : IMessageSqs +{ + public ulong GuildId { get; init; } + public ulong UserId { get; init; } + public ulong ModeratorId { get; init; } + public string Reason { get; init; } = string.Empty; + + public ProviderSource Source { get; init; } = ProviderSource.Discord; +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/BotLeave.cs b/Hanekawa.Application/Contracts/Discord/Services/BotLeave.cs new file mode 100644 index 00000000..979f4bc2 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/BotLeave.cs @@ -0,0 +1,5 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record BotLeave(ulong GuildId) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/MessageDeleted.cs b/Hanekawa.Application/Contracts/Discord/Services/MessageDeleted.cs new file mode 100644 index 00000000..39393a70 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/MessageDeleted.cs @@ -0,0 +1,6 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record MessageDeleted + (ulong GuildId, ulong ChannelId, ulong AuthorId, ulong MessageId, string MessageContent) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/MessageReceived.cs b/Hanekawa.Application/Contracts/Discord/Services/MessageReceived.cs new file mode 100644 index 00000000..90203678 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/MessageReceived.cs @@ -0,0 +1,7 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record MessageReceived(ulong GuildId, ulong ChannelId, DiscordMember Member, + ulong MessageId, string? Message, DateTimeOffset CreatedAt) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/MessagesDeleted.cs b/Hanekawa.Application/Contracts/Discord/Services/MessagesDeleted.cs new file mode 100644 index 00000000..de7aa965 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/MessagesDeleted.cs @@ -0,0 +1,6 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record MessagesDeleted(ulong GuildId, ulong ChannelId, ulong[] AuthorId, + ulong[] MessageIds, string[] MessageContents) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/ReactionAdd.cs b/Hanekawa.Application/Contracts/Discord/Services/ReactionAdd.cs new file mode 100644 index 00000000..e4e22747 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/ReactionAdd.cs @@ -0,0 +1,5 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record ReactionAdd(ulong GuildId, ulong ChannelId, ulong MessageId, ulong UserId, string? Emoji) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/ReactionCleared.cs b/Hanekawa.Application/Contracts/Discord/Services/ReactionCleared.cs new file mode 100644 index 00000000..739cd917 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/ReactionCleared.cs @@ -0,0 +1,5 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record ReactionCleared(ulong GuildId, ulong ChannelId, ulong MessageId) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/ReactionRemove.cs b/Hanekawa.Application/Contracts/Discord/Services/ReactionRemove.cs new file mode 100644 index 00000000..0b044919 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/ReactionRemove.cs @@ -0,0 +1,5 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record ReactionRemove(ulong GuildId, ulong ChannelId, ulong MessageId, ulong UserId, string? Emoji) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/UserBanned.cs b/Hanekawa.Application/Contracts/Discord/Services/UserBanned.cs new file mode 100644 index 00000000..3ed2b235 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/UserBanned.cs @@ -0,0 +1,9 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record UserBanned(DiscordMember Member) : INotificationSqs +{ + public ulong GuildId { get; init; } +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/UserJoin.cs b/Hanekawa.Application/Contracts/Discord/Services/UserJoin.cs new file mode 100644 index 00000000..cbe88772 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/UserJoin.cs @@ -0,0 +1,6 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record UserJoin(ulong GuildId, ulong UserId, string Username, + string AvatarUrl, DateTimeOffset CreatedAt) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/UserLeave.cs b/Hanekawa.Application/Contracts/Discord/Services/UserLeave.cs new file mode 100644 index 00000000..bab33e15 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/UserLeave.cs @@ -0,0 +1,5 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record UserLeave(ulong GuildId, ulong UserId) : INotificationSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/UserUnbanned.cs b/Hanekawa.Application/Contracts/Discord/Services/UserUnbanned.cs new file mode 100644 index 00000000..42c947b6 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/UserUnbanned.cs @@ -0,0 +1,9 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record UserUnbanned(DiscordMember Member) : INotificationSqs +{ + public ulong GuildId { get; init; } +} \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/Discord/Services/VoiceStateUpdate.cs b/Hanekawa.Application/Contracts/Discord/Services/VoiceStateUpdate.cs new file mode 100644 index 00000000..c37b00e0 --- /dev/null +++ b/Hanekawa.Application/Contracts/Discord/Services/VoiceStateUpdate.cs @@ -0,0 +1,5 @@ +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application.Contracts.Discord.Services; + +public record VoiceStateUpdate(ulong GuildId, ulong UserId, ulong? ChannelId, string? SessionId) : IMessageSqs; \ No newline at end of file diff --git a/Hanekawa.Application/Contracts/LevelUp.cs b/Hanekawa.Application/Contracts/LevelUp.cs new file mode 100644 index 00000000..5ac43732 --- /dev/null +++ b/Hanekawa.Application/Contracts/LevelUp.cs @@ -0,0 +1,7 @@ +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using MediatR; + +namespace Hanekawa.Application.Contracts; + +public record LevelUp(DiscordMember Member, ulong[] RoleIds, int Level, GuildConfig GuildConfig) : IRequest; \ No newline at end of file diff --git a/Hanekawa.Application/DependencyInjection.cs b/Hanekawa.Application/DependencyInjection.cs new file mode 100644 index 00000000..87232f0b --- /dev/null +++ b/Hanekawa.Application/DependencyInjection.cs @@ -0,0 +1,56 @@ +using System.Reflection; +using Hanekawa.Application.Handlers.Commands.Account; +using Hanekawa.Application.Handlers.Commands.Administration; +using Hanekawa.Application.Handlers.Commands.Boost; +using Hanekawa.Application.Handlers.Commands.Club; +using Hanekawa.Application.Handlers.Commands.Settings; +using Hanekawa.Application.Handlers.Services.Internal; +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Application.Interfaces.Services; +using Hanekawa.Application.Services; +using Hanekawa.Application.Services.Images; +using Hanekawa.Entities.Settings.Images; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Prometheus.Client.Collectors; +using Prometheus.Client.DependencyInjection; +using SixLabors.Fonts; + +namespace Hanekawa.Application; + +public static class DependencyInjection +{ + public static IServiceCollection AddApplicationLayer(this IServiceCollection serviceCollection, IConfiguration configuration) + { + serviceCollection.Configure(configuration.GetSection("ImageSettings")); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + serviceCollection.AddScoped(); + //serviceCollection.AddScoped(); + + var fontCollection = new FontCollection(); + fontCollection.Add(@"Data/Fonts/ARIAL.TTF"); + fontCollection.Add(@"Data/Fonts/TIMES.TTF"); + fontCollection.AddSystemFonts(); + serviceCollection.AddSingleton(fontCollection); + serviceCollection.AddMediatR(x => + { + x.RegisterServicesFromAssemblies(Assembly.GetCallingAssembly(), Assembly.GetEntryAssembly()); + }); + serviceCollection.AddMetricFactory(new CollectorRegistry()); + serviceCollection.AddSingleton(); + + return serviceCollection; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Extensions/DbExtensions.cs b/Hanekawa.Application/Extensions/DbExtensions.cs new file mode 100644 index 00000000..42cec431 --- /dev/null +++ b/Hanekawa.Application/Extensions/DbExtensions.cs @@ -0,0 +1,33 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Extensions; + +public static class DbExtensions +{ + public static async ValueTask GetOrCreateUserAsync(this IDbContext dbContext, + ulong guildId, ulong userId, CancellationToken cancellationToken = default) + { + var user = await dbContext.Users + .Include(e => e.User) + .FirstOrDefaultAsync(x => x.GuildId == guildId && x.Id == userId, cancellationToken); + + if (user is null) + { + user = new GuildUser + { + GuildId = guildId, + Id = userId, + User = new User + { + Id = userId, + } + }; + await dbContext.Users.AddAsync(user, cancellationToken); + await dbContext.SaveChangesAsync(cancellationToken); + } + + return user; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Extensions/ImageExtensions.cs b/Hanekawa.Application/Extensions/ImageExtensions.cs new file mode 100644 index 00000000..8273c7c0 --- /dev/null +++ b/Hanekawa.Application/Extensions/ImageExtensions.cs @@ -0,0 +1,53 @@ +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Drawing; +using SixLabors.ImageSharp.Drawing.Processing; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace Hanekawa.Application.Extensions; + +public static class ImageExtensions +{ + public static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext processingContext, + Size size, float cornerRadius) + => processingContext.Resize(new ResizeOptions + { + Size = size, + Mode = ResizeMode.Crop + }).ApplyRoundedCorners(cornerRadius); + + private 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, + AlphaCompositionMode = PixelAlphaCompositionMode.DestOut + }); + + foreach (var c in corners) + { + ctx = ctx.Fill(Color.Red, c); + } + return ctx; + } + + private static PathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius) + { + var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius); + + var cornerTopLeft = rect.Clip( + new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius)); + + var rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1; + var bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1; + + 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); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Extensions/ProviderSourceExtensions.cs b/Hanekawa.Application/Extensions/ProviderSourceExtensions.cs new file mode 100644 index 00000000..368188e6 --- /dev/null +++ b/Hanekawa.Application/Extensions/ProviderSourceExtensions.cs @@ -0,0 +1,15 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Microsoft.Extensions.DependencyInjection; + +namespace Hanekawa.Application.Extensions; + +internal static class ProviderSourceExtensions +{ + internal static IBot GetClient(this ProviderSource source, IServiceProvider services) + => source switch + { + ProviderSource.Discord => services.GetRequiredKeyedService(nameof(ProviderSource.Discord)), + _ => throw new NotImplementedException() + }; +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Account/AccountCommandService.cs b/Hanekawa.Application/Handlers/Commands/Account/AccountCommandService.cs new file mode 100644 index 00000000..a144c9ff --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Account/AccountCommandService.cs @@ -0,0 +1,45 @@ +using Hanekawa.Application.Extensions; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Handlers.Commands.Account; + +public interface IAccountCommandService +{ + ValueTask RankAsync(DiscordMember member, CancellationToken cancellationToken = default); + ValueTask ProfileAsync(DiscordMember member, CancellationToken cancellationToken = default); + Task GetWalletAsync(DiscordMember discordMember, CancellationToken cancellationToken = default); + Task GetTopUsersAsync(ulong guildId); +} + +public class AccountCommandService(IImageService imageService, IDbContext db) : IAccountCommandService +{ + public async ValueTask RankAsync(DiscordMember member, CancellationToken cancellationToken = default) + { + var user = await db.GetOrCreateUserAsync(member.Guild.GuildId, member.Id, cancellationToken).ConfigureAwait(false); + return await imageService.DrawRankAsync(member, user, cancellationToken); + } + + public async ValueTask ProfileAsync(DiscordMember member, CancellationToken cancellationToken = default) + { + var user = await db.GetOrCreateUserAsync(member.Guild.GuildId, member.Id, cancellationToken).ConfigureAwait(false); + return await imageService.DrawProfileAsync(member, user, cancellationToken); + } + + public async Task GetWalletAsync(DiscordMember discordMember, CancellationToken cancellationToken = default) + { + var user = await db.GetOrCreateUserAsync(discordMember.Guild.GuildId, discordMember.Id, cancellationToken).ConfigureAwait(false); + return user.Currency; + } + + public Task GetTopUsersAsync(ulong guildId) + { + return db.Users + .Where(u => u.GuildId == guildId && !u.Inactive) + .OrderByDescending(u => u.Experience) + .Take(10) + .ToArrayAsync(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Account/ProfileCommandHandler.cs b/Hanekawa.Application/Handlers/Commands/Account/ProfileCommandHandler.cs new file mode 100644 index 00000000..eb1a6a81 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Account/ProfileCommandHandler.cs @@ -0,0 +1,18 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Account; + +public record ProfileCommand(DiscordMember Member) : IRequest; +public record ProfileCommandResult(Stream ImageStream); + +public class ProfileCommandHandler(IImageService imageService, IDbContext db) : IRequestHandler +{ + public async Task Handle(ProfileCommand request, + CancellationToken cancellationToken) + { + var user = await db.Users.FindAsync([request.Member.Guild, request.Member.Id], cancellationToken: cancellationToken); + return new ProfileCommandResult(await imageService.DrawProfileAsync(request.Member, user, cancellationToken)); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Account/RankCommandHandler.cs b/Hanekawa.Application/Handlers/Commands/Account/RankCommandHandler.cs new file mode 100644 index 00000000..c029124f --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Account/RankCommandHandler.cs @@ -0,0 +1,6 @@ +namespace Hanekawa.Application.Handlers.Commands.Account; + +public class RankCommandHandler +{ + +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Account/TopCommandHandler.cs b/Hanekawa.Application/Handlers/Commands/Account/TopCommandHandler.cs new file mode 100644 index 00000000..65602469 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Account/TopCommandHandler.cs @@ -0,0 +1,6 @@ +namespace Hanekawa.Application.Handlers.Commands.Account; + +public class TopCommandHandler +{ + +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Account/WalletCommandHandler.cs b/Hanekawa.Application/Handlers/Commands/Account/WalletCommandHandler.cs new file mode 100644 index 00000000..1ed805f5 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Account/WalletCommandHandler.cs @@ -0,0 +1,6 @@ +namespace Hanekawa.Application.Handlers.Commands.Account; + +public class WalletCommandHandler +{ + +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/AdministrationCommandService.cs b/Hanekawa.Application/Handlers/Commands/Administration/AdministrationCommandService.cs new file mode 100644 index 00000000..3cbc24d9 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/AdministrationCommandService.cs @@ -0,0 +1,101 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Entities; +using Hanekawa.Entities.Discord; +using Hanekawa.Localize; +using Humanizer; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +/// +public class AdministrationCommandService(IBot bot, ILogger logger) + : IAdministrationCommandService +{ + /// + public async Task> BanUserAsync(DiscordMember user, ulong moderatorId, string reason, + int days = 0) + { + logger.LogInformation("Banning user {UserId} from guild {GuildId} by moderator {ModeratorId} for " + + "reason {Reason}", + user.Id, user.Guild.GuildId, moderatorId, reason); + await bot.BanAsync(user.Guild.GuildId, user.Id, days, reason).ConfigureAwait(false); + return new Response(new Message( + string.Format(Localization.BannedGuildUser, user.Mention, user.Guild.Name))); + } + + /// + public async Task> UnbanUserAsync(Guild guild, ulong userId, ulong moderatorId, string reason) + { + logger.LogInformation("Unbanning user {UserId} from guild {GuildId} by moderator {ModeratorId} for " + + "reason {Reason}", + userId, guild.GuildId, moderatorId, reason); + await bot.UnbanAsync(guild.GuildId, userId, reason).ConfigureAwait(false); + return new Response(new Message( + string.Format(Localization.UnbannedGuildUser, userId, guild.Name))); + } + + /// + public async Task> KickUserAsync(DiscordMember user, ulong moderatorId, string reason) + { + logger.LogInformation("Kicking user {UserId} from guild {GuildId} by moderator {ModeratorId} for " + + "reason {Reason}", + user.Id, user.Guild.GuildId, moderatorId, reason); + await bot.KickAsync(user.Guild.GuildId, user.Id, reason).ConfigureAwait(false); + return new Response(new Message( + string.Format(Localization.KickedGuildUser, user.Username, user.Guild.Name))); + } + + /// + public async Task> MuteUserAsync(DiscordMember user, ulong moderatorId, string reason, + TimeSpan duration) + { + logger.LogInformation("Muting user {UserId} from guild {GuildId} by moderator {ModeratorId} for " + + "reason {Reason} for duration {Duration}", + user.Id, user.Guild.GuildId, moderatorId, reason, duration); + await bot.MuteAsync(user.Guild.GuildId, user.Id, reason, duration).ConfigureAwait(false); + return new Response(new Message(string.Format(Localization.MutedGuildUserDuration, + user.Mention, duration.Humanize()))); + } + + /// + public async Task> UnmuteUserAsync(DiscordMember user, ulong moderatorId, string reason) + { + logger.LogInformation("Unmuting user {UserId} from guild {GuildId} by moderator {ModeratorId} for " + + "reason {Reason}", + user.Id, user.Guild.GuildId, moderatorId, reason); + await bot.UnmuteAsync(user.Guild.GuildId, user.Id, reason).ConfigureAwait(false); + return new Response(new Message(string.Format(Localization.UnMutedUser, user.Mention))); + } + + /// + public async Task> AddRoleAsync(DiscordMember user, ulong moderatorId, ulong roleId) + { + logger.LogInformation("Adding role {RoleId} to user {UserId} from guild {GuildId} by moderator " + + "{ModeratorId}", + roleId, user.Id, user.Guild.GuildId, moderatorId); + await bot.AddRoleAsync(user.Guild.GuildId, user.Id, roleId).ConfigureAwait(false); + return new Response(new Message("")); + } + + /// + public async Task> RemoveRoleAsync(DiscordMember user, ulong moderatorId, ulong roleId) + { + logger.LogInformation("Removing role {RoleId} from user {UserId} from guild {GuildId} by moderator " + + "{ModeratorId}", + roleId, user.Id, user.Guild.GuildId, moderatorId); + await bot.RemoveRoleAsync(user.Guild.GuildId, user.Id, roleId).ConfigureAwait(false); + return new Response(new Message("")); + } + + /// + public async Task> PruneAsync(ulong guildId, ulong channelId, ulong[] messageIds, + ulong moderatorId, string reason) + { + logger.LogInformation("Pruning {MessageAmount} messages from channel {ChannelId} by moderator " + + "{ModeratorId} for reason {Reason}", + messageIds.Length, channelId, moderatorId, reason); + await bot.PruneMessagesAsync(guildId, channelId, messageIds).ConfigureAwait(false); + return new Response(new Message(string.Format(Localization.PrunedMessages, messageIds.Length))); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/BanHandler.cs b/Hanekawa.Application/Handlers/Commands/Administration/BanHandler.cs new file mode 100644 index 00000000..9e4a971e --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/BanHandler.cs @@ -0,0 +1,22 @@ +using Hanekawa.Application.Contracts.Discord.Common; +using Hanekawa.Application.Extensions; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +public class BanHandler : IRequestHandler +{ + private readonly IServiceProvider _services; + + public BanHandler(IServiceProvider services) + => _services = services; + + public Task Handle(Ban request, CancellationToken cancellationToken) + { + var bot = request.Source.GetClient(_services); + return bot.BanAsync(request.GuildId, + request.UserId, + request.Days, + request.Reason + $" %{request.ModeratorId}%"); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/KickHandler.cs b/Hanekawa.Application/Handlers/Commands/Administration/KickHandler.cs new file mode 100644 index 00000000..a0c5ad28 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/KickHandler.cs @@ -0,0 +1,23 @@ +using Hanekawa.Application.Contracts.Discord.Common; +using Hanekawa.Application.Extensions; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +public class KickHandler : IRequestHandler +{ + private readonly IServiceProvider _service; + + public KickHandler(IServiceProvider service) + { + _service = service; + } + + public Task Handle(Kick request, CancellationToken cancellationToken) + { + var bot = request.Source.GetClient(_service); + return bot.KickAsync(request.GuildId, + request.UserId, + request.Reason + $" %{request.ModeratorId}%"); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/MuteHandler.cs b/Hanekawa.Application/Handlers/Commands/Administration/MuteHandler.cs new file mode 100644 index 00000000..7f646f0c --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/MuteHandler.cs @@ -0,0 +1,21 @@ +using Hanekawa.Application.Contracts.Discord.Common; +using Hanekawa.Application.Extensions; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +public class MuteHandler : IRequestHandler +{ + private readonly IServiceProvider _services; + public MuteHandler(IServiceProvider services) + => _services = services; + + public Task Handle(Mute request, CancellationToken cancellationToken) + { + var bot = request.Source.GetClient(_services); + return bot.MuteAsync(request.GuildId, + request.UserId, + request.Reason + $" %{request.ModeratorId}%", + request.Duration); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/PruneHandler.cs b/Hanekawa.Application/Handlers/Commands/Administration/PruneHandler.cs new file mode 100644 index 00000000..6157f264 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/PruneHandler.cs @@ -0,0 +1,21 @@ +using Hanekawa.Application.Contracts.Discord.Common; +using Hanekawa.Application.Extensions; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +public class PruneHandler : IRequestHandler +{ + private readonly IServiceProvider _services; + + public PruneHandler(IServiceProvider services) + => _services = services; + + public Task Handle(Prune request, CancellationToken cancellationToken) + { + var bot = request.Source.GetClient(_services); + return bot.PruneMessagesAsync(request.GuildId, + request.UserId, + []); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/UnbanHandler.cs b/Hanekawa.Application/Handlers/Commands/Administration/UnbanHandler.cs new file mode 100644 index 00000000..3c092793 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/UnbanHandler.cs @@ -0,0 +1,21 @@ +using Hanekawa.Application.Contracts.Discord.Common; +using Hanekawa.Application.Extensions; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +public class UnbanHandler : IRequestHandler +{ + private readonly IServiceProvider _services; + + public UnbanHandler(IServiceProvider services) + => _services = services; + + public Task Handle(Unban request, CancellationToken cancellationToken) + { + var bot = request.Source.GetClient(_services); + return bot.UnbanAsync(request.GuildId, + request.UserId, + request.Reason + $" %{request.ModeratorId}%"); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Administration/UnmuteHandler.cs b/Hanekawa.Application/Handlers/Commands/Administration/UnmuteHandler.cs new file mode 100644 index 00000000..110708b6 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Administration/UnmuteHandler.cs @@ -0,0 +1,20 @@ +using Hanekawa.Application.Contracts.Discord.Common; +using Hanekawa.Application.Extensions; +using MediatR; + +namespace Hanekawa.Application.Handlers.Commands.Administration; + +public class UnmuteHandler : IRequestHandler +{ + private readonly IServiceProvider _services; + public UnmuteHandler(IServiceProvider services) + => _services = services; + + public Task Handle(Unmute request, CancellationToken cancellationToken) + { + var bot = request.Source.GetClient(_services); + return bot.UnmuteAsync(request.GuildId, + request.UserId, + request.Reason + $" %{request.ModeratorId}%"); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Boost/BoostCommands.cs b/Hanekawa.Application/Handlers/Commands/Boost/BoostCommands.cs new file mode 100644 index 00000000..d4da4a81 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Boost/BoostCommands.cs @@ -0,0 +1,32 @@ +using System.Runtime.InteropServices; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Hanekawa.Entities.Configs; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Handlers.Commands.Boost; + +public interface IBoostCommandService +{ + ValueTask?> ListAsync(ulong guildId); +} + +internal class BoostCommands : IBoostCommandService +{ + private readonly IDbContext _context; + + public BoostCommands(IDbContext context) + { + _context = context; + } + + public async ValueTask?> ListAsync(ulong guildId) + { + var config = await _context.GuildConfigs + .Include(e => e.BoostConfig) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + return config is null or { BoostConfig: null} + ? null + : new Response(config); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Club/ClubCommandService.cs b/Hanekawa.Application/Handlers/Commands/Club/ClubCommandService.cs new file mode 100644 index 00000000..cff5a539 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Club/ClubCommandService.cs @@ -0,0 +1,185 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Handlers.Commands.Club; + +/// +public class ClubCommandService(IDbContext db) : IClubCommandService +{ + /// + public async Task> Create(ulong guildId, string name, string description, ulong authorId) + { + var existingClub = await db.Clubs.FirstOrDefaultAsync(c => c.GuildId == guildId && c.Name == name); + if (existingClub != null) + { + return new Response(new Message($"A club with the name '{name}' already exists")); + } + + // Check if user already owns a club + var existingOwnership = await db.Clubs.AnyAsync(c => c.GuildId == guildId && c.OwnerId == authorId); + if (existingOwnership) + { + return new Response(new Message("You already own a club. You can only own one club at a time.")); + } + + var club = new Entities.Club.Club + { + GuildId = guildId, + Name = name, + Description = description, + OwnerId = authorId, + CreatedAt = DateTimeOffset.UtcNow + }; + + // Add owner as a member + var member = new Entities.Club.ClubMember + { + GuildId = guildId, + ClubName = name, + UserId = authorId, + JoinedAt = DateTimeOffset.UtcNow + }; + + await db.Clubs.AddAsync(club); + await db.ClubMembers.AddAsync(member); + await db.SaveChangesAsync(); + + return new Response(new Message($"Club '{name}' has been created successfully!")); + } + + /// + public async Task> Delete(ulong guildId, string name, ulong authorId) + { + var club = await db.Clubs.FirstOrDefaultAsync(c => c.GuildId == guildId && c.Name == name); + if (club == null) + { + return new Response(new Message($"Club '{name}' doesn't exist")); + } + + if (club.OwnerId != authorId) + { + return new Response(new Message("You don't have permission to delete this club")); + } + + db.Clubs.Remove(club); + await db.SaveChangesAsync(); + + return new Response(new Message($"Club '{name}' has been deleted successfully")); + } + + /// + public async Task> List(ulong guildId) + { + var clubs = await db.Clubs + .Where(c => c.GuildId == guildId) + .Select(c => new { c.Name, c.Description, MemberCount = c.Members.Count }) + .ToListAsync(); + + if (!clubs.Any()) + { + return new Response(new Message("No clubs found in this server")); + } + + var message = "**Clubs in this server:**\n"; + foreach (var club in clubs) + { + message += $"- **{club.Name}** ({club.MemberCount} members): {club.Description}\n"; + } + + return new Response(new Message(message)); + } + + /// + public async Task> Join(ulong guildId, string name, ulong authorId) + { + var club = await db.Clubs + .Include(c => c.Members) + .FirstOrDefaultAsync(c => c.GuildId == guildId && c.Name == name); + + if (club == null) + { + return new Response(new Message($"Club '{name}' doesn't exist")); + } + + if (club.Members.Any(m => m.UserId == authorId)) + { + return new Response(new Message("You are already a member of this club")); + } + + var member = new Entities.Club.ClubMember + { + GuildId = guildId, + ClubName = name, + UserId = authorId, + JoinedAt = DateTimeOffset.UtcNow + }; + + await db.ClubMembers.AddAsync(member); + await db.SaveChangesAsync(); + + return new Response(new Message($"You have joined the club '{name}'")); + } + + /// + public async Task> Leave(ulong guildId, string name, ulong authorId) + { + var club = await db.Clubs + .Include(c => c.Members) + .FirstOrDefaultAsync(c => c.GuildId == guildId && c.Name == name); + + if (club == null) + { + return new Response(new Message($"Club '{name}' doesn't exist")); + } + + if (club.OwnerId == authorId) + { + return new Response(new Message("As the owner, you cannot leave your club. You must delete it or transfer ownership first.")); + } + + var membership = club.Members.FirstOrDefault(m => m.UserId == authorId); + if (membership == null) + { + return new Response(new Message("You are not a member of this club")); + } + + db.ClubMembers.Remove(membership); + await db.SaveChangesAsync(); + + return new Response(new Message($"You have left the club '{name}'")); + } + + /// + public async Task> Info(ulong guildId, string name) + { + var club = await db.Clubs + .Include(c => c.Members) + .FirstOrDefaultAsync(c => c.GuildId == guildId && c.Name == name); + + if (club == null) + { + return new Response(new Message($"Club '{name}' doesn't exist")); + } + + var message = $"**Club: {club.Name}**\n" + + $"Description: {club.Description}\n" + + $"Owner: <@{club.OwnerId}>\n" + + $"Created: {club.CreatedAt:yyyy-MM-dd}\n" + + $"Members: {club.Members.Count}\n\n" + + "**Member List:**\n"; + + foreach (var member in club.Members.OrderBy(m => m.JoinedAt)) + { + var joinedDate = member.JoinedAt.ToString("yyyy-MM-dd"); + var ownerIndicator = member.UserId == club.OwnerId ? " 👑" : ""; + message += $"- <@{member.UserId}> (joined: {joinedDate}){ownerIndicator}\n"; + } + + return new Response(new Message(message)); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Settings/GreetService.cs b/Hanekawa.Application/Handlers/Commands/Settings/GreetService.cs new file mode 100644 index 00000000..88ac052f --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Settings/GreetService.cs @@ -0,0 +1,111 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using OneOf; +using OneOf.Types; + +namespace Hanekawa.Application.Handlers.Commands.Settings; + +public class GreetService(IDbContext db, ILogger logger) : IGreetService +{ + public async Task SetChannel(ulong guildId, TextChannel channel) + { + logger.LogInformation("Setting greet channel to {Channel} for guild {Guild}", + channel.Id, guildId); + var config = await GetOrCreateConfig(guildId); + config.GreetConfig!.Channel = channel.Id; + await db.SaveChangesAsync(); + return $"Set greet channel to {channel.Mention} !"; + } + + public async Task SetMessage(ulong guildId, string message) + { + logger.LogInformation("Setting greet message to {Message} for guild {Guild}", + message, guildId); + var config = await GetOrCreateConfig(guildId); + config.GreetConfig!.Message = message; + await db.SaveChangesAsync(); + return "Updated greet message !"; + } + + public async Task SetImage(ulong guildId, string url, ulong uploaderId) + { + logger.LogInformation("Setting greet image to {Url} for guild {Guild}", url, guildId); + var config = await GetOrCreateConfig(guildId); + + config.GreetConfig!.Images.Add(new GreetImage + { + GuildId = guildId, + ImageUrl = url, + Uploader = uploaderId, + CreatedAt = DateTimeOffset.UtcNow + }); + await db.SaveChangesAsync(); + return "Updated greet image !"; + } + + public async Task>> ListImages(ulong guildId) + { + logger.LogInformation("Listing greet images for guild {Guild}", guildId); + var config = await db.GuildConfigs + .Include(x => x.GreetConfig) + .ThenInclude(x => x.Images) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + + if (config?.GreetConfig is null || config.GreetConfig.Images.Count == 0) return new NotFound(); + + return config.GreetConfig.Images; + } + + public async Task RemoveImage(ulong guildId, int id) + { + logger.LogInformation("Removing greet image {Id} for guild {Guild}", id, guildId); + var config = await db.GuildConfigs + .Include(x => x.GreetConfig) + .ThenInclude(x => x.Images) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + if (config?.GreetConfig is null) return false; + for (var i = 0; i < config.GreetConfig.Images.Count; i++) + { + var x = config.GreetConfig.Images[i]; + if (x.Id != id) continue; + config.GreetConfig.Images.RemoveAt(i); + await db.SaveChangesAsync(); + return true; + } + logger.LogWarning("Could not find greet image {Id} for guild {Guild}", id, guildId); + return false; + } + + public async Task ToggleImage(ulong guildId) + { + var config = await GetOrCreateConfig(guildId); + logger.LogInformation("Toggling greet image for guild {Guild} from {Old} to {New}", guildId, + config.GreetConfig!.ImageEnabled, !config.GreetConfig.ImageEnabled); + config.GreetConfig.ImageEnabled = !config.GreetConfig.ImageEnabled; + await db.SaveChangesAsync(); + return $"{(config.GreetConfig.ImageEnabled ? "Enabled" : "Disabled")} greet image !"; + } + + private async Task GetOrCreateConfig(ulong guildId, CancellationToken cancellationToken = default) + { + var config = await db.GuildConfigs.Include(e => e.GreetConfig) + .FirstOrDefaultAsync(e => e.GuildId == guildId, cancellationToken: cancellationToken); + var addToDb = false; + if (config is null) + { + addToDb = true; + config ??= new GuildConfig { GuildId = guildId }; + } + config.GreetConfig ??= new GreetConfig { GuildId = guildId }; + if (addToDb) + { + await db.GuildConfigs.AddAsync(config, cancellationToken); + } + + return config; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Settings/LevelCommandService.cs b/Hanekawa.Application/Handlers/Commands/Settings/LevelCommandService.cs new file mode 100644 index 00000000..6da49edd --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Settings/LevelCommandService.cs @@ -0,0 +1,42 @@ +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Entities.Levels; + +namespace Hanekawa.Application.Handlers.Commands.Settings; + +public class LevelCommandService : ILevelCommandService +{ + public Task AddAsync(ulong guildId, ulong roleId, int level, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task RemoveAsync(ulong guildId, ulong roleId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task> ListAsync(ulong guildId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task ModifyAsync(ulong guildId, ulong roleId, int level, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task CreateBoostPeriodAsync(ulong guildId, TimeSpan duration, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task RemoveBoostPeriodAsync(ulong guildId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task> ListBoostPeriodsAsync(ulong guildId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Commands/Settings/LogSettingService.cs b/Hanekawa.Application/Handlers/Commands/Settings/LogSettingService.cs new file mode 100644 index 00000000..797dc8b8 --- /dev/null +++ b/Hanekawa.Application/Handlers/Commands/Settings/LogSettingService.cs @@ -0,0 +1,59 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Handlers.Commands.Settings; + +public class LogSettingService : ILogService +{ + private readonly ILogger _logger; + private readonly IDbContext _dbContext; + + public LogSettingService(ILogger logger, IDbContext dbContext) + { + _logger = logger; + _dbContext = dbContext; + } + + public async Task SetJoinLeaveLogChannelAsync(ulong guildId, ulong? channelId) + { + var cfg = await _dbContext.GuildConfigs.Include(x => x.LogConfig) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + if (cfg?.LogConfig is null) return; + cfg.LogConfig.JoinLeaveLogChannelId = channelId; + await _dbContext.SaveChangesAsync(); + _logger.LogInformation("Set join/leave log channel to {Channel} for guild {Guild}", channelId, guildId); + } + + public async Task SetMessageLogChannelAsync(ulong guildId, ulong? channelId) + { + var cfg = await _dbContext.GuildConfigs.Include(x => x.LogConfig) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + + if (cfg?.LogConfig is null) return; + cfg.LogConfig.MessageLogChannelId = channelId; + await _dbContext.SaveChangesAsync(); + _logger.LogInformation("Set message log channel to {Channel} for guild {Guild}", channelId, guildId); + } + + public async Task SetModLogChannelAsync(ulong guildId, ulong? channelId) + { + var cfg = await _dbContext.GuildConfigs.Include(x => x.LogConfig) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + if (cfg?.LogConfig is null) return; + cfg.LogConfig.ModLogChannelId = channelId; + await _dbContext.SaveChangesAsync(); + _logger.LogInformation("Set mod log channel to {Channel} for guild {Guild}", channelId, guildId); + } + + public async Task SetVoiceLogChannelAsync(ulong guildId, ulong? channelId) + { + var cfg = await _dbContext.GuildConfigs.Include(x => x.LogConfig) + .FirstOrDefaultAsync(x => x.GuildId == guildId); + if (cfg?.LogConfig is null) return; + cfg.LogConfig.VoiceLogChannelId = channelId; + await _dbContext.SaveChangesAsync(); + _logger.LogInformation("Set voice log channel to {Channel} for guild {Guild}", channelId, guildId); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Internal/BotService.cs b/Hanekawa.Application/Handlers/Services/Internal/BotService.cs new file mode 100644 index 00000000..2eec42e6 --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Internal/BotService.cs @@ -0,0 +1,48 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Configs; + +namespace Hanekawa.Application.Handlers.Services.Internal; + +public interface IBotService +{ + ValueTask LeftGuildAsync(ulong guildId); + ValueTask JoinedGuildAsync(ulong guildId); +} + +internal sealed class BotService : IBotService +{ + private readonly IDbContext _db; + + public BotService(IDbContext db) + { + _db = db; + } + + public async ValueTask LeftGuildAsync(ulong guildId) + { + var guild = await _db.GuildConfigs.FindAsync(guildId); + if (guild is not null) + { + return; + } + + await _db.GuildConfigs.AddAsync(new GuildConfig + { + GuildId = guildId + + }); + await _db.SaveChangesAsync(); + } + + public async ValueTask JoinedGuildAsync(ulong guildId) + { + var guild = await _db.GuildConfigs.FindAsync(guildId); + if (guild is null) + { + return; + } + + _db.GuildConfigs.Remove(guild); + await _db.SaveChangesAsync(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Levels/LevelUpRoleHandler.cs b/Hanekawa.Application/Handlers/Services/Levels/LevelUpRoleHandler.cs new file mode 100644 index 00000000..36f9c35c --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Levels/LevelUpRoleHandler.cs @@ -0,0 +1,31 @@ +using Hanekawa.Application.Contracts; +using Hanekawa.Application.Interfaces.Services; +using MediatR; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Handlers.Services.Levels; + +public class LevelUpRoleHandler : IRequestHandler +{ + private readonly ILogger _logger; + private readonly ILevelService _levelService; + + public LevelUpRoleHandler(ILogger logger, ILevelService levelService) + { + _logger = logger; + _levelService = levelService; + } + + /// + /// Handles the level up event. + /// + /// User information containing the new level of user + /// + /// + public async Task Handle(LevelUp request, CancellationToken cancellationToken) + { + _logger.LogInformation("handing out roles for user {UserId} in guild {GuildId} for level {Level}", + request.Member.Id, request.Member.Guild.GuildId, request.Level); + await _levelService.AdjustRolesAsync(request.Member, request.Level, request.GuildConfig); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Levels/MessageReceivedExperienceHandler.cs b/Hanekawa.Application/Handlers/Services/Levels/MessageReceivedExperienceHandler.cs new file mode 100644 index 00000000..537ab2c6 --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Levels/MessageReceivedExperienceHandler.cs @@ -0,0 +1,26 @@ +using Hanekawa.Application.Contracts.Discord; +using Hanekawa.Application.Contracts.Discord.Services; +using Hanekawa.Application.Interfaces.Services; +using MediatR; +using Microsoft.Extensions.Configuration; + +namespace Hanekawa.Application.Handlers.Services.Levels; + +public class MessageReceivedExperienceHandler: INotificationHandler +{ + private readonly IConfiguration _configuration; + private readonly ILevelService _levelService; + + public MessageReceivedExperienceHandler(ILevelService levelService, IConfiguration configuration) + { + _levelService = levelService; + _configuration = configuration; + } + + public async Task Handle(MessageReceived request, CancellationToken cancellationToken) + { + await _levelService.AddExperienceAsync(request.Member, + Random.Shared.Next(Convert.ToInt32(_configuration["expLower"]), + Convert.ToInt32(_configuration["expUpper"]))); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Logs/UserBannedHandler.cs b/Hanekawa.Application/Handlers/Services/Logs/UserBannedHandler.cs new file mode 100644 index 00000000..9bdf4b5f --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Logs/UserBannedHandler.cs @@ -0,0 +1,48 @@ +using Hanekawa.Application.Contracts.Discord; +using Hanekawa.Application.Contracts.Discord.Services; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Color = System.Drawing.Color; + +namespace Hanekawa.Application.Handlers.Services.Logs; + +public class UserBannedHandler : INotificationHandler +{ + private readonly IBot _bot; + private readonly IDbContext _db; + + public UserBannedHandler(IBot bot, IDbContext db) + { + _bot = bot; + _db = db; + } + + public async Task Handle(UserBanned request, CancellationToken cancellationToken) + { + var cfg = await _db.GuildConfigs.Include(x => x.LogConfig) + .FirstOrDefaultAsync(x => x.GuildId == request.Member.Guild.GuildId, cancellationToken: cancellationToken); + if (cfg is { LogConfig.ModLogChannelId: null }) return; + var channel = _bot.GetChannel(request.Member.Guild.GuildId, cfg!.LogConfig.ModLogChannelId.Value); + if (channel is null) + { + cfg.LogConfig.ModLogChannelId = null; + await _db.SaveChangesAsync(cancellationToken); + return; + } + + await _bot.SendMessageAsync(channel.Value, new Embed + { + Title = $"User Banned | Case ID: {request.Member.Id} | ${request.Member.Guild.GuildId}", + Color = Color.Red.ToArgb(), + Fields = + [ + new EmbedField("User", $"<@{request.Member.Id}>", false), + new EmbedField("Moderator", "N/A", false), + new EmbedField("Reason", "No reason provided", false) + ] + }); + return; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Logs/UserJoinedHandler.cs b/Hanekawa.Application/Handlers/Services/Logs/UserJoinedHandler.cs new file mode 100644 index 00000000..2ee719b9 --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Logs/UserJoinedHandler.cs @@ -0,0 +1,13 @@ +using Hanekawa.Application.Contracts.Discord; +using Hanekawa.Application.Contracts.Discord.Services; +using MediatR; + +namespace Hanekawa.Application.Handlers.Services.Logs; + +public class UserJoinedHandler : INotificationHandler +{ + public Task Handle(UserJoin request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Logs/UserLeftHandler.cs b/Hanekawa.Application/Handlers/Services/Logs/UserLeftHandler.cs new file mode 100644 index 00000000..1d4ccc63 --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Logs/UserLeftHandler.cs @@ -0,0 +1,13 @@ +using Hanekawa.Application.Contracts.Discord; +using Hanekawa.Application.Contracts.Discord.Services; +using MediatR; + +namespace Hanekawa.Application.Handlers.Services.Logs; + +public class UserLeftHandler : INotificationHandler +{ + public Task Handle(UserLeave request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Logs/UserUnbannedHandler.cs b/Hanekawa.Application/Handlers/Services/Logs/UserUnbannedHandler.cs new file mode 100644 index 00000000..0cc3135f --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Logs/UserUnbannedHandler.cs @@ -0,0 +1,48 @@ +using Hanekawa.Application.Contracts.Discord; +using Hanekawa.Application.Contracts.Discord.Services; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Color = System.Drawing.Color; + +namespace Hanekawa.Application.Handlers.Services.Logs; + +public class UserUnbannedHandler : INotificationHandler +{ + private readonly IBot _bot; + private readonly IDbContext _db; + + public UserUnbannedHandler(IBot bot, IDbContext db) + { + _bot = bot; + _db = db; + } + + public async Task Handle(UserUnbanned request, CancellationToken cancellationToken) + { + var cfg = await _db.GuildConfigs.Include(x => x.LogConfig) + .FirstOrDefaultAsync(x => x.GuildId == request.Member.Guild.GuildId, cancellationToken: cancellationToken); + if (cfg is { LogConfig.ModLogChannelId: null }) return; + var channel = _bot.GetChannel(request.Member.Guild.GuildId, cfg.LogConfig.ModLogChannelId.Value); + if (channel is null) + { + cfg.LogConfig.ModLogChannelId = null; + await _db.SaveChangesAsync(cancellationToken); + return; + } + + await _bot.SendMessageAsync(channel.Value, new Embed + { + Title = $"User Banned | Case ID: {request.Member.Id} | ${request.Member.Guild.GuildId}", + Color = Color.LimeGreen.ToArgb(), + Fields = + [ + new EmbedField("User", $"<@{request.Member.Id}>", false), + new EmbedField("Moderator", "N/A", false), + new EmbedField("Reason", "No reason provided", false) + ] + }); + return; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Metrics/CommandMetricHandler.cs b/Hanekawa.Application/Handlers/Services/Metrics/CommandMetricHandler.cs new file mode 100644 index 00000000..c031b698 --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Metrics/CommandMetricHandler.cs @@ -0,0 +1,13 @@ +using MediatR; + +namespace Hanekawa.Application.Handlers.Services.Metrics; + +public record CommandMetric(ulong GuildId, ulong UserId, string Command, DateTimeOffset Timestamp) : IRequest; + +public class CommandMetricHandler : IRequestHandler +{ + public Task Handle(CommandMetric request, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Warnings/WarningClearHandler.cs b/Hanekawa.Application/Handlers/Services/Warnings/WarningClearHandler.cs new file mode 100644 index 00000000..94892b0e --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Warnings/WarningClearHandler.cs @@ -0,0 +1,50 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Hanekawa.Entities.Discord; +using Hanekawa.Localize; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Handlers.Services.Warnings; + +public record WarningClear(DiscordMember User, ulong ModeratorId, string? Reason, bool All = false) + : IRequest>; + +public class WarningClearHandler(IDbContext db, ILogger logger) + : IRequestHandler> +{ + public async Task> Handle(WarningClear request, CancellationToken cancellationToken) + { + if (request.All) + { + var warnings = await db.Warnings.Where(x => x.GuildId == request.User.Guild.GuildId + && x.UserId == request.User.Id + && x.Valid) + .ToArrayAsync(cancellationToken: cancellationToken); + for (var i = 0; i < warnings.Length; i++) + { + var x = warnings[i]; + x.Valid = false; + } + await db.SaveChangesAsync(); + return new Response(new Message(string.Format(Localization.ClearedAllWarnUserMention, + request.User.Mention))); + } + var warning = await db.Warnings.FirstOrDefaultAsync(x => x.GuildId == request.User.Guild.GuildId + && x.UserId == request.User.Id + && x.Valid, + cancellationToken: cancellationToken); + if (warning is null) + { + return new Response(new Message(string.Format(Localization.NoWarningsUserMention, + request.User.Mention))); + } + + warning.Valid = false; + db.Warnings.Update(warning); + await db.SaveChangesAsync(); + return new Response(new Message(string.Format(Localization.ClearedWarningUserMention, + request.User.Mention))); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Warnings/WarningListHandler.cs b/Hanekawa.Application/Handlers/Services/Warnings/WarningListHandler.cs new file mode 100644 index 00000000..a9ca34ba --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Warnings/WarningListHandler.cs @@ -0,0 +1,27 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Hanekawa.Extensions; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Handlers.Services.Warnings; + +public record WarningList(ulong GuildId, ulong? UserId) : IRequest>>; + +public class WarningListHandler(IDbContext db ) : IRequestHandler>> +{ + public async Task>> Handle(WarningList request, CancellationToken cancellationToken) + { + var result = await db.Warnings.Where(x => + x.GuildId == request.GuildId && + x.UserId == request.UserId) + .ToArrayAsync(cancellationToken: cancellationToken); + if (result.Length == 0) + { + return new Response>(new Pagination([new Message("No warnings found")])); + } + + var pages = result.BuildPage().Paginate(); + return new Response>(new Pagination(pages)); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Handlers/Services/Warnings/WarningReceivedHandler.cs b/Hanekawa.Application/Handlers/Services/Warnings/WarningReceivedHandler.cs new file mode 100644 index 00000000..4dc7e54e --- /dev/null +++ b/Hanekawa.Application/Handlers/Services/Warnings/WarningReceivedHandler.cs @@ -0,0 +1,30 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Users; +using Hanekawa.Localize; +using MediatR; + +namespace Hanekawa.Application.Handlers.Services.Warnings; + +public record WarningReceived(DiscordMember User, string Warning, ulong ModeratorId) : IRequest>; + +public class WarningReceivedHandler(IDbContext db) : IRequestHandler> +{ + public async Task> Handle(WarningReceived request, CancellationToken cancellationToken) + { + await db.Warnings.AddAsync(new Warning + { + Id = Guid.NewGuid(), + GuildId = request.User.Guild.GuildId, + UserId = request.User.Id, + ModeratorId = request.ModeratorId, + Reason = request.Warning, + Valid = true, + CreatedAt = DateTimeOffset.UtcNow + }, cancellationToken); + await db.SaveChangesAsync(); + // Change to mention the user + return new Response(new Message(string.Format(Localization.WarnedUser, request.User.Mention))); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Hanekawa.Application.csproj b/Hanekawa.Application/Hanekawa.Application.csproj new file mode 100644 index 00000000..7b826605 --- /dev/null +++ b/Hanekawa.Application/Hanekawa.Application.csproj @@ -0,0 +1,31 @@ + + + + net9.0 + preview + enable + enable + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Commands/IAdministrationCommandService.cs b/Hanekawa.Application/Interfaces/Commands/IAdministrationCommandService.cs new file mode 100644 index 00000000..6df81b19 --- /dev/null +++ b/Hanekawa.Application/Interfaces/Commands/IAdministrationCommandService.cs @@ -0,0 +1,84 @@ +using Hanekawa.Entities; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Interfaces.Commands; + +public interface IAdministrationCommandService +{ + /// + /// + /// + /// + /// + /// + /// + /// + Task> BanUserAsync(DiscordMember user, ulong moderatorId, string reason, int days = 0); + + /// + /// + /// + /// + /// + /// + /// + /// + Task> UnbanUserAsync(Guild guild, ulong userId, ulong moderatorId, string reason); + + /// + /// + /// + /// + /// + /// + /// + Task> KickUserAsync(DiscordMember user, ulong moderatorId, string reason); + + /// + /// + /// + /// + /// + /// + /// + /// + Task> MuteUserAsync(DiscordMember user, ulong moderatorId, string reason, TimeSpan duration); + + /// + /// + /// + /// + /// + /// + /// + Task> UnmuteUserAsync(DiscordMember user, ulong moderatorId, string reason); + + /// + /// + /// + /// + /// + /// + /// + Task> AddRoleAsync(DiscordMember user, ulong moderatorId, ulong roleId); + + /// + /// + /// + /// + /// + /// + /// + Task> RemoveRoleAsync(DiscordMember user, ulong moderatorId, ulong roleId); + + /// + /// + /// + /// + /// + /// + /// + /// + /// + Task> PruneAsync(ulong guildId, ulong channelId, ulong[] messageIds, ulong moderatorId, string reason); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Commands/IClubCommandService.cs b/Hanekawa.Application/Interfaces/Commands/IClubCommandService.cs new file mode 100644 index 00000000..abf0f38a --- /dev/null +++ b/Hanekawa.Application/Interfaces/Commands/IClubCommandService.cs @@ -0,0 +1,62 @@ +using System.Threading.Tasks; +using Hanekawa.Entities; + +namespace Hanekawa.Application.Interfaces.Commands; + +/// +/// Service for managing clubs in a guild +/// +public interface IClubCommandService +{ + /// + /// Creates a new club in the guild + /// + /// The ID of the guild + /// The name of the club + /// The description of the club + /// The ID of the user creating the club + /// A message indicating success or failure + Task> Create(ulong guildId, string name, string description, ulong authorId); + + /// + /// Deletes a club from the guild + /// + /// The ID of the guild + /// The name of the club + /// The ID of the user deleting the club + /// A message indicating success or failure + Task> Delete(ulong guildId, string name, ulong authorId); + + /// + /// Lists all clubs in the guild + /// + /// The ID of the guild + /// A message with the list of clubs + Task> List(ulong guildId); + + /// + /// Joins a club in the guild + /// + /// The ID of the guild + /// The name of the club + /// The ID of the user joining the club + /// A message indicating success or failure + Task> Join(ulong guildId, string name, ulong authorId); + + /// + /// Leaves a club in the guild + /// + /// The ID of the guild + /// The name of the club + /// The ID of the user leaving the club + /// A message indicating success or failure + Task> Leave(ulong guildId, string name, ulong authorId); + + /// + /// Gets information about a club + /// + /// The ID of the guild + /// The name of the club + /// A message with information about the club + Task> Info(ulong guildId, string name); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Commands/IGreetService.cs b/Hanekawa.Application/Interfaces/Commands/IGreetService.cs new file mode 100644 index 00000000..2bb45417 --- /dev/null +++ b/Hanekawa.Application/Interfaces/Commands/IGreetService.cs @@ -0,0 +1,55 @@ +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using OneOf; +using OneOf.Types; + +namespace Hanekawa.Application.Interfaces.Commands; + +/// +/// +/// +public interface IGreetService +{ + /// + /// + /// + /// + /// + /// + Task SetChannel(ulong guildId, TextChannel channel); + /// + /// + /// + /// + /// + /// + Task SetMessage(ulong guildId, string message); + + /// + /// + /// + /// + /// + /// User uploading image + /// + Task SetImage(ulong guildId, string url, ulong uploaderId); + /// + /// + /// + /// + /// + Task>> ListImages(ulong guildId); + /// + /// + /// + /// + /// + /// + Task RemoveImage(ulong guildId, int id); + /// + /// + /// + /// + /// + Task ToggleImage(ulong guildId); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Commands/ILevelCommandService.cs b/Hanekawa.Application/Interfaces/Commands/ILevelCommandService.cs new file mode 100644 index 00000000..9aa73e82 --- /dev/null +++ b/Hanekawa.Application/Interfaces/Commands/ILevelCommandService.cs @@ -0,0 +1,15 @@ +using Hanekawa.Entities.Levels; + +namespace Hanekawa.Application.Interfaces.Commands; + +public interface ILevelCommandService +{ + Task AddAsync(ulong guildId, ulong roleId, int level, CancellationToken cancellationToken = default); + Task RemoveAsync(ulong guildId, ulong roleId, CancellationToken cancellationToken = default); + Task> ListAsync(ulong guildId, CancellationToken cancellationToken = default); + Task ModifyAsync(ulong guildId, ulong roleId, int level, CancellationToken cancellationToken = default); + + Task CreateBoostPeriodAsync(ulong guildId, TimeSpan duration, CancellationToken cancellationToken = default); + Task RemoveBoostPeriodAsync(ulong guildId, CancellationToken cancellationToken = default); + Task> ListBoostPeriodsAsync(ulong guildId, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Commands/ILogService.cs b/Hanekawa.Application/Interfaces/Commands/ILogService.cs new file mode 100644 index 00000000..1166cc23 --- /dev/null +++ b/Hanekawa.Application/Interfaces/Commands/ILogService.cs @@ -0,0 +1,36 @@ +namespace Hanekawa.Application.Interfaces.Commands; + +/// +/// +/// +public interface ILogService +{ + /// + /// + /// + /// + /// + /// + Task SetJoinLeaveLogChannelAsync(ulong guildId, ulong? channelId); + /// + /// + /// + /// + /// + /// + Task SetMessageLogChannelAsync(ulong guildId, ulong? channelId); + /// + /// + /// + /// + /// + /// + Task SetModLogChannelAsync(ulong guildId, ulong? channelId); + /// + /// + /// + /// + /// + /// + Task SetVoiceLogChannelAsync(ulong guildId, ulong? channelId); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Commands/IWarningCommandService.cs b/Hanekawa.Application/Interfaces/Commands/IWarningCommandService.cs new file mode 100644 index 00000000..a78b8e76 --- /dev/null +++ b/Hanekawa.Application/Interfaces/Commands/IWarningCommandService.cs @@ -0,0 +1,40 @@ +namespace Hanekawa.Application.Interfaces.Commands; + +/// +/// Warning command service. +/// +public interface IWarningCommandService +{ + /// + /// + /// + /// + /// + /// + /// + /// + Task WarnUserAsync(ulong guildId, ulong userId, ulong moderatorId, string reason); + /// + /// Short summary of all users with valid warnings in a guild. + /// + /// + /// + Task> Warns(ulong guildId); + /// + /// Gets all valid warnings for a user. + /// + /// + /// + /// + Task> WarnsAsync(ulong guildId, ulong userId); + /// + /// Clear warnings from a user, updating the validity of all to false + /// + /// + /// + /// + /// + /// + /// + Task ClearUserWarnAsync(ulong guildId, ulong userId, ulong moderatorId, string reason, bool all = false); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/IBot.cs b/Hanekawa.Application/Interfaces/IBot.cs new file mode 100644 index 00000000..06d1e9ad --- /dev/null +++ b/Hanekawa.Application/Interfaces/IBot.cs @@ -0,0 +1,117 @@ +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Interfaces; + +/// +/// +/// +public interface IBot +{ + /// + /// + /// + /// + /// + /// + /// + /// + public Task BanAsync(ulong guildId, ulong userId, int days, string reason); + /// + /// + /// + /// + /// + /// + /// + public Task UnbanAsync(ulong guildId, ulong userId, string reason); + /// + /// + /// + /// + /// + /// + /// + public Task KickAsync(ulong guildId, ulong userId, string reason); + /// + /// + /// + /// + /// + /// + /// + /// + public Task MuteAsync(ulong guildId, ulong userId, string reason, TimeSpan duration); + /// + /// + /// + /// + /// + /// + /// + public Task UnmuteAsync(ulong guildId, ulong userId, string reason); + /// + /// + /// + /// + /// + /// + /// + public Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId); + /// + /// + /// + /// + /// + /// + /// + public Task RemoveRoleAsync(ulong guildId, ulong userId, ulong roleId); + /// + /// + /// + /// + /// + /// + public Task ModifyRolesAsync(DiscordMember member, ulong[] modifiedRoles); + /// + /// Gets a channel from a guild. + /// + /// + /// + /// + public ulong? GetChannel(ulong guildId, ulong channelId); + /// + /// Prune messages from a channel + /// + /// + /// + /// + /// + public Task PruneMessagesAsync(ulong guildId, ulong channelId, ulong[] messageIds); + + /// + /// Deletes a message from a channel + /// + /// + /// + /// + /// + public Task DeleteMessageAsync(ulong guildId, ulong channelId, ulong messageId); + + /// + /// Sends a message to a channel + /// + /// + /// + /// + /// + public Task SendMessageAsync(ulong channelId, string message, Attachment? attachment = null); + + /// + /// Sends a message to a channel with an embed + /// + /// + /// + /// + /// + public Task SendMessageAsync(ulong channelId, Embed embedMessage, Attachment? attachment = null); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/ICacheContext.cs b/Hanekawa.Application/Interfaces/ICacheContext.cs new file mode 100644 index 00000000..c74913c1 --- /dev/null +++ b/Hanekawa.Application/Interfaces/ICacheContext.cs @@ -0,0 +1,50 @@ +namespace Hanekawa.Application.Interfaces; + +public interface ICacheContext +{ + /// + /// Retrieve a value from cache by its key + /// + /// + /// + /// + TEntity? Get(string key); + + /// + /// Retrieve a value from cache by its key and either refresh or adds expiration time + /// + /// + /// + /// + /// + TEntity? Get(string key, TimeSpan expiration); + + /// + /// Attempts to add a key-value into cache + /// + /// + /// + /// + void Add(string key, TEntity value); + + /// + /// Attempts to add a key-value into cache with expiration time + /// + /// + /// + /// + /// + void Add(string key, TEntity value, TimeSpan expiration); + + /// + /// Removes a key from cache + /// + /// + /// + bool Remove(string key); + + /// + /// Retrieve a value from cache by its key or create a new one if it doesn't exist + /// + ValueTask GetOrCreateAsync(string key, Func> factory); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/IDbContext.cs b/Hanekawa.Application/Interfaces/IDbContext.cs new file mode 100644 index 00000000..9f056a3b --- /dev/null +++ b/Hanekawa.Application/Interfaces/IDbContext.cs @@ -0,0 +1,58 @@ +using System.Data.Common; +using Hanekawa.Entities; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Club; +using Hanekawa.Entities.Internals; +using Hanekawa.Entities.Levels; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Interfaces; + +/// +/// +/// Database context interface +/// +public interface IDbContext : IAsyncDisposable +{ + /// + /// Guild configuration store + /// + DbSet GuildConfigs { get; set; } + /// + /// User store + /// + DbSet Users { get; set; } + /// + /// Level requirement between each level + /// + DbSet LevelRequirements { get; set; } + /// + /// Warning store + /// + DbSet Warnings { get; set; } + /// + /// Logging store + /// + DbSet Logs { get; set; } + /// + /// Guild moderator store. Ban / Mute / etc + /// + DbSet ModerationLogs { get; set; } + /// + /// Club store + /// + DbSet Clubs { get; set; } + /// + /// Club members store + /// + DbSet ClubMembers { get; set; } + DbSet Items { get; set; } + DbSet ItemTypes { get; set; } + + Task SaveChangesAsync(CancellationToken cancellationToken = default); + Task EnsureDatabaseCreated(CancellationToken cancellationToken = default); + Task MigrateDatabaseAsync(CancellationToken cancellationToken = default); + DbConnection GetConnection(); + Task ExecuteQuery(string query, object? param = null, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/IImageService.cs b/Hanekawa.Application/Interfaces/IImageService.cs new file mode 100644 index 00000000..8cdaa9c4 --- /dev/null +++ b/Hanekawa.Application/Interfaces/IImageService.cs @@ -0,0 +1,39 @@ +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Users; +using SixLabors.ImageSharp; + +namespace Hanekawa.Application.Interfaces; + +/// +/// Service for creating images +/// +public interface IImageService +{ + /// + /// Creates a rank image + /// + /// Discord user + /// + /// + /// + Task DrawRankAsync(DiscordMember member, GuildUser userData, CancellationToken cancellationToken = default); + + /// + /// Creates a welcome image + /// + /// Discord user + /// + /// + /// + ValueTask DrawWelcomeAsync(DiscordMember member, GreetConfig cfg, CancellationToken cancellationToken = default); + + /// + /// Creates a profile image + /// + /// Discord user + /// + /// + /// + ValueTask DrawProfileAsync(DiscordMember member, GuildUser userData, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/IItemService.cs b/Hanekawa.Application/Interfaces/IItemService.cs new file mode 100644 index 00000000..6f3c26b7 --- /dev/null +++ b/Hanekawa.Application/Interfaces/IItemService.cs @@ -0,0 +1,13 @@ +using Hanekawa.Entities.Users; + +namespace Hanekawa.Application.Interfaces; + +public interface IItemService +{ + ValueTask GetItemByIdAsync(Guid itemId); + ValueTask GetItemByNameAsync(string itemName); + ValueTask> GetAllItemsAsync(); + ValueTask> GetAllItemTypesAsync(); + ValueTask UseItemAsync(ulong guildId, ulong userId, Guid itemId); + ValueTask CreateItemAsync(string name, string description, Guid typeId, int? price = null); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/IMetrics.cs b/Hanekawa.Application/Interfaces/IMetrics.cs new file mode 100644 index 00000000..a286d79d --- /dev/null +++ b/Hanekawa.Application/Interfaces/IMetrics.cs @@ -0,0 +1,13 @@ +namespace Hanekawa.Application.Interfaces; + +public interface IMetrics +{ + public TrackedDuration All(ulong? guildId = null); + + public TrackedDuration All(string name, ulong? guildId = null); + + public void IncrementCounter(ulong? guildId = null); + public void IncrementCounter(string name, ulong? guildId = null); + public TrackedDuration MeasureDuration(ulong? guildId = null); + public TrackedDuration MeasureDuration(string name, ulong? guildId = null); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/INotificationSqs.cs b/Hanekawa.Application/Interfaces/INotificationSqs.cs new file mode 100644 index 00000000..30350131 --- /dev/null +++ b/Hanekawa.Application/Interfaces/INotificationSqs.cs @@ -0,0 +1,9 @@ +using MediatR; + +namespace Hanekawa.Application.Interfaces; + +public interface IMetric { ulong GuildId { get; init; } } +public interface INotificationSqs : IMetric, INotification; + +public interface IMessageSqs : IMetric, IRequest; +public interface IMessageSqs : IMetric, IRequest; \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Services/IDropService.cs b/Hanekawa.Application/Interfaces/Services/IDropService.cs new file mode 100644 index 00000000..8e726efd --- /dev/null +++ b/Hanekawa.Application/Interfaces/Services/IDropService.cs @@ -0,0 +1,36 @@ +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Interfaces.Services; + +/// +/// Drop service +/// +public interface IDropService +{ + /// + /// Initiate a drop event + /// + /// + /// + /// + /// + Task DropAsync(TextChannel channel, DiscordMember user, CancellationToken cancellationToken = default); + + /// + /// Claims an active drop + /// + /// + /// + /// + /// + /// + Task ClaimAsync(ulong channelId, ulong msgId, DiscordMember user, CancellationToken cancellationToken = default); + + /// + /// Configure drop config + /// + /// + /// + Task Configure(Action action); +} \ No newline at end of file diff --git a/Hanekawa.Application/Interfaces/Services/ILevelService.cs b/Hanekawa.Application/Interfaces/Services/ILevelService.cs new file mode 100644 index 00000000..ee39dfdc --- /dev/null +++ b/Hanekawa.Application/Interfaces/Services/ILevelService.cs @@ -0,0 +1,10 @@ +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Application.Interfaces.Services; + +public interface ILevelService +{ + Task AddExperienceAsync(DiscordMember member, int experience); + Task AdjustRolesAsync(DiscordMember member, int level, GuildConfig config); +} \ No newline at end of file diff --git a/Hanekawa.Application/Metrics.cs b/Hanekawa.Application/Metrics.cs new file mode 100644 index 00000000..f37b581c --- /dev/null +++ b/Hanekawa.Application/Metrics.cs @@ -0,0 +1,109 @@ +using System.Diagnostics.Metrics; +using Hanekawa.Application.Interfaces; + +namespace Hanekawa.Application; + +public class Metrics(IMeterFactory meterFactory) : IMetrics +{ + private readonly Dictionary _metrics = new(); + + /// + public TrackedDuration All(ulong? guildId = null) + { + return All(nameof(T), guildId); + } + + /// + public TrackedDuration All(string name, ulong? guildId = null) + { + if (!_metrics.TryGetValue(name, out var metric)) metric = CreateMetric(name, guildId); + metric.GlobalCounter.Add(1); + if (guildId is not null) metric.GuildCounter[guildId.Value].Add(1); + return new TrackedDuration(TimeProvider.System, metric.Histogram); + } + + /// + public void IncrementCounter(ulong? guildId = null) + { + IncrementCounter(nameof(T)); + } + + /// + public void IncrementCounter(string name, ulong? guildId = null) + { + if (_metrics.TryGetValue(name, out var metric)) + { + metric.GlobalCounter.Add(1); + return; + } + metric = CreateMetric(name); + metric.GlobalCounter.Add(1); + } + + + /// + public TrackedDuration MeasureDuration(ulong? guildId = null) + { + return MeasureDuration(nameof(T)); + } + + /// + public TrackedDuration MeasureDuration(string name, ulong? guildId = null) + { + if (_metrics.TryGetValue(name, out var metric)) + return new TrackedDuration(TimeProvider.System, metric.Histogram); + var collection = CreateMetric(name); + return new TrackedDuration(TimeProvider.System, collection.Histogram); + } + + private MetricCollection CreateMetric(string name, ulong? guildId = null) + { + var meter = meterFactory.Create($"hanekawa.{name}"); + var counter = meter.CreateCounter($"hanekawa.{name}.request.counter"); + var guildCounter = new Dictionary>(); + if (guildId != null) + { + guildCounter.Add(guildId.Value, + meter.CreateCounter($"hanekawa.{name}-{guildId.Value}.request.counter")); + } + var histogram = meter.CreateHistogram($"hanekawa.{name}.request.duration"); + var collection = new MetricCollection(counter, guildCounter, histogram); + _metrics.TryAdd(name, collection); + return collection; + } +} + +public class TrackedDuration : IDisposable +{ + private readonly long _requestStartTime; + private readonly Histogram _histogram; + private readonly TimeProvider _timeProvider; + + public TrackedDuration(TimeProvider timeProvider, Histogram histogram) + { + _requestStartTime = timeProvider.GetTimestamp(); + _timeProvider = timeProvider; + _histogram = histogram; + } + + public void Dispose() + { + var elapsed = _timeProvider.GetElapsedTime(_requestStartTime); + _histogram.Record(elapsed.TotalMilliseconds); + } +} + +internal class MetricCollection +{ + public MetricCollection(Counter globalCounter, Dictionary> guildCounter, Histogram histogram) + { + GlobalCounter = globalCounter; + GuildCounter = guildCounter; + Histogram = histogram; + } + + public Counter GlobalCounter { get; } + public Dictionary> GuildCounter { get; } + public Histogram Histogram { get; } +} \ No newline at end of file diff --git a/Hanekawa.Application/Pipelines/MetricPipeline.cs b/Hanekawa.Application/Pipelines/MetricPipeline.cs new file mode 100644 index 00000000..0376b173 --- /dev/null +++ b/Hanekawa.Application/Pipelines/MetricPipeline.cs @@ -0,0 +1,30 @@ +using System.Diagnostics; +using Hanekawa.Application.Interfaces; +using MediatR; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Pipelines; + +public sealed class MetricPipeline : IPipelineBehavior where TRequest : notnull +{ + private readonly ILogger> _logger; + private readonly Metrics _metrics; + + public MetricPipeline(ILogger> logger, Metrics metrics) + { + _logger = logger; + _metrics = metrics; + } + + public async Task Handle(IMetric request, RequestHandlerDelegate next, CancellationToken cancellationToken) + { + var type = request.GetType(); + _metrics.IncrementCounter(type.Name); + using var _ = _metrics.MeasureDuration(type.Name); + var start = Stopwatch.GetTimestamp(); + var response = await next().ConfigureAwait(false); + var elapsedTime = Stopwatch.GetElapsedTime(start); + _logger.LogInformation("Request {Request} executed in {Elapsed}ms", nameof(request), elapsedTime); + return response; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Pipelines/WarningAdded.cs b/Hanekawa.Application/Pipelines/WarningAdded.cs new file mode 100644 index 00000000..7d2df129 --- /dev/null +++ b/Hanekawa.Application/Pipelines/WarningAdded.cs @@ -0,0 +1,29 @@ +using Hanekawa.Application.Handlers.Services.Warnings; +using Hanekawa.Application.Interfaces; +using MediatR; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Pipelines; + +public sealed class WarningAdded(IDbContext db, IBot bot) : IPipelineBehavior +{ + public async Task Handle(WarningReceived request, + RequestHandlerDelegate next, + CancellationToken cancellationToken) + { + var result = await next(); + var config = await db.GuildConfigs.Include(x => x.AdminConfig) + .FirstOrDefaultAsync(x => x.GuildId == request.User.Guild.GuildId, + cancellationToken: cancellationToken); + var warningCount = await db.Warnings.CountAsync(x => x.GuildId == request.User.Guild.GuildId + && x.UserId == request.User.Id + && x.Valid + && x.CreatedAt > DateTimeOffset.UtcNow.AddDays(-7), cancellationToken); + // TODO: Add a warning threshold to the guild configuration + if (warningCount >= config?.AdminConfig?.MaxWarnings) + await bot.MuteAsync(request.User.Guild.GuildId, request.User.Id, + $"Auto-mod warning threshold reached ({config.AdminConfig.MaxWarnings})", + TimeSpan.FromHours(2 * Convert.ToDouble(warningCount / 3))); + return result; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/ConfigService.cs b/Hanekawa.Application/Services/ConfigService.cs new file mode 100644 index 00000000..7a5221b4 --- /dev/null +++ b/Hanekawa.Application/Services/ConfigService.cs @@ -0,0 +1,99 @@ +using System.Text.Json; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Configs; +using Hanekawa.Interfaces; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Distributed; + +namespace Hanekawa.Application.Services; + +public class ConfigService : IConfigService +{ + private readonly IDistributedCache _cache; + private readonly IDbContext _db; + + public ConfigService(IDistributedCache cache, IDbContext db) + { + _cache = cache; + _db = db; + } + + public async ValueTask GetAsync(ulong guildId, CancellationToken cancellationToken = default) + { + var value = await _cache.GetStringAsync(KeyName(guildId), cancellationToken); + if (value is not null or { Length: 0 }) + { + var cachedConfig = JsonSerializer.Deserialize(value); + if (cachedConfig is not null) + { + return cachedConfig; + } + } + + var config = await _db.GuildConfigs.FirstOrDefaultAsync(x => x.GuildId == guildId, cancellationToken); + if (config is null) + { + config = new GuildConfig { GuildId = guildId }; + await _db.GuildConfigs.AddAsync(config, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); + } + + await SetAsync(guildId, config, cancellationToken); + return config; + } + + public async ValueTask GetAsync(ulong guildId, Type include, + CancellationToken cancellationToken = default) + { + var value = await _cache.GetStringAsync(KeyName(guildId), cancellationToken); + if (value is not null or { Length: 0 }) + { + var cachedConfig = JsonSerializer.Deserialize(value); + object? includeValue = cachedConfig?.GetType() + .GetProperties() + .FirstOrDefault(x => nameof(x.PropertyType) == include.Name) + ?.GetValue(cachedConfig); + if(cachedConfig is not null && includeValue is not null) + { + return cachedConfig; + } + } + + var config = await _db.GuildConfigs.Include(include.Name).FirstOrDefaultAsync(x => x.GuildId == guildId, cancellationToken); + if (config is null) + { + config = new GuildConfig { GuildId = guildId }; + await _db.GuildConfigs.AddAsync(config, cancellationToken); + await _db.SaveChangesAsync(cancellationToken); + } + await SetAsync(guildId, config, cancellationToken); + return config; + } + + public async ValueTask SetAsync(ulong key, T value, CancellationToken cancellationToken = default) + where T : class, IConfig, new() + { + string json = JsonSerializer.Serialize(value); + await _cache.SetStringAsync(KeyName(key), json, + new DistributedCacheEntryOptions { SlidingExpiration = TimeSpan.FromMinutes(5) }, token: cancellationToken); + } + + public async ValueTask RemoveAsync(ulong guildId, CancellationToken cancellationToken = default) + where T : class, IConfig, new() + { + await _cache.RemoveAsync(KeyName(guildId), cancellationToken); + } + + private static string KeyName(ulong key) where T : class, IConfig + => $"{key}-{typeof(T).Name}"; +} + +public interface IConfigService +{ + ValueTask GetAsync(ulong guildId, CancellationToken cancellationToken = default); + ValueTask GetAsync(ulong guildId, Type include, + CancellationToken cancellationToken = default); + + ValueTask SetAsync(ulong key, T value, CancellationToken cancellationToken = default) where T : class, IConfig, new(); + ValueTask RemoveAsync(ulong guildId, CancellationToken cancellationToken = default) where T : class, IConfig, new(); +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/DropService.cs b/Hanekawa.Application/Services/DropService.cs new file mode 100644 index 00000000..20f29afc --- /dev/null +++ b/Hanekawa.Application/Services/DropService.cs @@ -0,0 +1,143 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Services; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Services; + +/// +public class DropService : IDropService +{ + private readonly ILevelService _levelService; + private readonly ILogger _logger; + private readonly SemaphoreSlim _semaphoreSlim; + private readonly IServiceProvider _serviceProvider; + private readonly Random _random; + + public DropService(ILevelService levelService, ILogger logger, IServiceProvider serviceProvider) + { + _levelService = levelService; + _logger = logger; + _serviceProvider = serviceProvider; + _random = Random.Shared; + _semaphoreSlim = new SemaphoreSlim(1); + } + + public DropService(ILevelService levelService, ILogger logger, IServiceProvider serviceProvider, + Random random) + { + _levelService = levelService; + _logger = logger; + _serviceProvider = serviceProvider; + _random = random; + _semaphoreSlim = new SemaphoreSlim(1); + } + + /// + public async Task DropAsync(TextChannel channel, DiscordMember user, CancellationToken cancellationToken = default) + { + var chance = _random.Next(1000); + if (chance < 850) return; + + await using var scope = _serviceProvider.CreateAsyncScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var config = await db.GuildConfigs + .Include(x => x.DropConfig) + .FirstOrDefaultAsync(x => x.GuildId == channel.GuildId, + cancellationToken: cancellationToken); + if (config is null || config.DropConfig.Blacklist.Contains(channel.Id)) return; + + var msg = await _serviceProvider.GetRequiredService() + .SendMessageAsync(channel.Id, "A drop event has been triggered!\n" + + $"React with {config.DropConfig.Emote} as it appears to claim it!"); + + var emotes = user.Guild.Emotes + .OrderBy(_ => _random.Next()) + .Take(3) + .ToArray(); + + for (var i = 0; i < emotes.Length; i++) + { + Start: + // TODO: Drop service emote = 123? properly implement this + var emote = emotes[i].Name; + await Task.Delay(1500, cancellationToken); + if(emote is "") goto Start; + } + + var cache = scope.ServiceProvider.GetRequiredService(); + cache.Add($"{msg.ChannelId}-{msg.Id}-drop", user.Id); + } + + /// + public async Task ClaimAsync(ulong channelId, ulong msgId, DiscordMember user, CancellationToken cancellationToken = default) + { + await _semaphoreSlim.WaitAsync(cancellationToken); + _logger.LogDebug("{UserId}-{GuildId} entered the semaphore for drop claims", + user.Id, user.Guild.GuildId); + + await using var scope = _serviceProvider.CreateAsyncScope(); + var cache = scope.ServiceProvider.GetRequiredService(); + var value = cache.Get($"{msgId}-{channelId}-drop"); + if(value is null) return; + + var bot = _serviceProvider.GetRequiredService(); + await bot.DeleteMessageAsync(user.Guild.GuildId, channelId, msgId); + + var db = scope.ServiceProvider.GetRequiredService(); + var config = await db.GuildConfigs + .Include(x => x.DropConfig) + .FirstOrDefaultAsync(x => x.GuildId == user.Guild.GuildId, + cancellationToken: cancellationToken); + if (config is null) return; + + var exp = await _levelService.AddExperienceAsync(user, config.DropConfig.ExpReward); + await bot.SendMessageAsync(channelId, + $"Rewarded {user.Nickname ?? user.Username} with {exp ?? 0} experience for claiming the drop!"); + + cache.Remove($"{msgId}-{channelId}-drop"); + _semaphoreSlim.Release(); + _logger.LogDebug("{UserId}-{GuildId} exited the semaphore for drop claims", + user.Id, user.Guild.GuildId); + } + + /// + public async Task Configure(Action action) + { + var config = new DropConfig(); + action.Invoke(config); + await using var scope = _serviceProvider.CreateAsyncScope(); + var db = scope.ServiceProvider.GetRequiredService(); + var cfg = await db.GuildConfigs + .Include(x => x.DropConfig) + .FirstOrDefaultAsync(x => x.GuildId == config.GuildId) + ?? new GuildConfig { GuildId = config.GuildId }; + + if (cfg.DropConfig is null) + { + cfg.DropConfig = config; + goto Save; + } + + if (config.ExpReward is not 100) cfg.DropConfig.ExpReward = config.ExpReward; + if (config.Emote is not "") cfg.DropConfig.Emote = config.Emote; + + if (config.Blacklist.Length > 0) + { + var newBlacklist = new ulong[cfg.DropConfig.Blacklist.Length + config.Blacklist.Length]; + for (var i = 0; i < cfg.DropConfig.Blacklist.Length + config.Blacklist.Length; i++) + { + var x = i >= cfg.DropConfig.Blacklist.Length + ? config.Blacklist[i - cfg.DropConfig.Blacklist.Length] + : cfg.DropConfig.Blacklist[i]; + newBlacklist[i] = x; + } + } + Save: + await db.SaveChangesAsync(); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/Images/CommonImageService.cs b/Hanekawa.Application/Services/Images/CommonImageService.cs new file mode 100644 index 00000000..fbb76926 --- /dev/null +++ b/Hanekawa.Application/Services/Images/CommonImageService.cs @@ -0,0 +1,43 @@ +using Hanekawa.Application.Extensions; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace Hanekawa.Application.Services.Images; + +public class CommonImageService +{ + private readonly IHttpClientFactory _httpClientFactory; + public CommonImageService(IHttpClientFactory httpClientFactory) + { + _httpClientFactory = httpClientFactory; + } + + /// + /// Draws an avatar onto the image + /// + /// + /// Size of avatar + /// + /// + public async Task CreateAvatarAsync(string avatarUrl, int size, CancellationToken cancellationToken = default) + { + using var img = await GetImageFromUrlAsync(new Uri(avatarUrl), cancellationToken); + img.Mutate(e => + e.ConvertToAvatar(new Size(size), (int)Math.Ceiling((size * Math.PI) / (2 * Math.PI)))); + return img.CloneAs(); + } + + /// + /// Obtains the image memory stream from the given URI. + /// + /// + /// + /// + internal async Task GetImageFromUrlAsync(Uri uri, CancellationToken cancellationToken = default) + { + var client = _httpClientFactory.CreateClient("ImageService"); + var imgStream = await client.GetStreamAsync(uri, cancellationToken); + return await Image.LoadAsync(imgStream, cancellationToken); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/Images/ImageService.cs b/Hanekawa.Application/Services/Images/ImageService.cs new file mode 100644 index 00000000..3929ce1c --- /dev/null +++ b/Hanekawa.Application/Services/Images/ImageService.cs @@ -0,0 +1,58 @@ +using Hanekawa.Application.Extensions; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Settings.Images; +using Hanekawa.Entities.Users; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using SixLabors.Fonts; + +namespace Hanekawa.Application.Services.Images; + +/// +public class ImageService : IImageService +{ + private readonly IHttpClientFactory _httpClientFactory; + private readonly FontCollection _fontCollection; + private readonly IOptionsMonitor _settings; + private readonly ILogger _logger; + private readonly IDbContext _dbContext; + private readonly IConfigService _configService; + + public ImageService(IHttpClientFactory httpClientFactory, FontCollection fontCollection, + IOptionsMonitor settings, ILogger logger, IDbContext dbContext, IConfigService configService) + { + _httpClientFactory = httpClientFactory; + _fontCollection = fontCollection; + _settings = settings; + _logger = logger; + _dbContext = dbContext; + _configService = configService; + } + + /// + public ValueTask DrawWelcomeAsync(DiscordMember member, GreetConfig cfg, + CancellationToken cancellationToken = default) + { + return new WelcomeImageService(_httpClientFactory, _fontCollection, _logger) + .DrawAsync(member, cfg, cancellationToken); + } + + /// + public ValueTask DrawProfileAsync(DiscordMember member, GuildUser userData, + CancellationToken cancellationToken = default) + { + return new ProfileImageService(_settings.CurrentValue, _httpClientFactory, + _dbContext, _fontCollection, _logger, _configService) + .DrawAsync(member, userData, cancellationToken); + } + + /// + public Task DrawRankAsync(DiscordMember member, GuildUser userData, CancellationToken cancellationToken = default) + { + return new RankImageService(_settings.CurrentValue, _httpClientFactory, + _dbContext, _fontCollection, _logger, _configService) + .DrawAsync(member, userData, cancellationToken); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/Images/ProfileImageService.cs b/Hanekawa.Application/Services/Images/ProfileImageService.cs new file mode 100644 index 00000000..c6688cbc --- /dev/null +++ b/Hanekawa.Application/Services/Images/ProfileImageService.cs @@ -0,0 +1,227 @@ +using System.Numerics; +using Hanekawa.Application.Extensions; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Settings.Images; +using Hanekawa.Entities.Users; +using Hanekawa.Extensions; +using Humanizer; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using SixLabors.Fonts; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Drawing; +using SixLabors.ImageSharp.Drawing.Processing; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using Path = SixLabors.ImageSharp.Drawing.Path; + +namespace Hanekawa.Application.Services.Images; + +public class ProfileImageService +{ + private readonly IDbContext _dbContext; + private readonly IConfigService _config; + private readonly FontCollection _fontCollection; + private readonly ImageSettings _settings; + private readonly CommonImageService _common; + private readonly ILogger _logger; + + public ProfileImageService(ImageSettings settings, IHttpClientFactory httpClientFactory, + IDbContext dbContext, FontCollection fontCollection, ILogger logger, IConfigService config) + { + _common = new CommonImageService(httpClientFactory); + _dbContext = dbContext; + _fontCollection = fontCollection; + _logger = logger; + _config = config; + _settings = settings; + } + + private static Image ProfileTemplate => Image.Load(ProfileTemplatePath); + private static string ProfileTemplatePath => $"{Directory.GetCurrentDirectory()}/Data/Template/ProfileTemplate.png"; + + public async ValueTask DrawAsync(DiscordMember member, GuildUser userData, CancellationToken cancellationToken = default) + { + var toReturn = new MemoryStream(); + using var img = new Image(_settings.Profile.Width, _settings.Profile.Height); + var avatar = await _common.CreateAvatarAsync(member.AvatarUrl, _settings.Profile.Avatar.Size, cancellationToken); + img.Mutate(async void (x) => + { + try + { + x.DrawImage(ProfileTemplate, new Point(0, 0), new GraphicsOptions()); // image + x.DrawImage(avatar, + new Point(_settings.Profile.Avatar.X, _settings.Profile.Avatar.Y), + new GraphicsOptions { Antialias = true }); + + await ApplyText(x, _settings.Profile.Texts, member, userData, cancellationToken); + } + catch (Exception e) + { + _logger.LogError(e, "Async void error drawing profile image"); + } + }); + var progressBar = CreateProgressBar(userData, avatar.Height); + img.Mutate(x => + x.DrawLine(new DrawingOptions + { + GraphicsOptions = new GraphicsOptions + { + BlendPercentage = 1 + } + }, Color.Gray, 3, CreateProgressBar(1, avatar.Height))); + if (progressBar.Length > 0) + { + img.Mutate(x => x.DrawLine(Color.Red,3, progressBar)); + } + + await img.SaveAsync(toReturn, WebpFormat.Instance, cancellationToken: cancellationToken); + return toReturn; + } + + private async ValueTask ApplyText(IImageProcessingContext x, TextSettings[] texts, DiscordMember member, + GuildUser userData, + CancellationToken cancellationToken) + { + for (var i = 0; i < texts.Length; i++) + { + var item = texts[i]; + var points = item.Position.Select(e => new PointF(e.X, e.Y)).ToArray(); + try + { + if (!item.Headline) + { + var textValue = await HandleCustomTextAsync(member, userData, item, cancellationToken); + DrawTextValue(x, textValue, item, points); + } + + var value = "undefined"; + switch (item.SourceType) + { + case nameof(GuildUser): + value = userData.GetType().GetProperty(item.SourceField)?.GetValue(userData)?.ToString() + ?? "undefined"; + break; + case nameof(DiscordMember): + value = member.GetType().GetProperty(item.SourceField)?.GetValue(member)?.ToString() + ?? "undefined"; + break; + case "Custom": + value = await HandleCustomSourceTextAsync(member, userData, item, cancellationToken); + break; + } + + DrawTextValue(x, value, item, points, HorizontalAlignment.Right); + } + catch (Exception e) + { + _logger.LogError(e, "Error drawing text {TextName} on profile image", item.Text); + } + } + } + + private async ValueTask HandleCustomTextAsync(DiscordMember member, GuildUser userData, TextSettings item, + CancellationToken cancellationToken = default) + { + var value = ""; + switch (item.TextType) + { + case "Regular": + value = item.Text; + break; + case "Custom": + switch (item.Text) + { + case "Currency": + var config = await _config.GetAsync(userData.GuildId, + typeof(CurrencyConfig), cancellationToken); + if (config is { CurrencyConfig: null }) + { + config.CurrencyConfig = new CurrencyConfig(); + } + value = config.CurrencyConfig.CurrencyName; + break; + } + break; + } + return value; + } + + private async ValueTask HandleCustomSourceTextAsync(DiscordMember member, GuildUser userData, TextSettings item, + CancellationToken cancellationToken = default) + { + var value = ""; + switch (item.SourceField) + { + case "ServerRank": + var rank = await _dbContext.Users.CountAsync(e => e.GuildId == member.GuildId + && e.Experience >= userData.Experience, + cancellationToken); + var count = await _dbContext.Users.CountAsync(e => e.GuildId == member.GuildId, + cancellationToken); + value = $"{rank.Humanize()}/{count.Humanize()}"; + break; + } + return value; + } + + private static PointF[] CreateProgressBar(float percentage, int size) + { + var numb = percentage * 100 / 100 * 360 * 2; + var points = new PointF[Convert.ToInt32(numb)]; + //const double radius = 55; + var radius = (int) Math.Ceiling((size * Math.PI) / (2 * Math.PI)); + for (var i = 0; i < numb; i++) + { + var radians = i * Math.PI / 360; + + var x = 200 + radius * Math.Cos(radians - Math.PI / 2); + var y = 58 + radius * Math.Sin(radians - Math.PI / 2); + points[i] = (new PointF((float) x, (float) y)); + } + return points; + } + + private static PointF[] CreateProgressBar(GuildUser userData, int avatarSize) + { + var exp = userData.CurrentLevelExperience; + if (exp == 0) exp = 1; + var percentage = (exp) / (float) userData.NextLevelExperience; + + return CreateProgressBar(percentage, avatarSize); + } + + private void DrawTextValue(IImageProcessingContext context, string text, TextSettings item, PointF[] points, HorizontalAlignment alignment = HorizontalAlignment.Left) + { + var position = Vector2.Zero; + if (item.Headline) + { + alignment = HorizontalAlignment.Center; + } + + switch (alignment) + { + case HorizontalAlignment.Left: + position.X = 0; + break; + case HorizontalAlignment.Right: + position.X = points[1].X; + break; + case HorizontalAlignment.Center: + position.X = points[1].X / 2F; + break; + } + + var font = new Font(_fontCollection.Get(_settings.Profile.Font), item.Size); + var options = new RichTextOptions(font) + { + Path = new Path(new LinearLineSegment(points)), + HorizontalAlignment = alignment, + Origin = position + }; + context.DrawText(options, text, Color.White); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/Images/RankImageService.cs b/Hanekawa.Application/Services/Images/RankImageService.cs new file mode 100644 index 00000000..b886ba48 --- /dev/null +++ b/Hanekawa.Application/Services/Images/RankImageService.cs @@ -0,0 +1,85 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Settings.Images; +using Hanekawa.Entities.Users; +using Microsoft.Extensions.Logging; +using SixLabors.Fonts; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Drawing.Processing; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + +namespace Hanekawa.Application.Services.Images; + +internal class RankImageService +{ + private readonly CommonImageService _common; + private readonly ImageSettings currentValue; + private readonly IHttpClientFactory httpClientFactory; + private readonly IDbContext dbContext; + private readonly FontCollection fontCollection; + private readonly ILogger logger; + private readonly IConfigService configService; + + public RankImageService(ImageSettings currentValue, IHttpClientFactory httpClientFactory, IDbContext dbContext, + FontCollection fontCollection, ILogger logger, IConfigService configService) + { + _common = new CommonImageService(httpClientFactory); + this.currentValue = currentValue; + this.httpClientFactory = httpClientFactory; + this.dbContext = dbContext; + this.fontCollection = fontCollection; + this.logger = logger; + this.configService = configService; + } + + internal async Task DrawAsync(DiscordMember member, GuildUser userData, CancellationToken cancellationToken) + { + var image = new Image(currentValue.Rank.Width, currentValue.Rank.Height); + image.Mutate(x => x.Fill(Color.White)); + + var avatar = await _common.CreateAvatarAsync(member.AvatarUrl, currentValue.Rank.Avatar.Size, cancellationToken); + image.Mutate(x => x.DrawImage(avatar, new Point(currentValue.Rank.Avatar.X, currentValue.Rank.Avatar.Y), 1f)); + + var font = this.fontCollection.Get(currentValue.Rank.Font); + + for (int i = 0; i < currentValue.Rank.Texts.Length; i++) + { + TextSettings? text = currentValue.Rank.Texts[i]; + var textValue = text.TextType switch + { + "Regular" => text.Text, + "Custom" => text.SourceType switch + { + "GuildUser" => text.SourceField switch + { + "Username" => member.Username, + "Level" => userData.Level.ToString(), + "Experience" => userData.Experience.ToString(), + _ => string.Empty + }, + "ServerRank" => string.Empty, + _ => string.Empty + }, + _ => string.Empty + }; + + var textFont = text.Headline + ? new Font(font, text.Size, FontStyle.Bold) + : new Font(font, text.Size); + + image.Mutate(x => x.DrawText( + textValue, + textFont, + Color.Black, + new Point(text.TextPosition.X, text.TextPosition.Y) + )); + } + + var stream = new MemoryStream(); + await image.SaveAsync(stream, new WebpEncoder(), cancellationToken); + stream.Position = 0; + return stream; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/Images/WelcomeImageService.cs b/Hanekawa.Application/Services/Images/WelcomeImageService.cs new file mode 100644 index 00000000..27e0d882 --- /dev/null +++ b/Hanekawa.Application/Services/Images/WelcomeImageService.cs @@ -0,0 +1,43 @@ +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Microsoft.Extensions.Logging; +using SixLabors.Fonts; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Drawing.Processing; +using SixLabors.ImageSharp.Formats.Png; +using SixLabors.ImageSharp.Processing; + +namespace Hanekawa.Application.Services.Images; + +public class WelcomeImageService +{ + private readonly CommonImageService _common; + private readonly FontCollection _fontCollection; + private ILogger _logger; + + public WelcomeImageService(IHttpClientFactory httpClientFactory, FontCollection fontCollection, ILogger logger) + { + _common = new CommonImageService(httpClientFactory); + _fontCollection = fontCollection; + _logger = logger; + } + + public async ValueTask DrawAsync(DiscordMember member, GreetConfig cfg, CancellationToken cancellationToken = default) + { + var toReturn = new MemoryStream(); + var dbImage = cfg.Images[Random.Shared.Next(cfg.Images.Count - 1)]; + var image = await _common.GetImageFromUrlAsync(new Uri(dbImage.ImageUrl), cancellationToken); + + var avatar = + await _common.CreateAvatarAsync(member.AvatarUrl, dbImage.AvatarSize, cancellationToken); + image.Mutate(x => + { + x.DrawImage(avatar, new Point(dbImage.AvatarX, dbImage.AvatarY), 1f); + x.DrawText(member.Username, new Font(_fontCollection.Get("Arial"), dbImage.UsernameSize), Color.White, + new Point(dbImage.UsernameX, dbImage.UsernameY)); + }); + + await image.SaveAsync(toReturn, PngFormat.Instance, cancellationToken: cancellationToken); + return toReturn; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/InventoryService.cs b/Hanekawa.Application/Services/InventoryService.cs new file mode 100644 index 00000000..a4c9e0a1 --- /dev/null +++ b/Hanekawa.Application/Services/InventoryService.cs @@ -0,0 +1,179 @@ +using Hanekawa.Application.Extensions; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Services; + +public interface IInventoryService +{ + ValueTask GetInventoryAsync(ulong guildId, ulong userId, CancellationToken cancellationToken = default); + ValueTask UpdateInventoryAsync(GuildUser user, List inventory); + ValueTask UpdateInventoryAsync(GuildUser user, Inventory inventory); + ValueTask AddItemAsync(GuildUser user, Guid itemId, int amount); + ValueTask RemoveItemAsync(GuildUser user, Guid itemId, int amount); + ValueTask HasItemAsync(GuildUser user, Guid itemId); + ValueTask GetItemCountAsync(ulong userId, Guid itemId); +} + +public class InventoryService : IInventoryService +{ + private readonly IDbContext _dbContext; + private readonly ICacheContext _cache; + + public InventoryService(IDbContext dbContext, ICacheContext cache) + { + _dbContext = dbContext; + _cache = cache; + } + + public ValueTask GetInventoryAsync(ulong guildId, ulong userId, + CancellationToken cancellationToken = default) + { + return GetOrCreateInventoryAsync(guildId, userId, cancellationToken); + } + + public async ValueTask UpdateInventoryAsync(GuildUser user, List inventory) + { + var existingUser = await _dbContext.Users + .Include(e => e.User) + .ThenInclude(e => e.Inventory) + .FirstOrDefaultAsync(x => x.GuildId == user.GuildId && x.Id == user.Id); + + if (existingUser == null) return; + + // Replace inventory items + existingUser.User.Inventory = inventory; + + await _dbContext.SaveChangesAsync(); + _cache.Remove($"inventory_{user.Id}"); + } + public async ValueTask UpdateInventoryAsync(GuildUser user, Inventory inventory) + { + var existingUser = await _dbContext.Users + .Include(e => e.User) + .ThenInclude(e => e.Inventory) + .FirstOrDefaultAsync(x => x.GuildId == user.GuildId && x.Id == user.Id); + + if (existingUser == null) return; + + // Replace inventory items + var item = existingUser.User.Inventory.FirstOrDefault(e => e.ItemId == inventory.ItemId); + if (item is not null) + { + item.Amount += inventory.Amount; + } + else + { + existingUser.User.Inventory.Add(inventory); + } + + await _dbContext.SaveChangesAsync(); + _cache.Remove($"inventory_{user.Id}"); + } + + public async ValueTask AddItemAsync(GuildUser user, Guid itemId, int amount) + { + if (amount <= 0) + throw new ArgumentException("Amount must be positive", nameof(amount)); + + var existingUser = await _dbContext.Users + .Include(e => e.User) + .ThenInclude(e => e.Inventory) + .FirstOrDefaultAsync(x => x.GuildId == user.GuildId && x.Id == user.Id); + + if (existingUser == null) + return; + + var item = existingUser.User.Inventory.FirstOrDefault(x => x.ItemId == itemId); + if (item != null) + { + item.Amount += amount; + } + else + { + existingUser.User.Inventory.Add(new Inventory + { + ItemId = itemId, + Amount = amount, + UserId = user.Id + }); + } + + await _dbContext.SaveChangesAsync(); + _cache.Remove($"inventory_{user.Id}"); + } + + public async ValueTask RemoveItemAsync(GuildUser user, Guid itemId, int amount) + { + if (amount <= 0) + throw new ArgumentException("Amount must be positive", nameof(amount)); + + var existingUser = await _dbContext.Users + .Include(e => e.User) + .ThenInclude(e => e.Inventory) + .FirstOrDefaultAsync(x => x.GuildId == user.GuildId && x.Id == user.Id); + + if (existingUser == null) + return; + + var item = existingUser.User.Inventory.FirstOrDefault(x => x.ItemId == itemId); + if (item == null) + throw new InvalidOperationException("Item not found in inventory"); + + if (item.Amount < amount) + throw new InvalidOperationException("Not enough items in inventory"); + + item.Amount -= amount; + if (item.Amount == 0) + { + existingUser.User.Inventory.Remove(item); + } + + await _dbContext.SaveChangesAsync(); + _cache.Remove($"inventory_{user.Id}"); + } + + public async ValueTask HasItemAsync(GuildUser user, Guid itemId) + { + var existingUser = await _dbContext.Users + .Include(e => e.User) + .ThenInclude(e => e.Inventory) + .FirstOrDefaultAsync(x => x.GuildId == user.GuildId && x.Id == user.Id); + + if (existingUser == null) + return false; + + return existingUser.User.Inventory.Any(x => x.ItemId == itemId); + } + + public async ValueTask GetItemCountAsync(ulong userId, Guid itemId) + { + var user = await _dbContext.Users.Include(e => e.User) + .ThenInclude(e => e.Inventory) + .Select(e => new + { + e.Id, + e.User.Inventory.FirstOrDefault(x => x.ItemId == itemId)!.Amount + }) + .FirstOrDefaultAsync(x => x.Id == userId); + return user?.Amount ?? 0; + } + + private async ValueTask GetOrCreateInventoryAsync(ulong guildId, ulong userId, CancellationToken cancellationToken = default) + { + return await _cache.GetOrCreateAsync($"inventory_{userId}", async () => + { + var userEntity = await _dbContext.Users.Include(e => e.User) + .ThenInclude(e => e.Inventory) + .ThenInclude(e => e.Item) + .ThenInclude(e => e.Type) + .FirstOrDefaultAsync(x => x.GuildId == guildId && x.Id == userId, cancellationToken: cancellationToken); + if (userEntity is null) + { + userEntity = await _dbContext.GetOrCreateUserAsync(guildId, userId, cancellationToken: cancellationToken); + } + return userEntity; + }); + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/ItemService.cs b/Hanekawa.Application/Services/ItemService.cs new file mode 100644 index 00000000..6578964c --- /dev/null +++ b/Hanekawa.Application/Services/ItemService.cs @@ -0,0 +1,98 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Application.Services; + +public class ItemService : IItemService +{ + private readonly IDbContext _dbContext; + private readonly ICacheContext _cache; + + public ItemService(IDbContext dbContext, ICacheContext cache) + { + _dbContext = dbContext; + _cache = cache; + } + + public async ValueTask GetItemByIdAsync(Guid itemId) + { + return await _cache.GetOrCreateAsync($"item_{itemId}", async () => + { + return await _dbContext.Items + .Include(e => e.Type) + .FirstOrDefaultAsync(x => x.Id == itemId); + }); + } + + public async ValueTask GetItemByNameAsync(string itemName) + { + // Don't cache this query as it's by name + return await _dbContext.Items + .Include(e => e.Type) + .FirstOrDefaultAsync(x => x.Name.Equals(itemName, StringComparison.OrdinalIgnoreCase)); + } + + public async ValueTask> GetAllItemsAsync() + { + return await _cache.GetOrCreateAsync("all_items", async () => + { + return await _dbContext.Items + .Include(e => e.Type) + .ToListAsync(); + }); + } + + public async ValueTask> GetAllItemTypesAsync() + { + return await _cache.GetOrCreateAsync("all_item_types", async () => + { + return await _dbContext.ItemTypes.ToListAsync(); + }); + } + + public async ValueTask UseItemAsync(ulong guildId, ulong userId, Guid itemId) + { + var item = await GetItemByIdAsync(itemId); + if (item == null) + throw new InvalidOperationException("Item not found"); + + // Implement item-specific effects here based on item type or properties + switch (item.Type.Name.ToLowerInvariant()) + { + case "consumable": + // Implement consumable effect + break; + case "collectible": + // Collectibles might not have an effect when used + break; + case "utility": + // Implement utility effect + break; + default: + throw new NotSupportedException($"Item type '{item.Type.Name}' has no use implementation"); + } + } + + public async ValueTask CreateItemAsync(string name, string description, Guid typeId, int? price = null) + { + var itemType = await _dbContext.ItemTypes.FindAsync(typeId); + if (itemType == null) + throw new ArgumentException("Item type not found", nameof(typeId)); + + var item = new Item + { + Id = Guid.NewGuid(), + Name = name, + Description = description, + TypeId = typeId, + Price = price + }; + + await _dbContext.Items.AddAsync(item); + await _dbContext.SaveChangesAsync(); + _cache.Remove("all_items"); + + return item; + } +} \ No newline at end of file diff --git a/Hanekawa.Application/Services/LevelService.cs b/Hanekawa.Application/Services/LevelService.cs new file mode 100644 index 00000000..454d193a --- /dev/null +++ b/Hanekawa.Application/Services/LevelService.cs @@ -0,0 +1,90 @@ +using System.Runtime.InteropServices; +using Hanekawa.Application.Contracts; +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Services; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Levels; +using Hanekawa.Entities.Users; +using Hanekawa.Extensions; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Application.Services; + +/// +public class LevelService : ILevelService +{ + private readonly IDbContext _db; + private readonly IBot _bot; + private readonly ILogger _logger; + private readonly IMediator _mediator; + + public LevelService(IDbContext db, ILogger logger, + IBot bot, IMediator mediator) + { + _db = db; + _logger = logger; + _bot = bot; + _mediator = mediator; + } + + /// + public async Task AddExperienceAsync(DiscordMember member, int experience) + { + var config = await _db.GuildConfigs.Include(x => x.LevelConfig) + .ThenInclude(x => x.Rewards) + .FirstOrDefaultAsync(x => x.GuildId == member.Guild.GuildId); + if (config?.LevelConfig is null || !config.LevelConfig.LevelEnabled) return null; + _logger.LogInformation("Adding {Experience} experience to guild user {User} in guild {Guild}", + experience, member.Id, member.Guild.GuildId); + + var user = await _db.Users.FirstOrDefaultAsync(x => x.GuildId == member.Guild.GuildId && x.Id == member.Id) + ?? new GuildUser { GuildId = member.Guild.GuildId, Id = member.Id }; + var nextLevel = await _db.LevelRequirements.FirstOrDefaultAsync(x => x.Level == user.Level + 1); + if(nextLevel is not null && user.Experience + experience >= nextLevel.Experience) + { + user.Level++; + await AdjustRolesAsync(member, user.Level, config); + _logger.LogInformation("User {User} in guild {Guild} has leveled up to level {Level}", + member.Id, member.Guild.GuildId, user.Level); + await _mediator.Send(new LevelUp(member, member.RoleIds, user.Level, config)); + } + + user.Experience += experience; + await _db.SaveChangesAsync(); + + return experience; + } + /// + public async Task AdjustRolesAsync(DiscordMember member, int level, GuildConfig config) + { + for (var i = 0; i < config.LevelConfig?.Rewards.Count; i++) + { + AdjustRoles(member, level, config.LevelConfig.Rewards[i]); + } + + await _bot.ModifyRolesAsync(member, member.RoleIds); + return member; + } + private static void AdjustRoles(DiscordMember member, int level, LevelReward x) + { + if (!x.RoleId.HasValue) + { + return; + } + if (x.Level <= level && !member.RoleIds.Contains(x.RoleId.Value)) + { + member.RoleIds.Add(x.RoleId.Value); + } + else if (x.Level > level && member.RoleIds.Contains(x.RoleId.Value)) + { + member.RoleIds.Remove(x.RoleId.Value); + var tempList = new List(member.RoleIds); + tempList.Remove(x.RoleId.Value); + var span = CollectionsMarshal.AsSpan(tempList); + member.RoleIds = span.ToArray(); + } + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Bot/AuditLogHelper.cs b/Hanekawa.Bot/Bot/AuditLogHelper.cs new file mode 100644 index 00000000..0e79e56e --- /dev/null +++ b/Hanekawa.Bot/Bot/AuditLogHelper.cs @@ -0,0 +1,241 @@ +using Disqord; +using Disqord.AuditLogs; +using Disqord.Gateway; +using Disqord.Rest; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Bot.Bot; + +/// +/// A response class that represents a standardized audit log entry +/// +public record AuditLogResponse +{ + /// + /// The ID of the audit log entry + /// + public ulong Id { get; init; } + + /// + /// The user who performed the action + /// + public ulong UserId { get; init; } + + /// + /// The type of action performed + /// + public AuditLogActionType ActionType { get; init; } + + /// + /// The timestamp when the action was performed + /// + public DateTimeOffset Timestamp { get; init; } + + /// + /// The reason provided for the action (if any) + /// + public string? Reason { get; init; } + + /// + /// The target ID of the action (if applicable) + /// + public ulong? TargetId { get; set; } + + /// + /// Additional data specific to the audit log type (serialized as JSON) + /// + public Dictionary AdditionalData { get; init; } = new(); +} + +/// +/// Helper class for retrieving and processing Discord audit logs +/// +public static class AuditLogHelper +{ + /// + /// Retrieves audit logs of a specific type and maps them to a standardized response format + /// + /// The guild to retrieve audit logs from + /// The specific audit log action type to retrieve + /// Maximum number of audit logs to retrieve (optional) + /// A list of standardized audit log responses + public static async Task GetAuditLogsAsync(CachedGuild guild, AuditLogActionType actionType, int limit = 100) + { + var auditLogs = await FetchAuditLogsAsync(guild, actionType, limit); + return MapAuditLogs(auditLogs); + } + + /// + /// Retrieves all audit logs and maps them to a standardized response format + /// + /// The guild to retrieve audit logs from + /// Maximum number of audit logs to retrieve (optional) + /// A list of standardized audit log responses + public static async Task GetAllAuditLogsAsync(CachedGuild guild, int limit = 100) + { + var auditLogs = await guild.FetchAuditLogsAsync(limit: limit); + return MapAuditLogs(auditLogs); + } + + /// + /// Maps a collection of audit logs to the standardized response format + /// + private static AuditLogResponse[] MapAuditLogs(IReadOnlyList auditLogs) + { + var responses = new AuditLogResponse[auditLogs.Count]; + + for (var i = 0; i < auditLogs.Count; i++) + { + var log = auditLogs[i]; + var response = new AuditLogResponse + { + Id = log.Id.RawValue, + UserId = log.ActorId.Value.RawValue, + Timestamp = log.CreatedAt(), + Reason = log.Reason + }; + + // Handle specific audit log types and extract additional data + ExtractAdditionalData(log, response); + + responses[i] = response; + } + + return responses; + } + + /// + /// Extracts additional data from specific audit log types + /// + private static void ExtractAdditionalData(IAuditLog log, AuditLogResponse response) + { + switch (log) + { + case IGuildUpdatedAuditLog guildUpdated: + response.TargetId = guildUpdated.TargetId; + break; + + case IChannelCreatedAuditLog channelCreated: + response.TargetId = channelCreated.TargetId; + break; + + case IChannelUpdatedAuditLog channelUpdated: + response.TargetId = channelUpdated.TargetId; + break; + + case IChannelDeletedAuditLog channelDeleted: + response.TargetId = channelDeleted.TargetId; + break; + + case IMemberBannedAuditLog memberBanned: + response.TargetId = memberBanned.TargetId; + break; + + case IMemberUnbannedAuditLog memberUnbanned: + response.TargetId = memberUnbanned.TargetId; + break; + + case IMemberKickedAuditLog memberKicked: + response.TargetId = memberKicked.TargetId; + break; + + case IMemberUpdatedAuditLog memberUpdated: + response.TargetId = memberUpdated.TargetId; + break; + + case IRoleCreatedAuditLog roleCreated: + response.TargetId = roleCreated.TargetId; + break; + + case IRoleUpdatedAuditLog roleUpdated: + response.TargetId = roleUpdated.TargetId; + break; + + case IRoleDeletedAuditLog roleDeleted: + response.TargetId = roleDeleted.TargetId; + break; + + case IMessagesDeletedAuditLog messageDeleted: + response.TargetId = messageDeleted.TargetId; + response.AdditionalData["ChannelId"] = messageDeleted.ChannelId; + break; + + case IMessagesBulkDeletedAuditLog messagesDeleted: + response.TargetId = messagesDeleted.TargetId; + response.AdditionalData["ChannelId"] = messagesDeleted.ChannelId; + response.AdditionalData["MessageCount"] = messagesDeleted.Count; + break; + + // For any audit log type without a specific handler, + // try to extract a target ID if the interface implements ITargetedAuditLog + default: + response.TargetId = log.TargetId; + break; + } + } + + /// + /// Fetches the appropriate type of audit logs based on the action type + /// + private static async Task> FetchAuditLogsAsync(CachedGuild guild, AuditLogActionType actionType, int limit) + { + return actionType switch + { + AuditLogActionType.GuildUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ChannelCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ChannelUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ChannelDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.OverwriteCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.OverwriteUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.OverwriteDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MemberKicked => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MembersPruned => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MemberBanned => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MemberUnbanned => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MemberUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MemberRolesUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MembersMoved => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MembersDisconnected => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.BotAdded => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.RoleCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.RoleUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.RoleDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.InviteCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.InviteUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.InviteDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.WebhookCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.WebhookUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.WebhookDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.EmojiCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.EmojiUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.EmojiDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MessagesDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MessagesBulkDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MessagePinned => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.MessageUnpinned => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.IntegrationCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.IntegrationUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.IntegrationDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.StageCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.StageUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.StageDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.StickerCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.StickerUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.StickerDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.GuildEventCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.GuildEventUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.GuildEventDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ThreadCreate => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ThreadUpdate => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ThreadDelete => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.ApplicationCommandPermissionsUpdate => await guild + .FetchAuditLogsAsync(limit: limit), + AuditLogActionType.AutoModerationRuleCreated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.AutoModerationRuleUpdated => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.AutoModerationRuleDeleted => await guild.FetchAuditLogsAsync(limit: limit), + AuditLogActionType.AutoModerationMessageBlocked => + await guild.FetchAuditLogsAsync(limit: limit), + _ => throw new ArgumentOutOfRangeException(nameof(actionType), actionType, null) + }; + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Bot/Bot.cs b/Hanekawa.Bot/Bot/Bot.cs new file mode 100644 index 00000000..073d3818 --- /dev/null +++ b/Hanekawa.Bot/Bot/Bot.cs @@ -0,0 +1,177 @@ +using System.Diagnostics; +using System.Diagnostics.Metrics; +using Disqord; +using Disqord.AuditLogs; +using Disqord.Bot; +using Disqord.Bot.Commands; +using Disqord.Gateway; +using Disqord.Rest; +using Disqord.Rest.Pagination; +using Hanekawa.Application.Handlers.Services.Metrics; +using Hanekawa.Application.Interfaces; +using Hanekawa.Bot.Mapper; +using Hanekawa.Entities; +using Hanekawa.Entities.Discord; +using MediatR; +using Microsoft.Extensions.Options; +using Prometheus.Client; +using IResult = Qmmands.IResult; + +namespace Hanekawa.Bot.Bot; + +/// +public sealed class Bot : DiscordBot, IBot +{ + private readonly Counter _commandsExecutedTotal; + + public Bot(IOptions options, ILogger logger, + IServiceProvider services, DiscordClient client) + : base(options, logger, services, client) + { + var meter = services.GetRequiredService().Create(MeterName.DiscordCommands); + _commandsExecutedTotal = meter.CreateCounter(MeterName.DiscordCommands + ".Total"); + } + + protected override ValueTask OnAfterExecuted(IDiscordCommandContext context, IResult result) + { + _commandsExecutedTotal.Add(1); + return base.OnAfterExecuted(context, result); + } + + protected override async ValueTask OnBeforeExecuted(IDiscordCommandContext context) + { + var start = Stopwatch.GetTimestamp(); + var result = await base.OnBeforeExecuted(context); + var elapsedTime = Stopwatch.GetElapsedTime(start).Milliseconds; + Logger.LogInformation("Command {Command} executed in {Elapsed}ms", + context.Command?.Name, elapsedTime); + return result; + } + + /// + public Task BanAsync(ulong guildId, ulong userId, int days, string reason) + => this.CreateBanAsync(guildId, userId, reason, days, new DefaultRestRequestOptions { Reason = reason }); + + /// + public Task UnbanAsync(ulong guildId, ulong userId, string reason) + => this.DeleteBanAsync(guildId, userId, new DefaultRestRequestOptions { Reason = reason }); + + /// + public Task KickAsync(ulong guildId, ulong userId, string reason) + => this.KickMemberAsync(guildId, userId, new DefaultRestRequestOptions { Reason = reason}); + + /// + public Task MuteAsync(ulong guildId, ulong userId, string reason, TimeSpan duration) + => this.ModifyMemberAsync(guildId, userId, x => + { + x.TimedOutUntil = DateTimeOffset.UtcNow.Add(duration); + }, new DefaultRestRequestOptions{ Reason = reason } ); + + /// + public Task UnmuteAsync(ulong guildId, ulong userId, string reason) + => this.ModifyMemberAsync(guildId, userId, x => + { + x.TimedOutUntil = null; + }, new DefaultRestRequestOptions{ Reason = reason } ); + + /// + public Task AddRoleAsync(ulong guildId, ulong userId, ulong roleId) + => this.GrantRoleAsync(guildId, userId, roleId); + + /// + public Task RemoveRoleAsync(ulong guildId, ulong userId, ulong roleId) + => this.RevokeRoleAsync(guildId, userId, roleId); + + /// + public Task ModifyRolesAsync(DiscordMember member, ulong[] modifiedRoles) + => this.ModifyMemberAsync(member.Guild.GuildId, member.Id, x => + { + x.RoleIds = ConvertToSnowflake(modifiedRoles); + }); + + /// + public ulong? GetChannel(ulong guildId, ulong channelId) + => this.GetGuild(guildId)!.GetChannel(channelId)!.Id; + + /// + public Task PruneMessagesAsync(ulong guildId, ulong channelId, ulong[] messageIds) + => (this.GetGuild(guildId)!.GetChannel(channelId) as ITextChannel) + !.DeleteMessagesAsync(ConvertToSnowflake(messageIds)); + + /// + public Task DeleteMessageAsync(ulong guildId, ulong channelId, ulong messageId) + => (this.GetGuild(guildId)?.GetChannel(channelId) as ITextChannel) + !.DeleteMessageAsync(messageId); + + /// + public async Task SendMessageAsync(ulong channelId, string message, Attachment? attachment = null) + { + var localMsg = new LocalMessage() + .WithContent(message) + .WithAllowedMentions(LocalAllowedMentions.None); + if (attachment is not null) localMsg.WithAttachments(new LocalAttachment(attachment.Stream, attachment.FileName)); + var result = await this.SendMessageAsync(channelId, localMsg).ConfigureAwait(false); + return new RestMessage + { + Id = result.Id, + ChannelId = result.ChannelId, + Content = result.Content, + AuthorId = result.Author.Id, + Attachment = result is {Attachments.Count: >0} ? result.Attachments[0].Url : string.Empty, + Embed = result is {Embeds.Count: >0} ? result.Embeds[0].ToEmbed() : null + }; + } + + /// + public async Task SendMessageAsync(ulong channelId, Embed embedMessage, Attachment? attachment = null) + { + var localMsg = new LocalMessage() + .WithEmbeds(embedMessage.ToLocalEmbed()) + .WithAllowedMentions(LocalAllowedMentions.None); + if (attachment?.Stream is not null) localMsg.WithAttachments(new LocalAttachment(attachment.Stream, attachment.FileName)); + await this.SendMessageAsync(channelId, localMsg).ConfigureAwait(false); + } + + public async Task GetAuditLogAsync(ulong guildId, AuditLogActionType actionType) + { + var guild = this.GetGuild(guildId); + if (guild is null) + { + return; + } + + var auditLogs = await AuditLogHelper.GetAuditLogsAsync(guild, actionType); + foreach (var log in auditLogs) + { + Logger.LogInformation("Audit Log: {Action} by {User} at {Timestamp}", + log.ActionType, log.UserId, log.Timestamp); + } + } + + public async Task GetAuditLogAsync(ulong guildId) + { + var guild = this.GetGuild(guildId); + if (guild is null) + { + return; + } + + var auditLogs = await AuditLogHelper.GetAllAuditLogsAsync(guild); + foreach (var log in auditLogs) + { + Logger.LogInformation("Audit Log: {Action} by {User} at {Timestamp}", + log.ActionType, log.UserId, log.Timestamp); + } + } + + private static Snowflake[] ConvertToSnowflake(ulong[] modifiedRoles) + { + var result = new Snowflake[modifiedRoles.Length]; + var span = modifiedRoles.AsSpan(); + for (var i = 0; i < span.Length; i++) + { + result[i] = span[i]; + } + return result; + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Bot/LocalizationService.cs b/Hanekawa.Bot/Bot/LocalizationService.cs new file mode 100644 index 00000000..e4778a6b --- /dev/null +++ b/Hanekawa.Bot/Bot/LocalizationService.cs @@ -0,0 +1,21 @@ +using System.Globalization; +using Disqord.Bot.Commands.Application.Default; +using Disqord.Serialization.Json; +using Microsoft.Extensions.Options; + +namespace Hanekawa.Bot.Bot; + +public class LocalizationService : DefaultApplicationCommandLocalizer +{ + public LocalizationService(IOptions options, + ILogger logger, IJsonSerializer serializer) + : base(options, logger, serializer) + { } + + protected override StoreInformation CreateStoreInformation(CultureInfo locale, string localeFilePath, + bool localeExists, MemoryStream memoryStream, LocalizationStoreJsonModel model) + { + + return base.CreateStoreInformation(locale, localeFilePath, localeExists, memoryStream, model); + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Metas/Commands.cs b/Hanekawa.Bot/Commands/Metas/Commands.cs new file mode 100644 index 00000000..5c40b0e3 --- /dev/null +++ b/Hanekawa.Bot/Commands/Metas/Commands.cs @@ -0,0 +1,67 @@ +namespace Hanekawa.Bot.Commands.Metas; + +public static class SlashGroupName +{ + public const string Greet = "Greet"; + public const string Administration = "Administration"; + public const string Club = "Club"; + public const string Level = "Level"; + public const string Boost = "Boost"; +} + +public static class Account +{ + public const string Rank = "rank"; + public const string Wallet = "wallet"; + public const string Profile = "profile"; + public const string Top = "top"; +} + +public static class Admin +{ + public const string Ban = "ban"; + public const string Unban = "unban"; + public const string Kick = "kick"; + public const string Mute = "mute"; + public const string Unmute = "unmute"; + public const string Warn = "warn"; + public const string VoidWarn = "voidwarn"; + public const string ClearWarns = "clearwarns"; + public const string WarnLog = "warnlog"; + public const string Prune = "prune"; +} + +public static class Club +{ + public const string Create = "create"; + public const string Delete = "delete"; + public const string List = "list"; + public const string Join = "join"; + public const string Leave = "leave"; + public const string Info = "info"; +} + +public static class Greet +{ + public const string Channel = "channel"; + public const string Message = "message"; + public const string ImageUrl = "imageurl"; + public const string ImageList = "imagelist"; + public const string ImageRemove = "imageremove"; + public const string ImageToggle = "image"; +} + +public static class LevelName +{ + public const string Add = "add"; + public const string Remove = "remove"; + public const string List = "list"; + public const string Modify = "modify"; +} + +public static class Boost +{ + public const string Config = "config"; + public const string Add = "add"; + public const string Remove = "remove"; +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Slash/Account/AccountCommands.cs b/Hanekawa.Bot/Commands/Slash/Account/AccountCommands.cs new file mode 100644 index 00000000..97cec912 --- /dev/null +++ b/Hanekawa.Bot/Commands/Slash/Account/AccountCommands.cs @@ -0,0 +1,92 @@ +using Disqord; +using Disqord.Bot.Commands.Application; +using Disqord.Bot.Commands.Interaction; +using Disqord.Gateway; +using Hanekawa.Application.Handlers.Commands.Account; +using Hanekawa.Bot.Mapper; +using Qmmands; + +namespace Hanekawa.Bot.Commands.Slash.Account; + +[Name("Account")] +public class AccountCommands(IServiceProvider provider) : DiscordApplicationModuleBase +{ + [SlashCommand(Metas.Account.Rank)] + [Description("Shows the rank of a user")] + public async Task RankAsync(IMember user) + { + var service = provider.GetRequiredService(); + var result = await service.RankAsync(user.ToDiscordMember()); + + var response = new LocalInteractionMessageResponse().WithAttachments(new LocalAttachment(result, "rank.png")); + return Response(response); + } + + [SlashCommand(Metas.Account.Wallet)] + [Description("Shows the wallet of a user")] + public async Task WalletAsync() + { + var service = provider.GetRequiredService(); + var result = await service.GetWalletAsync((Context.Author as IMember).ToDiscordMember()); + + var embed = new LocalEmbed() + .WithTitle("Wallet") + .WithDescription($"You have **{result}** coins") + .WithColor(Color.Gold); + + return Response(new LocalInteractionMessageResponse() + .WithEmbeds(embed) + .WithAllowedMentions(LocalAllowedMentions.None)); + } + + [SlashCommand(Metas.Account.Profile)] + [Description("Shows the profile of a user")] + public async Task ProfileAsync() + { + var service = provider.GetRequiredService(); + var result = await service.ProfileAsync( + Bot.GetMember(Context.GuildId!.Value, Context.Author.Id) + .ToDiscordMember()); + result.Position = 0; + return Response(new LocalInteractionMessageResponse() + .WithContent($"Profile for {Context.Author.Name}") + .WithAllowedMentions(LocalAllowedMentions.None) + .WithAttachments(new LocalAttachment(result, "profile.png"))); + } + + [SlashCommand(Metas.Account.Top)] + [Description("Shows the top users")] + public async Task TopAsync() + { + var service = provider.GetRequiredService(); + + // Get top users from the service + var topUsers = await service.GetTopUsersAsync(Context.GuildId!.Value); + + var embed = new LocalEmbed() + .WithTitle("Top 10 Users") + .WithDescription("Ranked by experience") + .WithColor(Color.Purple); // Default to purple as requested + + var rank = 1; + for (var i = 0; i < topUsers.Length; i++) + { + var user = topUsers[i]; + var member = Bot.GetMember(Context.GuildId!.Value, user.Id); + var displayName = member != null + ? member.Name + : $"User {user.Id}"; + + embed.AddField($"#{rank} {displayName}", + $"Level: {user.Level}\n" + + $"Experience: {user.Experience}\n" + + $"Currency: {user.Currency}"); + + rank++; + } + + return Response(new LocalInteractionMessageResponse() + .WithEmbeds(embed) + .WithAllowedMentions(LocalAllowedMentions.None)); + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Slash/Administration/AdministrationCommands.cs b/Hanekawa.Bot/Commands/Slash/Administration/AdministrationCommands.cs new file mode 100644 index 00000000..d6cf85c2 --- /dev/null +++ b/Hanekawa.Bot/Commands/Slash/Administration/AdministrationCommands.cs @@ -0,0 +1,161 @@ +using Disqord; +using Disqord.Bot.Commands; +using Disqord.Bot.Commands.Application; +using Disqord.Bot.Commands.Interaction; +using Disqord.Gateway; +using Disqord.Rest; +using Hanekawa.Application.Handlers.Commands.Administration; +using Hanekawa.Application.Handlers.Services.Warnings; +using Hanekawa.Application.Interfaces; +using Hanekawa.Bot.Commands.Metas; +using Hanekawa.Bot.Mapper; +using MediatR; +using Qmmands; + +namespace Hanekawa.Bot.Commands.Slash.Administration; + +[Name("Administration")] +[Description("Administration commands")] +public class AdministrationCommands(IMetrics metrics) : DiscordApplicationGuildModuleBase +{ + [SlashCommand(Admin.Ban)] + [RequireBotPermissions(Permissions.BanMembers)] + [RequireAuthorPermissions(Permissions.BanMembers)] + [Description("Bans a user from the server")] + public async Task BanAsync(AutoComplete member, string reason) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var result = await Bot.Services.GetRequiredService() + .BanUserAsync(user.ToDiscordMember(), Context.AuthorId, reason); + return Response(result.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.Unban)] + [RequireBotPermissions(Permissions.BanMembers)] + [RequireAuthorPermissions(Permissions.BanMembers)] + [Description("Unbans a user from the server")] + public async Task UnbanAsync(AutoComplete member, string reason) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var result = await Bot.Services.GetRequiredService() + .UnbanUserAsync(user.ToGuild(),user.Id, Context.AuthorId.RawValue, reason); + return Response(result.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.Kick)] + [RequireBotPermissions(Permissions.BanMembers)] + [RequireAuthorPermissions(Permissions.BanMembers)] + [Description("Kick a user from the server")] + public async Task KickAsync(AutoComplete member, string reason) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var result = await Bot.Services.GetRequiredService() + .KickUserAsync(user.ToDiscordMember(), Context.AuthorId, reason); + return Response(result.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.Mute)] + [RequireBotPermissions(Permissions.MuteMembers)] + [RequireAuthorPermissions(Permissions.MuteMembers)] + [Description("Mutes a user in the server")] + public async Task MuteAsync(AutoComplete member, + TimeSpan duration, string reason) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var result = await Bot.Services.GetRequiredService() + .MuteUserAsync(user.ToDiscordMember(), Context.AuthorId, reason, duration); + return Response(result.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.Unmute)] + [RequireBotPermissions(Permissions.MuteMembers)] + [RequireAuthorPermissions(Permissions.MuteMembers)] + [Description("Un-mutes a user in the server")] + public async Task UnmuteAsync(AutoComplete member, string reason) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var result = await Bot.Services.GetRequiredService() + .UnmuteUserAsync(user.ToDiscordMember(), Context.AuthorId, reason); + return Response(result.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.Warn)] + [RequireAuthorPermissions(Permissions.MuteMembers)] + [Description("Warns a user in the server")] + public async Task WarnAsync(AutoComplete member, string reason) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var response = await Bot.Services.GetRequiredService() + .Send(new WarningReceived(user.ToDiscordMember(), reason, Context.AuthorId)); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.VoidWarn)] + [RequireAuthorPermissions(Permissions.BanMembers)] + [Description("Voids a warn from a user in the server")] + public async Task VoidWarnAsync(AutoComplete member) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var response = await Bot.Services.GetRequiredService() + .Send(new WarningClear(user.ToDiscordMember(), Context.AuthorId, "Voided by moderator")); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.WarnLog)] + [RequireAuthorPermissions(Permissions.MuteMembers)] + [Description("List all warnings from a user in the server")] + public async Task WarnsAsync(AutoComplete member) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var response = await Bot.Services.GetRequiredService() + .Send(new WarningList(user.GuildId, user.Id)); + return Pages(response.ToPages()); + } + + [SlashCommand(Admin.ClearWarns)] + [RequireAuthorPermissions(Permissions.BanMembers)] + [Description("Clears all warnings from a user in the server")] + public async Task ClearWarnsAsync(AutoComplete member) + { + using var _ = metrics.All(); + var user = member.Argument.Value; + var response = await Bot.Services.GetRequiredService() + .Send(new WarningClear(user.ToDiscordMember(), Context.AuthorId, + "Cleared by moderator", true)); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Admin.Prune)] + [RequireBotPermissions(Permissions.ManageMessages)] + [RequireAuthorPermissions(Permissions.ManageMessages)] + [Description("Prunes a number of messages from a channel")] + public async Task Prune(int messageCount = 100) + { + using var _ = metrics.All(); + var channel = Bot.GetChannel(Context.GuildId, Context.ChannelId); + if (channel is not ITextChannel textChannel) return Response("This command can only be used in text channels"); + var messagesAsync = await textChannel.FetchMessagesAsync(messageCount); + var messageIds = new ulong[messagesAsync.Count]; + + for (var i = 0; i < messagesAsync.Count; i++) + { + var msg = messagesAsync[i]; + if((msg as IUserMessage)!.CreatedAt() < DateTimeOffset.UtcNow.AddDays(-14)) continue; + messageIds[i] = msg.Id.RawValue; + } + + var result= await Bot.Services.GetRequiredService() + .PruneAsync(Context.GuildId, Context.ChannelId, + messageIds, Context.AuthorId, + ""); + return Response(result.ToLocalInteractionMessageResponse()); + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Slash/Boost/BoostCommands.cs b/Hanekawa.Bot/Commands/Slash/Boost/BoostCommands.cs new file mode 100644 index 00000000..88af29a3 --- /dev/null +++ b/Hanekawa.Bot/Commands/Slash/Boost/BoostCommands.cs @@ -0,0 +1,58 @@ +using Disqord.Bot.Commands.Application; +using Disqord.Bot.Commands.Interaction; +using Hanekawa.Application.Handlers.Commands.Boost; +using Hanekawa.Application.Interfaces; +using Hanekawa.Bot.Commands.Metas; +using Hanekawa.Bot.Mapper; +using Hanekawa.Entities.Discord; +using Hanekawa.Localize; +using Qmmands; + +namespace Hanekawa.Bot.Commands.Slash.Boost; + +[SlashGroup(SlashGroupName.Boost)] +public class BoostCommands(IMetrics metrics) : DiscordApplicationGuildModuleBase +{ + [SlashCommand(Metas.Boost.Config)] + [Description("List all registered boost actions")] + public async Task ListAsync() + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.ListAsync(Context.GuildId); + if (response is null) + { + return Response(Localization.NoFound_BoostActions); + } + + List<(string, string)> values = []; + foreach (var x in response.Value.BoostConfig.GetType().GetProperties()) + { + var value = x.GetValue(response.Value.BoostConfig); + if (value != null) + { + values.Add((x.Name, value.ToString())); + } + } + + var fields = new List(); + for (var i = 0; i < values.Count; i++) + { + var x = values[i]; + fields.Add(new EmbedField(x.Item1, string.IsNullOrWhiteSpace(x.Item2) + ? "NaN" + : x.Item2, + true)); + } + + var embed = new Embed + { + Title = Localization.BoostConfig, + Content = string.Empty, + Fields = fields + }; + + return Response(embed.ToLocalEmbed()); + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Slash/Club/ClubCommands.cs b/Hanekawa.Bot/Commands/Slash/Club/ClubCommands.cs new file mode 100644 index 00000000..fbf372b7 --- /dev/null +++ b/Hanekawa.Bot/Commands/Slash/Club/ClubCommands.cs @@ -0,0 +1,82 @@ +using Disqord; +using Disqord.Bot.Commands; +using Disqord.Bot.Commands.Application; +using Disqord.Bot.Commands.Interaction; +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Bot.Commands.Metas; +using Hanekawa.Bot.Mapper; +using Qmmands; + +namespace Hanekawa.Bot.Commands.Slash.Club; + +[SlashGroup(SlashGroupName.Club)] +public class ClubCommands(IMetrics metrics) : DiscordApplicationGuildModuleBase +{ + [SlashCommand(Metas.Club.Create)] + [Description("Create a club")] + public async Task Create(string name, string description) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.Create(Context.GuildId, name, description, Context.AuthorId); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Metas.Club.Delete)] + [Description("Delete a club")] + [RequireAuthorPermissions(Permissions.ManageGuild)] + public async Task Delete(string name) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.Delete(Context.GuildId, name, Context.AuthorId); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Metas.Club.List)] + [Description("List all clubs")] + public async Task List() + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.List(Context.GuildId); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Metas.Club.Join)] + [Description("Join a club")] + public async Task Join(string name) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.Join(Context.GuildId, name, Context.AuthorId); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Metas.Club.Leave)] + [Description("Leave a club")] + public async Task Leave(string name) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.Leave(Context.GuildId, name, Context.AuthorId); + return Response(response.ToLocalInteractionMessageResponse()); + } + + [SlashCommand(Metas.Club.Info)] + [Description("Get club info")] + public async Task Info(string name) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.Info(Context.GuildId, name); + return Response(response.ToLocalInteractionMessageResponse()); + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Slash/Setting/GreetCommands.cs b/Hanekawa.Bot/Commands/Slash/Setting/GreetCommands.cs new file mode 100644 index 00000000..d218261f --- /dev/null +++ b/Hanekawa.Bot/Commands/Slash/Setting/GreetCommands.cs @@ -0,0 +1,134 @@ +using Disqord; +using Disqord.Bot.Commands; +using Disqord.Bot.Commands.Application; +using Disqord.Bot.Commands.Interaction; +using Disqord.Extensions.Interactivity.Menus.Paged; +using Disqord.Gateway; +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Bot.Commands.Metas; +using Hanekawa.Bot.Mapper; +using Hanekawa.Entities.Configs; +using Hanekawa.Localize; +using Qmmands; +using IResult = Qmmands.IResult; + +namespace Hanekawa.Bot.Commands.Slash.Setting; + +[SlashGroup(SlashGroupName.Greet)] +[RequireAuthorPermissions(Permissions.ManageChannels)] +public class GreetCommands(IMetrics metrics) : DiscordApplicationGuildModuleBase +{ + [SlashCommand(Greet.Channel)] + [Description("Set the greet channel")] + public async Task Set(IChannel channel) + { + using var _ = metrics.MeasureDuration(); + metrics.IncrementCounter(); + if (channel is not TransientInteractionChannel { Type: ChannelType.Text } textChannel) + return Response(Localization.ChannelMustBeTextChannel); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.SetChannel(Context.GuildId, textChannel.ToTextChannel()); + return Response(response); + } + + [SlashCommand(Greet.Message)] + [Description("Set the greet message")] + public async Task Set(string message) + { + using var _ = metrics.MeasureDuration(); + metrics.IncrementCounter(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.SetMessage(Context.GuildId, message); + return Response(response); + } + + [SlashCommand(Greet.ImageUrl)] + [Description("Set the greet image url")] + public async Task SetImage(string url) + { + using var _ = metrics.MeasureDuration(); + metrics.IncrementCounter(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.SetImage(Context.GuildId, url, Context.AuthorId); + return Response(response); + } + + [SlashCommand(Greet.ImageList)] + [Description("List the greet images")] + public async Task ListImages() + { + using var _ = metrics.MeasureDuration(); + metrics.IncrementCounter(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.ListImages(Context.GuildId); + if (response.Value is not List images) return Response(Localization.NoImagesFound); + + var pages = new List(); + for (var i = 0; i < images.Count / 5; i++) + { + var page = new Page(); + for (var j = 0; j < 5; j++) + { + var x = images[j + (5 * i)]; + page.WithContent($"ID: {x.Id}\nURL: {x.ImageUrl}\n"); + } + pages.Add(page); + } + return Pages(pages); + } + + [SlashCommand(Greet.ImageRemove)] + [Description("Remove the greet image")] + public async Task RemoveImage(int id) + { + using var _ = metrics.MeasureDuration(); + metrics.IncrementCounter(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.RemoveImage(Context.GuildId, id); + return Response(response + ? Localization.RemovedImage + : Localization.NoImageWithIdFound); + } + + [SlashCommand(Greet.ImageToggle)] + [Description("Toggle the greet image")] + public async Task ToggleImage() + { + using var _ = metrics.MeasureDuration(); + metrics.IncrementCounter(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.ToggleImage(Context.GuildId); + return Response(response); + } + + [AutoComplete(Greet.Channel)] + public void GreetAutoComplete(AutoComplete channel) + { + if (!channel.IsFocused) return; + var guild = Bot.GetGuild(Context.GuildId); + if (guild is null) throw new ArgumentException("Couldn't get guild in auto-complete"); + + var channels = guild.GetChannels(); + foreach (var x in channels) + if (x.Value is CachedTextChannel textChannel) + channel.Choices.Add($"{textChannel.Name}", textChannel); + } + + [AutoComplete(Greet.ImageRemove)] + public async Task RemoveImage(AutoComplete id) + { + if(!id.IsFocused) return; + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.ListImages(Context.GuildId); + if (response.Value is not List images) return; + foreach (var x in images) id.Choices.Add($"{x.Id} - {x.ImageUrl}", x.Id); + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Commands/Slash/Setting/LevelCommands.cs b/Hanekawa.Bot/Commands/Slash/Setting/LevelCommands.cs new file mode 100644 index 00000000..0a316185 --- /dev/null +++ b/Hanekawa.Bot/Commands/Slash/Setting/LevelCommands.cs @@ -0,0 +1,105 @@ +using System.Runtime.InteropServices; +using Disqord; +using Disqord.Bot.Commands; +using Disqord.Bot.Commands.Application; +using Disqord.Bot.Commands.Interaction; +using Disqord.Extensions.Interactivity.Menus.Paged; +using Disqord.Gateway; +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Interfaces.Commands; +using Hanekawa.Bot.Commands.Metas; +using Hanekawa.Entities.Levels; +using Hanekawa.Localize; +using Qmmands; + +namespace Hanekawa.Bot.Commands.Slash.Setting; + +[SlashGroup(SlashGroupName.Level)] +[RequireAuthorPermissions(Permissions.ManageGuild)] +public class LevelCommands(IMetrics metrics) : DiscordApplicationGuildModuleBase +{ + [SlashCommand(LevelName.Add)] + [Description("Add a level role")] + public async Task Add(int level, IRole role) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + await service.AddAsync(Context.GuildId, role.Id, level, Context.CancellationToken); + return Response(); + } + + [SlashCommand(LevelName.Remove)] + [Description("Remove a level role")] + public async Task Remove(IRole role) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + await service.RemoveAsync(Context.GuildId, role.Id, Context.CancellationToken); + return Response(); + } + + [SlashCommand(LevelName.List)] + [Description("List all level roles")] + public async Task List() + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + var response = await service.ListAsync(Context.GuildId, Context.CancellationToken); + if (response.Count == 0) return Response(Localization.NoRolesFound); + return Pages(BuildPages(response)); + } + + [SlashCommand(LevelName.Modify)] + [Description("Modify a level role")] + public async Task Modify(int level, IRole role) + { + using var _ = metrics.All(); + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + await service.ModifyAsync(Context.GuildId, role.Id, level, Context.CancellationToken); + return Response(); + } + + [AutoComplete(LevelName.Add)] + public Task AutoCompleteAdd(AutoComplete level, AutoComplete role) + { + if (!role.IsFocused) return Task.CompletedTask; + if(Context.CancellationToken.IsCancellationRequested) return Task.CompletedTask; + role.Choices?.AddRange(Bot.GetGuild(Context.GuildId)?.Roles.Values ?? throw new InvalidOperationException()); + return Task.CompletedTask; + } + + [AutoComplete(LevelName.Remove)] + public async Task AutoCompleteRemove(AutoComplete role) + { + if (!role.IsFocused) return; + if(Context.CancellationToken.IsCancellationRequested) return; + await using var scope = Bot.Services.CreateAsyncScope(); + var service = scope.ServiceProvider.GetRequiredService(); + + } + + private static List BuildPages(List roles) + { + var result = new List(); + var span = CollectionsMarshal.AsSpan(roles); + for (var i = 0; i < span.Length;) + { + var page = new Page(); + for (var j = 0; j < 5; j++) + { + if(i >= span.Length) break; + var entry = span[i]; + if(roles[i].Money != null) page.Content += $"Level {entry.Level}: {entry.Money} coins\n"; + else page.Content += $"Level {roles[i].Level}: <@&{entry.RoleId}>\n"; + i++; + } + result.Add(page); + } + + return result; + } +} \ No newline at end of file diff --git a/Hanekawa/Data/Fonts/ARIAL.TTF b/Hanekawa.Bot/Data/Fonts/ARIAL.TTF similarity index 100% rename from Hanekawa/Data/Fonts/ARIAL.TTF rename to Hanekawa.Bot/Data/Fonts/ARIAL.TTF diff --git a/Hanekawa/Data/Fonts/TIMES.TTF b/Hanekawa.Bot/Data/Fonts/TIMES.TTF similarity index 100% rename from Hanekawa/Data/Fonts/TIMES.TTF rename to Hanekawa.Bot/Data/Fonts/TIMES.TTF diff --git a/Hanekawa.Bot/Data/Template/ProfileTemplate.png b/Hanekawa.Bot/Data/Template/ProfileTemplate.png new file mode 100644 index 00000000..d69f6951 Binary files /dev/null and b/Hanekawa.Bot/Data/Template/ProfileTemplate.png differ diff --git a/Hanekawa/Data/Profile/Template/Template.png b/Hanekawa.Bot/Data/Template/ProfileTemplateOld.png similarity index 100% rename from Hanekawa/Data/Profile/Template/Template.png rename to Hanekawa.Bot/Data/Template/ProfileTemplateOld.png diff --git a/Hanekawa/Data/Welcome/Default.png b/Hanekawa.Bot/Data/Template/WelcomeDefault.png similarity index 100% rename from Hanekawa/Data/Welcome/Default.png rename to Hanekawa.Bot/Data/Template/WelcomeDefault.png diff --git a/Hanekawa.Bot/Dockerfile b/Hanekawa.Bot/Dockerfile new file mode 100644 index 00000000..45a2c6e0 --- /dev/null +++ b/Hanekawa.Bot/Dockerfile @@ -0,0 +1,27 @@ +FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["nuget.config", ""] +COPY ["Hanekawa.Bot/Hanekawa.Bot.csproj", "Hanekawa.Bot/"] +COPY ["Hanekawa.Infrastructure/Hanekawa.Infrastructure.csproj", "Hanekawa.Infrastructure/"] +COPY ["Hanekawa.Application/Hanekawa.Application.csproj", "Hanekawa.Application/"] +COPY ["Hanekawa/Hanekawa.csproj", "Hanekawa/"] +RUN dotnet restore "Hanekawa.Bot/Hanekawa.Bot.csproj" +COPY . . +WORKDIR "/src/Hanekawa.Bot" +RUN dotnet build "Hanekawa.Bot.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "Hanekawa.Bot.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "Hanekawa.Bot.dll"] \ No newline at end of file diff --git a/Hanekawa.Bot/Hanekawa.Bot.csproj b/Hanekawa.Bot/Hanekawa.Bot.csproj new file mode 100644 index 00000000..6617f6b1 --- /dev/null +++ b/Hanekawa.Bot/Hanekawa.Bot.csproj @@ -0,0 +1,68 @@ + + + + net9.0 + preview + enable + enable + Linux + f7d196c4-e732-4306-a766-86a0881bda72 + + + + + + + + + + + + + + + + + + + + + + + .dockerignore + + + PreserveNewest + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + \ No newline at end of file diff --git a/Hanekawa.Bot/Mapper/DiscordMapper.cs b/Hanekawa.Bot/Mapper/DiscordMapper.cs new file mode 100644 index 00000000..f1032e8c --- /dev/null +++ b/Hanekawa.Bot/Mapper/DiscordMapper.cs @@ -0,0 +1,185 @@ +using Disqord; +using Disqord.Extensions.Interactivity.Menus.Paged; +using Disqord.Gateway; +using Hanekawa.Entities; +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Bot.Mapper; + +internal static class DiscordExtensions +{ + internal static LocalEmbed ToLocalEmbed(this Embed embed) + { + var toReturn = new LocalEmbed + { + Title = embed.Title ?? string.Empty, + ThumbnailUrl = embed.Icon ?? string.Empty, + Color = new Color(embed.Color), + Description = embed.Content ?? string.Empty, + ImageUrl = embed.Attachment ?? string.Empty, + Timestamp = embed.Timestamp + }; + if (embed.Header is not null) + { + toReturn.Author = new LocalEmbedAuthor + { + Name = embed.Header.Name, + IconUrl = embed.Header.IconUrl, + Url = embed.Header.Url + }; + } + if (embed.Footer is not null) + { + toReturn.Footer= new LocalEmbedFooter + { + IconUrl = embed.Footer.IconUrl, + Text = embed.Footer.Text, + }; + } + var fields = new List(); + for (var i = 0; i < embed.Fields.Count; i++) + { + var x = embed.Fields[i]; + fields.Add(new LocalEmbedField + { + Name = x.Name, + Value = x.Value, + IsInline = x.IsInline + }); + } + + if (fields is not { Count: 0 }) toReturn.Fields = fields; + return toReturn; + } + + internal static Embed ToEmbed(this IEmbed embed) + { + var toReturn = new Embed + { + Header = new EmbedHeader(embed.Author!.Name, (embed.Author.IconUrl ?? null)!, (embed.Author.Url ?? null)!), + Title = embed.Title, + Icon = embed.Thumbnail!.Url, + Color = embed.Color!.Value.RawValue, + Content = embed.Description!, + Attachment = embed.Image!.Url, + Timestamp = embed.Timestamp!.Value, + Footer = new EmbedFooter((embed.Footer!.Text), (embed.Footer.IconUrl ?? null)!) + }; + if (embed.Author is not null) + { + toReturn.Header = new EmbedHeader(embed.Author.Name, + embed.Author.IconUrl ?? string.Empty, + embed.Author.Url ?? string.Empty); + } + if (embed.Footer is not null) + { + toReturn.Footer = new EmbedFooter(embed.Footer.IconUrl ?? string.Empty, embed.Footer.Text); + } + return toReturn; + } + + internal static TextChannel ToTextChannel(this TransientInteractionChannel channel) => + new() + { + Id = channel.Id, + Category = (channel as ITextChannel)?.CategoryId ?? null, + GuildId = (channel as ITextChannel)?.GuildId ?? null, + Name = channel.Name, + Mention = "<#" + channel.Id + ">", + IsNsfw = (channel as ITextChannel)?.IsAgeRestricted ?? true + }; + + internal static DiscordMember ToDiscordMember(this IMember? member) + { + if (member is null) return new DiscordMember(); + return new DiscordMember + { + Id = member.Id, + Username = member.Name, + AvatarUrl = member.GetAvatarUrl(), + GuildId = member.GetGuild()!.Id, + Guild = new Guild + { + GuildId = member.GetGuild()!.Id, + Name = member.GetGuild()!.Name, + IconUrl = member.GetGuild()?.GetIconUrl()!, + Description = member.GetGuild()?.Description, + BoostCount = member.GetGuild()?.BoostingMemberCount, + BoostTier = member.GetGuild()!.BoostTier.GetHashCode(), + MemberCount = member.GetGuild()!.MemberCount, + Emotes = member.GetGuild()!.Emojis + .Select(e => new Emote + { + Id = e.Key.RawValue, + Name = e.Value.Name, + Format = e.Value.GetReactionFormat(), + IsAnimated = e.Value.IsAnimated, + IsAvailable = e.Value.IsAvailable, + IsManaged = e.Value.IsManaged + }).ToArray() + }, + Nickname = member.Nick, + IsBot = member.IsBot, + RoleIds = member.RoleIds.Select(x => x.RawValue).ToArray(), + VoiceSessionId = member.GetVoiceState()?.SessionId + }; + } + + internal static Guild ToGuild(this IMember user) => + new() + { + GuildId = user.GetGuild()!.Id, + Name = user.GetGuild()!.Name, + IconUrl = user.GetGuild()?.GetIconUrl()!, + Description = user.GetGuild()?.Description, + BoostCount = user.GetGuild()?.BoostingMemberCount, + BoostTier = user.GetGuild()!.BoostTier.GetHashCode(), + MemberCount = user.GetGuild()!.MemberCount, + Emotes = user.GetGuild()!.Emojis + .Select(e => new Emote + { + Id = e.Key.RawValue, + Name = e.Value.Name, + Format = e.Value.GetReactionFormat(), + IsAnimated = e.Value.IsAnimated, + IsAvailable = e.Value.IsAvailable, + IsManaged = e.Value.IsManaged + }).ToArray() + }; + + internal static LocalInteractionMessageResponse ToLocalInteractionMessageResponse(this Response response) => + new () + { + Content = response.Value.Content, + Embeds = new List { response.Value.Embed.ToLocalEmbed() }, + IsTextToSpeech = false, + AllowedMentions = response.Value.AllowMentions + ? LocalAllowedMentions.ExceptEveryone : LocalAllowedMentions.None, + Components = new List + { + new () + { + Components = new List + { + + } + } + }, + IsEphemeral = response.Value.Emphemeral + }; + + internal static Page[] ToPages(this Response> list) + { + var pages = new Page[list.Value.Items.Length / 5 + 1]; + var spans = list.Value.Items.AsSpan(); + for (var i = 0; i < spans.Length; i++) + { + var x = spans[i]; + pages[i] = new Page + { + Content = x.Content + }; + } + return pages; + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Program.cs b/Hanekawa.Bot/Program.cs new file mode 100644 index 00000000..a58e5e5c --- /dev/null +++ b/Hanekawa.Bot/Program.cs @@ -0,0 +1,44 @@ +using Disqord; +using Disqord.Bot.Hosting; +using Disqord.Gateway; +using Hanekawa.Application; +using Hanekawa.Application.Interfaces; +using Hanekawa.Bot.Bot; +using Hanekawa.Infrastructure; +using Serilog; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddApplicationLayer(builder.Configuration); +builder.Services.AddInfrastructureLayer(builder.Configuration); + +builder.Host.ConfigureDiscordBot((_, bot) => +{ + bot.Token = builder.Configuration["botToken"]; + bot.ApplicationId = new Snowflake(ulong.Parse(builder.Configuration["applicationId"]!)); + bot.UseMentionPrefix = true; + bot.ReadyEventDelayMode = ReadyEventDelayMode.Guilds; + bot.Intents |= GatewayIntents.All; +}); + +builder.Services.AddSingleton(); +builder.Services.AddHttpClient(); +builder.Host.UseDefaultServiceProvider(x => +{ + x.ValidateScopes = true; + x.ValidateOnBuild = true; +}); + +Log.Logger = new LoggerConfiguration() + .WriteTo.Console() + .CreateLogger(); + +builder.Logging.ClearProviders(); +builder.Host.UseSerilog(); + +var app = builder.Build(); +using (var scope = app.Services.CreateScope()) + await scope.ServiceProvider.GetRequiredService() + .MigrateDatabaseAsync(); + +app.Run(); \ No newline at end of file diff --git a/Hanekawa.Bot/Properties/launchSettings.json b/Hanekawa.Bot/Properties/launchSettings.json new file mode 100644 index 00000000..b3088c27 --- /dev/null +++ b/Hanekawa.Bot/Properties/launchSettings.json @@ -0,0 +1,22 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5120", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7234;http://localhost:5120", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/Services/Bot/DiscordEventRegister.cs b/Hanekawa.Bot/Services/Bot/DiscordEventRegister.cs new file mode 100644 index 00000000..812df35f --- /dev/null +++ b/Hanekawa.Bot/Services/Bot/DiscordEventRegister.cs @@ -0,0 +1,128 @@ +using Disqord; +using Disqord.Bot.Hosting; +using Disqord.Gateway; +using Hanekawa.Application.Contracts.Discord.Services; +using Hanekawa.Entities.Discord; +using MediatR; + +namespace Hanekawa.Bot.Services.Bot; + +public class DiscordEventRegister(IServiceProvider service) : DiscordBotService +{ + protected override async ValueTask OnMemberJoined(MemberJoinedEventArgs e) => + await service.GetRequiredService() + .Publish(new UserJoin(e.GuildId, e.MemberId, e.Member.Name, + e.Member.GetGuildAvatarUrl(), e.Member.CreatedAt())) + .ConfigureAwait(false); + + protected override async ValueTask OnMemberLeft(MemberLeftEventArgs e) + => await service.GetRequiredService() + .Publish(new UserLeave(e.GuildId, e.MemberId)) + .ConfigureAwait(false); + + protected override async ValueTask OnMessageReceived(BotMessageReceivedEventArgs e) + { + if (e.GuildId is null || e.Member is null) return; + await service.GetRequiredService() + .Publish(new MessageReceived(e.GuildId.Value, e.ChannelId, new DiscordMember + { + Guild = new Guild { GuildId = e.GuildId.Value }, + Id = e.Member.Id, + RoleIds = ConvertRoles(e.Member.RoleIds), + Nickname = e.Member.Nick, + IsBot = e.Member.IsBot, + Username = e.Member.Name, + AvatarUrl = e.Member.GetAvatarUrl(), + VoiceSessionId = e.Member.GetVoiceState()?.SessionId + }, e.MessageId, e.Message.Content, e.Message.CreatedAt())) + .ConfigureAwait(false); + } + + protected override async ValueTask OnMessageDeleted(MessageDeletedEventArgs e) + { + if (!e.GuildId.HasValue || e.Message is null) return; + await service.GetRequiredService() + .Publish(new MessageDeleted(e.GuildId.Value, e.ChannelId, e.Message.Author.Id, + e.MessageId, e.Message.Content)) + .ConfigureAwait(false); + } + + protected override async ValueTask OnMessagesDeleted(MessagesDeletedEventArgs e) + => await service.GetRequiredService() + .Publish(new MessagesDeleted(e.GuildId, e.ChannelId, + e.Messages.Select(x => x.Key.RawValue).ToArray(), + e.MessageIds.Select(x => x.RawValue).ToArray(), + e.Messages.Select(x => x.Value.Content).ToArray())) + .ConfigureAwait(false); + + protected override async ValueTask OnBanCreated(BanCreatedEventArgs e) + => await service.GetRequiredService() + .Publish(new UserBanned(new DiscordMember + { + Guild = new Guild { GuildId = e.GuildId }, + Id = e.UserId, + Username = e.User.Name, + IsBot = e.User.IsBot, + AvatarUrl = e.User.GetAvatarUrl() + })) + .ConfigureAwait(false); + + protected override async ValueTask OnBanDeleted(BanDeletedEventArgs e) + => await service.GetRequiredService() + .Publish(new UserUnbanned(new DiscordMember + { + Guild = new Guild { GuildId = e.GuildId }, + Id = e.UserId, + Username = e.User.Name, + IsBot = e.User.IsBot, + AvatarUrl = e.User.GetAvatarUrl() + })) + .ConfigureAwait(false); + + protected override ValueTask OnVoiceServerUpdated(VoiceServerUpdatedEventArgs e) => base.OnVoiceServerUpdated(e); + + protected override async ValueTask OnVoiceStateUpdated(VoiceStateUpdatedEventArgs e) + { + await service.GetRequiredService() + .Publish(new VoiceStateUpdate(e.GuildId, e.MemberId, e.NewVoiceState.ChannelId, + e.NewVoiceState.SessionId)) + .ConfigureAwait(false); + } + + protected override async ValueTask OnReactionAdded(ReactionAddedEventArgs e) + { + if (!e.GuildId.HasValue) return; + await service.GetRequiredService() + .Publish(new ReactionAdd(e.GuildId.Value, e.ChannelId, + e.MessageId, e.UserId, e.Emoji.GetReactionFormat())) + .ConfigureAwait(false); + } + + protected override async ValueTask OnReactionRemoved(ReactionRemovedEventArgs e) + { + if (!e.GuildId.HasValue) return; + await service.GetRequiredService() + .Publish(new ReactionRemove(e.GuildId.Value, e.ChannelId, e.MessageId, e.UserId, + e.Emoji.GetReactionFormat())) + .ConfigureAwait(false); + } + + protected override async ValueTask OnReactionsCleared(ReactionsClearedEventArgs e) + { + if (!e.GuildId.HasValue) return; + await service.GetRequiredService() + .Publish(new ReactionCleared(e.GuildId.Value, e.ChannelId, e.MessageId)) + .ConfigureAwait(false); + } + + private static ulong[] ConvertRoles(IReadOnlyList roles) + { + var toReturn = new ulong[roles.Count]; + for (var i = 0; i < roles.Count; i++) + { + var role = roles[i]; + toReturn[i] = role.RawValue; + } + return toReturn; + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/cache/cache.json b/Hanekawa.Bot/application-commands/cache/cache.json new file mode 100644 index 00000000..0c1a28f2 --- /dev/null +++ b/Hanekawa.Bot/application-commands/cache/cache.json @@ -0,0 +1 @@ +{"v":1,"g":[{"id":1216342277148905543,"t":1,"n":"unmute","d":"Un-mutes a user in the server","o":[{"t":3,"n":"member","d":"No description.","r":true},{"t":3,"n":"reason","d":"No description.","r":true}],"rmp":4194304,"dm":false,"ar":false},{"id":1216342277148905545,"t":1,"n":"ban","d":"Bans a user from the server","o":[{"t":3,"n":"member","d":"No description.","r":true},{"t":3,"n":"reason","d":"No description.","r":true}],"rmp":4,"dm":false,"ar":false},{"id":1216342277753143348,"t":1,"n":"voidwarn","d":"Voids a warn from a user in the server","o":[{"t":3,"n":"member","d":"No description.","r":true}],"rmp":4,"dm":false,"ar":false},{"id":1216342277753143349,"t":1,"n":"mute","d":"Mutes a user in the server","o":[{"t":3,"n":"member","d":"No description.","r":true},{"t":3,"n":"duration","d":"No description.","r":true},{"t":3,"n":"reason","d":"No description.","r":true}],"rmp":4194304,"dm":false,"ar":false},{"id":1216342277753143350,"t":1,"n":"unban","d":"Unbans a user from the server","o":[{"t":3,"n":"member","d":"No description.","r":true},{"t":3,"n":"reason","d":"No description.","r":true}],"rmp":4,"dm":false,"ar":false},{"id":1216342278222909501,"t":1,"n":"prune","d":"Prunes a number of messages from a channel","o":[{"t":4,"n":"message-count","d":"No description.","r":false,"mn":-2147483648.0,"mx":2147483647.0}],"rmp":8192,"dm":false,"ar":false},{"id":1216342278222909502,"t":1,"n":"clearwarns","d":"Clears all warnings from a user in the server","o":[{"t":3,"n":"member","d":"No description.","r":true}],"rmp":4,"dm":false,"ar":false},{"id":1222950922766778538,"t":1,"n":"rank","d":"Shows the rank of a user","o":[{"t":6,"n":"user","d":"No description.","r":true}],"dm":false,"ar":false},{"id":1216342278222909504,"t":1,"n":"warn","d":"Warns a user in the server","o":[{"t":3,"n":"member","d":"No description.","r":true},{"t":3,"n":"reason","d":"No description.","r":true}],"rmp":4194304,"dm":false,"ar":false},{"id":1216342278759518288,"t":1,"n":"kick","d":"Kick a user from the server","o":[{"t":3,"n":"member","d":"No description.","r":true},{"t":3,"n":"reason","d":"No description.","r":true}],"rmp":4,"dm":false,"ar":false},{"id":1222950924029267988,"t":1,"n":"wallet","d":"Shows the wallet of a user","ar":false},{"id":1216342278759518290,"t":1,"n":"warnlog","d":"List all warnings from a user in the server","o":[{"t":3,"n":"member","d":"No description.","r":true}],"rmp":4194304,"dm":false,"ar":false},{"id":1222950925178769468,"t":1,"n":"top","d":"Shows the top users","ar":false},{"id":1222950926495518750,"t":1,"n":"profile","d":"Shows the profile of a user","ar":false},{"id":1089986263362318399,"t":1,"n":"greet","d":"No description.","o":[{"t":1,"n":"imageremove","d":"Remove the greet image","o":[{"t":4,"n":"id","d":"No description.","r":true,"mn":-2147483648.0,"mx":2147483647.0,"ac":true}]},{"t":1,"n":"image","d":"Toggle the greet image"},{"t":1,"n":"message","d":"Set the greet message","o":[{"t":3,"n":"message","d":"No description.","r":true}]},{"t":1,"n":"imagelist","d":"List the greet images"},{"t":1,"n":"channel","d":"Set the greet channel","o":[{"t":7,"n":"channel","d":"No description.","r":true}]},{"t":1,"n":"imageurl","d":"Set the greet image url","o":[{"t":3,"n":"url","d":"No description.","r":true}]}],"rmp":16,"dm":false,"ar":false},{"id":1216342278759518291,"t":1,"n":"club","d":"No description.","o":[{"t":1,"n":"delete","d":"Delete a club","o":[{"t":3,"n":"name","d":"No description.","r":true}]},{"t":1,"n":"leave","d":"Leave a club","o":[{"t":3,"n":"name","d":"No description.","r":true}]},{"t":1,"n":"join","d":"Join a club","o":[{"t":3,"n":"name","d":"No description.","r":true}]},{"t":1,"n":"info","d":"Get club info","o":[{"t":3,"n":"name","d":"No description.","r":true}]},{"t":1,"n":"create","d":"Create a club","o":[{"t":3,"n":"name","d":"No description.","r":true},{"t":3,"n":"description","d":"No description.","r":true}]},{"t":1,"n":"list","d":"List all clubs"}],"dm":false,"ar":false},{"id":1216342278759518292,"t":1,"n":"level","d":"No description.","o":[{"t":1,"n":"modify","d":"Modify a level role","o":[{"t":4,"n":"level","d":"No description.","r":true,"mn":-2147483648.0,"mx":2147483647.0},{"t":8,"n":"role","d":"No description.","r":true}]},{"t":1,"n":"remove","d":"Remove a level role","o":[{"t":8,"n":"role","d":"No description.","r":true}]},{"t":1,"n":"add","d":"Add a level role","o":[{"t":4,"n":"level","d":"No description.","r":true,"mn":-2147483648.0,"mx":2147483647.0,"ac":true},{"t":8,"n":"role","d":"No description.","r":true}]},{"t":1,"n":"list","d":"List all level roles"}],"rmp":32,"dm":false,"ar":false},{"id":1380282568464797810,"t":1,"n":"boost","d":"No description.","o":[{"t":1,"n":"config","d":"List all registered boost actions"}],"dm":false,"ar":false}],"s":null} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/bg.json b/Hanekawa.Bot/application-commands/localizations/bg.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/bg.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/cs.json b/Hanekawa.Bot/application-commands/localizations/cs.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/cs.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/da.json b/Hanekawa.Bot/application-commands/localizations/da.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/da.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/de.json b/Hanekawa.Bot/application-commands/localizations/de.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/de.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/el.json b/Hanekawa.Bot/application-commands/localizations/el.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/el.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/en-GB.json b/Hanekawa.Bot/application-commands/localizations/en-GB.json new file mode 100644 index 00000000..04dfc543 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/en-GB.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "message", + "description": "Set the greet message", + "options": + { + "message": + { + "name": "message", + "description": "No description." + } + } + }, + "imageurl": + { + "name": "imageurl", + "description": "Set the greet image url", + "options": + { + "url": + { + "name": "url", + "description": "No description." + } + } + }, + "channel": + { + "name": "channel", + "description": "Set the greet channel", + "options": + { + "channel": + { + "name": "channel", + "description": "No description." + } + } + }, + "image": + { + "name": "image", + "description": "Toggle the greet image" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "imagelist", + "description": "List the greet images" + }, + "imageremove": + { + "name": "imageremove", + "description": "Remove the greet image", + "options": + { + "id": + { + "name": "id", + "description": "No description." + } + } + } + } + }, + "unmute": + { + "name": "unmute", + "description": "Un-mutes a user in the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + }, + "reason": + { + "name": "reason", + "description": "No description." + } + } + }, + "ban": + { + "name": "ban", + "description": "Bans a user from the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + }, + "reason": + { + "name": "reason", + "description": "No description." + } + } + }, + "voidwarn": + { + "name": "voidwarn", + "description": "Voids a warn from a user in the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + } + } + }, + "mute": + { + "name": "mute", + "description": "Mutes a user in the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + }, + "duration": + { + "name": "duration", + "description": "No description." + }, + "reason": + { + "name": "reason", + "description": "No description." + } + } + }, + "unban": + { + "name": "unban", + "description": "Unbans a user from the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + }, + "reason": + { + "name": "reason", + "description": "No description." + } + } + }, + "prune": + { + "name": "prune", + "description": "Prunes a number of messages from a channel", + "options": + { + "message-count": + { + "name": "message-count", + "description": "No description." + } + } + }, + "clearwarns": + { + "name": "clearwarns", + "description": "Clears all warnings from a user in the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + } + } + }, + "warn": + { + "name": "warn", + "description": "Warns a user in the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + }, + "reason": + { + "name": "reason", + "description": "No description." + } + } + }, + "kick": + { + "name": "kick", + "description": "Kick a user from the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + }, + "reason": + { + "name": "reason", + "description": "No description." + } + } + }, + "warnlog": + { + "name": "warnlog", + "description": "List all warnings from a user in the server", + "options": + { + "member": + { + "name": "member", + "description": "No description." + } + } + }, + "club": + { + "name": "club", + "description": "No description.", + "options": + { + "delete": + { + "name": "delete", + "description": "Delete a club", + "options": + { + "name": + { + "name": "name", + "description": "No description." + } + } + }, + "leave": + { + "name": "leave", + "description": "Leave a club", + "options": + { + "name": + { + "name": "name", + "description": "No description." + } + } + }, + "join": + { + "name": "join", + "description": "Join a club", + "options": + { + "name": + { + "name": "name", + "description": "No description." + } + } + }, + "info": + { + "name": "info", + "description": "Get club info", + "options": + { + "name": + { + "name": "name", + "description": "No description." + } + } + }, + "create": + { + "name": "create", + "description": "Create a club", + "options": + { + "name": + { + "name": "name", + "description": "No description." + }, + "description": + { + "name": "description", + "description": "No description." + } + } + }, + "list": + { + "name": "list", + "description": "List all clubs" + } + } + }, + "level": + { + "name": "level", + "description": "No description.", + "options": + { + "modify": + { + "name": "modify", + "description": "Modify a level role", + "options": + { + "level": + { + "name": "level", + "description": "No description." + }, + "role": + { + "name": "role", + "description": "No description." + } + } + }, + "remove": + { + "name": "remove", + "description": "Remove a level role", + "options": + { + "role": + { + "name": "role", + "description": "No description." + } + } + }, + "add": + { + "name": "add", + "description": "Add a level role", + "options": + { + "level": + { + "name": "level", + "description": "No description." + }, + "role": + { + "name": "role", + "description": "No description." + } + } + }, + "list": + { + "name": "list", + "description": "List all level roles" + } + } + }, + "rank": + { + "name": "rank", + "description": "Shows the rank of a user", + "options": + { + "user": + { + "name": "user", + "description": "No description." + } + } + }, + "wallet": + { + "name": "wallet", + "description": "Shows the wallet of a user" + }, + "top": + { + "name": "top", + "description": "Shows the top users" + }, + "profile": + { + "name": "profile", + "description": "Shows the profile of a user" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/en-US.json b/Hanekawa.Bot/application-commands/localizations/en-US.json new file mode 100644 index 00000000..c85cba50 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/en-US.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "toggleimage", + "description": "Enables or disables image to be sent with the greet message. Need to set a greet channel for it to be sent" + }, + "setmessage": + { + "name": "setmessage", + "description": "Sets message to be sent with the greet message. Need to set a greet channel for it to be sent", + "options": + { + "message": + { + "name": "message", + "description": "No description." + } + } + }, + "setimage": + { + "name": "setimage", + "description": "Sets image to be sent with the greet message. Need to set a greet channel for it to be sent", + "options": + { + "url": + { + "name": "url", + "description": "No description." + } + } + }, + "setchannel": + { + "name": "setchannel", + "description": "Sets which channel to send greet messages to", + "options": + { + "channel": + { + "name": "channel", + "description": "No description." + } + } + }, + "test2": + { + "name": "test2", + "description": "No description.", + "options": + { + "message": + { + "name": "message", + "description": "No description." + } + } + }, + "test4": + { + "name": "test4", + "description": "No description." + }, + "test1": + { + "name": "test1", + "description": "No description.", + "options": + { + "channel": + { + "name": "channel", + "description": "No description." + } + } + }, + "test3": + { + "name": "test3", + "description": "No description.", + "options": + { + "url": + { + "name": "url", + "description": "No description." + } + } + }, + "greet": + { + "name": "greet", + "description": "No description.", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "listimages", + "description": "List the greet images" + }, + "removeimage": + { + "name": "removeimage", + "description": "Remove the greet image", + "options": + { + "id": + { + "name": "id", + "description": "No description." + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "boost", + "description": "No description.", + "options": + { + "config": + { + "name": "config", + "description": "List all registered boost actions" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/es-ES.json b/Hanekawa.Bot/application-commands/localizations/es-ES.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/es-ES.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/fi.json b/Hanekawa.Bot/application-commands/localizations/fi.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/fi.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/fr.json b/Hanekawa.Bot/application-commands/localizations/fr.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/fr.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/hi.json b/Hanekawa.Bot/application-commands/localizations/hi.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/hi.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/hr.json b/Hanekawa.Bot/application-commands/localizations/hr.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/hr.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/hu.json b/Hanekawa.Bot/application-commands/localizations/hu.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/hu.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/id.json b/Hanekawa.Bot/application-commands/localizations/id.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/id.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/it.json b/Hanekawa.Bot/application-commands/localizations/it.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/it.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/ja.json b/Hanekawa.Bot/application-commands/localizations/ja.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/ja.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/ko.json b/Hanekawa.Bot/application-commands/localizations/ko.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/ko.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/lt.json b/Hanekawa.Bot/application-commands/localizations/lt.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/lt.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/nl.json b/Hanekawa.Bot/application-commands/localizations/nl.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/nl.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/no.json b/Hanekawa.Bot/application-commands/localizations/no.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/no.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/pl.json b/Hanekawa.Bot/application-commands/localizations/pl.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/pl.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/pt-BR.json b/Hanekawa.Bot/application-commands/localizations/pt-BR.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/pt-BR.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/ro.json b/Hanekawa.Bot/application-commands/localizations/ro.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/ro.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/ru.json b/Hanekawa.Bot/application-commands/localizations/ru.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/ru.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/sv-SE.json b/Hanekawa.Bot/application-commands/localizations/sv-SE.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/sv-SE.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/th.json b/Hanekawa.Bot/application-commands/localizations/th.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/th.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/tr.json b/Hanekawa.Bot/application-commands/localizations/tr.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/tr.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/uk.json b/Hanekawa.Bot/application-commands/localizations/uk.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/uk.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/vi.json b/Hanekawa.Bot/application-commands/localizations/vi.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/vi.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/zh-CN.json b/Hanekawa.Bot/application-commands/localizations/zh-CN.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/zh-CN.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/application-commands/localizations/zh-TW.json b/Hanekawa.Bot/application-commands/localizations/zh-TW.json new file mode 100644 index 00000000..4341c089 --- /dev/null +++ b/Hanekawa.Bot/application-commands/localizations/zh-TW.json @@ -0,0 +1,537 @@ +{ + "schema_version": 1, + "global_localizations": + { + "slash_commands": + { + "toggleimage": + { + "name": "", + "description": "" + }, + "setmessage": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "setimage": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "setchannel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test2": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "test4": + { + "name": "", + "description": "" + }, + "test1": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "test3": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "greet": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "", + "options": + { + "message": + { + "name": "", + "description": "" + } + } + }, + "imageurl": + { + "name": "", + "description": "", + "options": + { + "url": + { + "name": "", + "description": "" + } + } + }, + "channel": + { + "name": "", + "description": "", + "options": + { + "channel": + { + "name": "", + "description": "" + } + } + }, + "image": + { + "name": "", + "description": "" + }, + "listimages": + { + "name": "", + "description": "" + }, + "removeimage": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + }, + "imagelist": + { + "name": "", + "description": "" + }, + "imageremove": + { + "name": "", + "description": "", + "options": + { + "id": + { + "name": "", + "description": "" + } + } + } + } + }, + "unmute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "ban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "voidwarn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "mute": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "duration": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "unban": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "prune": + { + "name": "", + "description": "", + "options": + { + "message-count": + { + "name": "", + "description": "" + } + } + }, + "clearwarns": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "warn": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "kick": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + }, + "reason": + { + "name": "", + "description": "" + } + } + }, + "warnlog": + { + "name": "", + "description": "", + "options": + { + "member": + { + "name": "", + "description": "" + } + } + }, + "club": + { + "name": "", + "description": "", + "options": + { + "delete": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "leave": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "join": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "info": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + } + } + }, + "create": + { + "name": "", + "description": "", + "options": + { + "name": + { + "name": "", + "description": "" + }, + "description": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "level": + { + "name": "", + "description": "", + "options": + { + "modify": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "remove": + { + "name": "", + "description": "", + "options": + { + "role": + { + "name": "", + "description": "" + } + } + }, + "add": + { + "name": "", + "description": "", + "options": + { + "level": + { + "name": "", + "description": "" + }, + "role": + { + "name": "", + "description": "" + } + } + }, + "list": + { + "name": "", + "description": "" + } + } + }, + "rank": + { + "name": "", + "description": "", + "options": + { + "user": + { + "name": "", + "description": "" + } + } + }, + "wallet": + { + "name": "", + "description": "" + }, + "top": + { + "name": "", + "description": "" + }, + "profile": + { + "name": "", + "description": "" + }, + "boost": + { + "name": "", + "description": "", + "options": + { + "config": + { + "name": "", + "description": "" + } + } + } + } + }, + "guild_localizations": null +} \ No newline at end of file diff --git a/Hanekawa.Bot/appsettings.Development.json b/Hanekawa.Bot/appsettings.Development.json new file mode 100644 index 00000000..bd7f4c4a --- /dev/null +++ b/Hanekawa.Bot/appsettings.Development.json @@ -0,0 +1,100 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "ImageSettings": { + "Profile": { + "Width": 400, + "Height": 400, + "Avatar": { + "X": 145, + "Y": 4, + "Size": 110 + }, + "Font": "Arial", + "Texts": [ + { + "TextType": "Regular", + "Text": "Name", + "Headline": true, + "SourceType": "DiscordMember", + "SourceField": "DisplayName", + "Position": [{ "X": 10, "Y": 120 }, { "X": 390, "Y": 120 }], + "Size": 20 + }, + { + "TextType": "Regular", + "Text": "Level", + "SourceType": "GuildUser", + "SourceField": "Level", + "Position": [{ "X": 15, "Y": 160 }, { "X": 375, "Y": 160 }], + "Size": 20 + }, + { + "TextType": "Regular", + "Text": "Experience", + "SourceType": "GuildUser", + "SourceField": "CurrentLevelExperience", + "Position":[{ "X": 15, "Y": 190 },{ "X": 375, "Y": 190 }], + "Size": 20 + }, + { + "TextType": "Custom", + "Text": "Currency", + "SourceType": "GuildUser", + "SourceField": "Currency", + "Position":[{ "X": 15, "Y": 220 } ,{ "X": 375, "Y": 220 }], + "Size": 20 + }, + { + "TextType": "Regular", + "Text": "Rank", + "SourceType": "Custom", + "SourceField": "ServerRank", + "Position": [{ "X": 15, "Y": 250 } ,{ "X": 375, "Y": 250 }], + "Size": 20 + } + ] + }, + "Rank": { + "Width": 400, + "Height": 200, + "Avatar": { + "X": 25, + "Y": 4, + "Size": 150 + }, + "Font": "Arial", + "Texts": [ + { + "Headline": true, + "TextType": "Regular", + "Text": "Level", + "SourceType": "GuildUser", + "SourceField": "Level", + "Position": [{ "X": 15, "Y": 160 }, { "X": 375, "Y": 160 }], + "Size": 20 + }, + { + "TextType": "Regular", + "Text": "Experience", + "SourceType": "GuildUser", + "SourceField": "CurrentLevelExperience", + "Position": [{ "X": 15, "Y": 190 }, { "X": 375, "Y": 190 }], + "Size": 20 + }, + { + "TextType": "Regular", + "Text": "Rank", + "SourceType": "Custom", + "SourceField": "ServerRank", + "Position": [{ "X": 15, "Y": 220 }, { "X": 375, "Y": 220 }], + "Size": 20 + } + ] + } + } +} \ No newline at end of file diff --git a/Hanekawa.Bot/appsettings.json b/Hanekawa.Bot/appsettings.json new file mode 100644 index 00000000..1aef5074 --- /dev/null +++ b/Hanekawa.Bot/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Kestrel": { + "EndpointDefaults": { + "Protocols": "Http2" + } + } +} diff --git a/Hanekawa.Database/DbService.cs b/Hanekawa.Database/DbService.cs deleted file mode 100644 index e2658e84..00000000 --- a/Hanekawa.Database/DbService.cs +++ /dev/null @@ -1,855 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Hanekawa.Database.Tables; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Database.Tables.Achievement; -using Hanekawa.Database.Tables.Administration; -using Hanekawa.Database.Tables.Advertise; -using Hanekawa.Database.Tables.AutoMessage; -using Hanekawa.Database.Tables.BoardConfig; -using Hanekawa.Database.Tables.BotGame; -using Hanekawa.Database.Tables.Club; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Database.Tables.Giveaway; -using Hanekawa.Database.Tables.Internal; -using Hanekawa.Database.Tables.Moderation; -using Hanekawa.Database.Tables.Music; -using Hanekawa.Database.Tables.Premium; -using Hanekawa.Database.Tables.Profile; -using Hanekawa.Database.Tables.Quote; -using Hanekawa.Database.Tables.Stores; -using Hanekawa.Shared; -using Microsoft.EntityFrameworkCore; - -namespace Hanekawa.Database -{ - public class DbService : DbContext - { - public DbService(DbContextOptions options) : base(options) { } - - // Account - public DbSet Accounts { get; set; } - public DbSet AccountGlobals { get; set; } - public DbSet LevelRewards { get; set; } - public DbSet LevelExpEvents { get; set; } - public DbSet EventPayouts { get; set; } - public DbSet Highlights { get; set; } - - // Giveaway - public DbSet Giveaways { get; set; } - public DbSet GiveawayParticipants { get; set; } - public DbSet GiveawayHistories { get; set; } - - // Voice Role - public DbSet VoiceRoles { get; set; } - - // Stores - public DbSet ServerStores { get; set; } - - // Inventory - public DbSet Inventories { get; set; } - - // Items - public DbSet Items { get; set; } - public DbSet Backgrounds { get; set; } - - // Achievements - public DbSet Achievements { get; set; } - public DbSet AchievementNames { get; set; } - public DbSet AchievementTrackers { get; set; } - public DbSet AchievementUnlocks { get; set; } - public DbSet AchievementTypes { get; set; } - - // Administration - public DbSet Blacklists { get; set; } - public DbSet ApprovalQueues { get; set; } - - //Clubs - public DbSet ClubInfos { get; set; } - public DbSet ClubPlayers { get; set; } - public DbSet ClubBlacklists { get; set; } - - //Bot Game - public DbSet GameClasses { get; set; } - public DbSet GameConfigs { get; set; } - public DbSet GameEnemies { get; set; } - - //Config - public DbSet GuildConfigs { get; set; } - public DbSet AdminConfigs { get; set; } - public DbSet BoardConfigs { get; set; } - public DbSet ChannelConfigs { get; set; } - public DbSet ClubConfigs { get; set; } - public DbSet CurrencyConfigs { get; set; } - public DbSet LevelConfigs { get; set; } - public DbSet LoggingConfigs { get; set; } - public DbSet SuggestionConfigs { get; set; } - public DbSet WelcomeConfigs { get; set; } - public DbSet DropConfigs { get; set; } - public DbSet BoostConfigs { get; set; } - - public DbSet LootChannels { get; set; } - public DbSet WelcomeBanners { get; set; } - public DbSet IgnoreChannels { get; set; } - public DbSet Boards { get; set; } - public DbSet LevelExpReductions { get; set; } - public DbSet SelfAssignAbleRoles { get; set; } - - //Moderation - public DbSet ModLogs { get; set; } - public DbSet MuteTimers { get; set; } - public DbSet Reports { get; set; } - public DbSet Suggestions { get; set; } - public DbSet Warns { get; set; } - - // Music - public DbSet MusicConfigs { get; set; } - public DbSet Playlists { get; set; } - - // Premium - public DbSet MvpConfigs { get; set; } - - // Hunger Games - public DbSet HungerGames { get; set; } - public DbSet HungerGameCustomChars { get; set; } - public DbSet HungerGameDefaults { get; set; } - public DbSet HungerGameHistories { get; set; } - public DbSet HungerGameProfiles { get; set; } - public DbSet HungerGameStatus { get; set; } - - // Advertise - public DbSet DblAuths { get; set; } - public DbSet VoteLogs { get; set; } - public DbSet AutoMessages { get; set; } - - // Quote - public DbSet Quotes { get; set; } - - // Internal - public virtual DbSet Logs { get; set; } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - InventoryBuilder(modelBuilder); - ItemBuilder(modelBuilder); - StoreBuilder(modelBuilder); - AccountBuilder(modelBuilder); - AchievementBuilder(modelBuilder); - OwnerBuilder(modelBuilder); - ClubBuilder(modelBuilder); - ConfigBuilder(modelBuilder); - GameBuilder(modelBuilder); - AdministrationBuilder(modelBuilder); - ProfileBuilder(modelBuilder); - MusicBuilder(modelBuilder); - PremiumBuilder(modelBuilder); - HungerGameBuilder(modelBuilder); - InternalBuilder(modelBuilder); - Advertise(modelBuilder); - Giveaway(modelBuilder); - - modelBuilder.Entity(x => - { - x.HasKey(e => new { e.GuildId, e.VoiceId }); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.VoiceId).HasConversion(); - x.Property(e => e.RoleId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new { e.GuildId, e.Name }); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Creator).HasConversion(); - x.Property(e => e.ChannelId).HasConversion(); - }); - - modelBuilder.Entity(x => - { - x.HasKey(e => new { e.GuildId, e.Key }); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Creator).HasConversion(); - }); - } - - private static void Giveaway(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => new { e.Id }); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Creator).HasConversion(); - x.HasMany(e => e.Participants) - .WithOne(e => e.Giveaway) - .HasForeignKey(e => e.GiveawayId) - .OnDelete(DeleteBehavior.Cascade); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new { e.Id }); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - /* - x.HasOne(e => e.Giveaway) - .WithMany(e => e.Participants) - .HasForeignKey(e => e.GiveawayId) - .OnDelete(DeleteBehavior.Cascade); - */ - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Creator).HasConversion(); - x.Property(e => e.Winner).HasConversion(c => c.Select(item => (long) item).ToArray(), - wops => wops.Select(item => (ulong) item).ToArray()); - }); - } - - private static void Advertise(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.RoleIdReward).HasConversion(); - x.Property(e => e.AuthKey).ValueGeneratedOnAdd(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - } - - private static void OwnerBuilder(ModelBuilder modelBuilder) => modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.ResponsibleUser).HasConversion(); - }); - - private static void InventoryBuilder(ModelBuilder modelBuilder) => modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.UserId, e.ItemId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - - private static void ItemBuilder(ModelBuilder modelBuilder) => modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Role).HasConversion(); - x.Property(e => e.Type).HasConversion( - v => v.ToString(), - v => (ItemType) Enum.Parse(typeof(ItemType), v)); - }); - - private static void StoreBuilder(ModelBuilder modelBuilder) => modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.RoleId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.RoleId).HasConversion(); - }); - - private static void AccountBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.UserId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.StatMessages).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - x.Property(e => e.Decay).HasDefaultValue(0); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.UserId); - x.Property(e => e.UserId).HasConversion(); - x.Property(e => e.UserColor).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.Level}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Role).HasConversion(); - x.Property(e => e.NoDecay).HasDefaultValue(false); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.ChannelId).HasConversion(); - x.Property(e => e.MessageId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.UserId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.UserId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - } - - private static void AchievementBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.AchievementId); - x.Property(e => e.AchievementId).ValueGeneratedOnAdd(); - x.HasOne(p => p.AchievementName).WithMany(); - x.HasOne(p => p.AchievementType).WithMany(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.AchievementNameId); - x.Property(e => e.AchievementNameId).ValueGeneratedOnAdd(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Type, e.UserId}); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.AchievementId, e.UserId}); - x.HasOne(p => p.Achievement).WithMany(); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.TypeId); - x.Property(e => e.TypeId).ValueGeneratedOnAdd(); - }); - } - - private static void GameBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - ; - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - }); - } - - private static void AdministrationBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.MessageId).HasConversion(); - x.Property(e => e.ModId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.UserId, e.GuildId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - x.Property(e => e.MessageId).HasConversion(); - x.Property(e => e.ResponseUser).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - x.Property(e => e.MessageId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Uploader).HasConversion(); - x.Property(e => e.Type).HasConversion( - v => v.ToString(), - v => (ApprovalQueueType)Enum.Parse(typeof(ApprovalQueueType), v)); - }); - } - - private static void ClubBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id}); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.LeaderId).HasConversion(); - x.Property(e => e.AdMessage).HasConversion(); - x.Property(e => e.Channel).HasConversion(); - x.Property(e => e.Role).HasConversion(); - }); - - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id}); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.ClubId, e.GuildId, e.BlackListUser}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.BlackListUser).HasConversion(); - x.Property(e => e.IssuedUser).HasConversion(); - }); - } - - private static void ConfigBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.Premium).HasDefaultValue(false); - x.Property(e => e.EmbedColor).HasConversion(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.AnimeAirChannel).HasConversion(); - x.Property(e => e.EmbedColor).HasConversion(); - x.Property(e => e.MusicChannel).HasConversion(); - x.Property(e => e.MusicVcChannel).HasConversion(); - x.Property(e => e.MvpChannel).HasConversion(); - x.Property(e => e.HungerGameChannel).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.MuteRole).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Channel).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.DesignChannel).HasConversion(); - x.Property(e => e.EventChannel).HasConversion(); - x.Property(e => e.EventSchedulerChannel).HasConversion(); - x.Property(e => e.ModChannel).HasConversion(); - x.Property(e => e.QuestionAndAnswerChannel).HasConversion(); - x.Property(e => e.ReportChannel).HasConversion(); - x.Property(e => e.SelfAssignableChannel).HasConversion(); - x.Property(e => e.SelfAssignableMessages).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.AdvertisementChannel).HasConversion(); - x.Property(e => e.ChannelCategory).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.EmoteCurrency).HasDefaultValue(false); - x.Property(e => e.SpecialEmoteCurrency).HasDefaultValue(false); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.BoostExpMultiplier).HasDefaultValue(1); - x.Property(e => e.Decay).HasDefaultValue(false); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.LogAutoMod).HasConversion(); - x.Property(e => e.LogAvi).HasConversion(); - x.Property(e => e.LogBan).HasConversion(); - x.Property(e => e.LogJoin).HasConversion(); - x.Property(e => e.LogWarn).HasConversion(); - x.Property(e => e.LogMsg).HasConversion(); - x.Property(e => e.LogReaction).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Channel).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Channel).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - }); - - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.ChannelId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.ChannelId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.MessageId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - x.Property(e => e.MessageId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.Id}); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Uploader).HasConversion(); - x.Property(e => e.AvatarSize).HasDefaultValue(60); - x.Property(e => e.AviPlaceX).HasDefaultValue(10); - x.Property(e => e.AviPlaceY).HasDefaultValue(10); - x.Property(e => e.TextSize).HasDefaultValue(33); - x.Property(e => e.TextPlaceX).HasDefaultValue(245); - x.Property(e => e.TextPlaceY).HasDefaultValue(40); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.ChannelId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.ChannelId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.ChannelId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.ChannelId).HasConversion(); - x.Property(e => e.ChannelType).HasConversion( - v => v.ToString(), - v => (ChannelType) Enum.Parse(typeof(ChannelType), v)); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.RoleId}); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.RoleId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.ChannelId).HasConversion(); - }); - } - - private static void ProfileBuilder(ModelBuilder modelBuilder) => modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.HasData(new List - { - new Background - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new Background - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new Background - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new Background - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new Background - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new Background - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - } - }); - }); - - private static void MusicBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.TextChId).HasConversion(); - x.Property(e => e.VoiceChId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.GuildId, e.Name}); - x.Property(e => e.GuildId).HasConversion(); - }); - } - - private static void PremiumBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.RoleId).HasConversion(); - x.Property(e => e.Day).HasConversion( - v => v.ToString(), - v => (DayOfWeek) Enum.Parse(typeof(DayOfWeek), v)); - x.Property(e => e.Disabled).HasDefaultValue(true); - }); - } - - private static void HungerGameBuilder(ModelBuilder modelBuilder) - { - modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.GuildId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GameId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.Winner).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new { e.GuildId, e.UserId }); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.UserId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.GuildId); - x.Property(e => e.GuildId).HasConversion(); - x.Property(e => e.EventChannel).HasConversion(); - x.Property(e => e.SignUpChannel).HasConversion(); - x.Property(e => e.RoleReward).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => new {e.Id, e.GuildId}); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.Property(e => e.Id).HasConversion(); - x.Property(e => e.GuildId).HasConversion(); - }); - modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).HasConversion(); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - x.HasData(new List - { - new HungerGameDefault - { - Id = 1, - Name = "Dia", - Avatar = "https://i.imgur.com/XMjW8Qn.png" - }, - new HungerGameDefault - { - Id = 2, - Name = "Kanan", - Avatar = "https://i.imgur.com/7URjbvT.png" - }, - new HungerGameDefault - { - Id = 3, - Name = "Yoshiko", - Avatar = "https://i.imgur.com/tPDON9P.png" - }, - new HungerGameDefault - { - Id = 4, - Name = "Kongou", - Avatar = "https://i.imgur.com/dcB1loo.png" - }, - new HungerGameDefault - { - Id = 5, - Name = "Haruna", - Avatar = "https://i.imgur.com/7GC7FvJ.png" - }, - new HungerGameDefault - { - Id = 6, - Name = "Yamato", - Avatar = "https://i.imgur.com/8748bUL.png" - }, - new HungerGameDefault - { - Id = 7, - Name = "Akagi", - Avatar = "https://i.imgur.com/VLsezdF.png" - }, - new HungerGameDefault - { - Id = 8, - Name = "Kaga", - Avatar = "https://i.imgur.com/eyt9k8E.png" - }, - new HungerGameDefault - { - Id = 9, - Name = "Zero Two", - Avatar = "https://i.imgur.com/4XYg6ch.png" - }, - new HungerGameDefault - { - Id = 10, - Name = "Echidna", - Avatar = "https://i.imgur.com/Nl6WsbP.png" - }, - new HungerGameDefault - { - Id = 11, - Name = "Emilia", - Avatar = "https://i.imgur.com/kF9b4SJ.png" - }, - new HungerGameDefault - { - Id = 12, - Name = "Rem", - Avatar = "https://i.imgur.com/y3bb8Sk.png" - }, - new HungerGameDefault - { - Id = 13, - Name = "Ram", - Avatar = "https://i.imgur.com/5CcdVBE.png" - }, - new HungerGameDefault - { - Id = 14, - Name = "Gura", - Avatar = "https://i.imgur.com/0VYBYEg.png" - }, - new HungerGameDefault - { - Id = 15, - Name = "Shiki", - Avatar = "https://i.imgur.com/rYa5iYc.png" - }, - new HungerGameDefault - { - Id = 16, - Name = "Chika", - Avatar = "https://i.imgur.com/PT8SsVB.png" - }, - new HungerGameDefault - { - Id = 17, - Name = "Sora", - Avatar = "https://i.imgur.com/5xR0ImK.png" - }, - new HungerGameDefault - { - Id = 18, - Name = "Nobuna", - Avatar = "https://i.imgur.com/U0NlfJd.png" - }, - new HungerGameDefault - { - Id = 19, - Name = "Akame", - Avatar = "https://i.imgur.com/CI9Osi5.png" - }, - new HungerGameDefault - { - Id = 20, - Name = "Shiina", - Avatar = "https://i.imgur.com/GhSG97V.png" - }, - new HungerGameDefault - { - Id = 21, - Name = "Bocchi", - Avatar = "https://i.imgur.com/VyJf95i.png" - }, - new HungerGameDefault - { - Id = 22, - Name = "Enterprise", - Avatar = "https://i.imgur.com/bv5ao8Z.png" - }, - new HungerGameDefault - { - Id = 23, - Name = "Chocola", - Avatar = "https://i.imgur.com/HoNwKi9.png" - }, - new HungerGameDefault - { - Id = 24, - Name = "Vanilla", - Avatar = "https://i.imgur.com/aijxHla.png" - }, - new HungerGameDefault - { - Id = 25, - Name = "Shiro", - Avatar = "https://i.imgur.com/Wxhd5WY.png" - } - }); - }); - } - - private static void InternalBuilder(ModelBuilder modelBuilder) => modelBuilder.Entity(x => - { - x.HasKey(e => e.Id); - x.Property(e => e.Id).ValueGeneratedOnAdd(); - }); - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Extensions/AccountExtension.cs b/Hanekawa.Database/Extensions/AccountExtension.cs deleted file mode 100644 index 2ce7a358..00000000 --- a/Hanekawa.Database/Extensions/AccountExtension.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Account; - -namespace Hanekawa.Database.Extensions -{ - public static partial class DbExtensions - { - public static async Task GetOrCreateUserData(this DbService context, CachedMember user) => - await GetOrCreateServerUser(context, user.Guild.Id.RawValue, user.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateUserData(this DbService context, IGuild guild, IUser user) => - await GetOrCreateServerUser(context, guild.Id.RawValue, user.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateUserData(this DbService context, ulong guild, ulong user) => - await GetOrCreateServerUser(context, guild, user).ConfigureAwait(false); - - public static async Task GetOrCreateGlobalUserData(this DbService context, IUser user) => - await GetOrCreateGlobalUser(context, user.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateGlobalUserData(this DbService context, ulong userId) => - await GetOrCreateGlobalUser(context, userId).ConfigureAwait(false); - - public static async Task GetOrCreateGlobalUserData(this DbService context, CachedMember user) => - await GetOrCreateGlobalUser(context, user.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateGlobalUserData(this DbService context, CachedUser user) => - await GetOrCreateGlobalUser(context, user.Id.RawValue).ConfigureAwait(false); - - private static async Task GetOrCreateServerUser(DbService context, ulong guild, ulong user) - { - var userdata = await context.Accounts.FindAsync(guild, user).ConfigureAwait(false); - if (userdata != null) return userdata; - - var data = new Account().DefaultAccount(guild, user); - try - { - await context.Accounts.AddAsync(data); - await context.SaveChangesAsync(); - await Task.Delay(20); - var toReturn = await context.Accounts.FindAsync(user, guild); - return toReturn ?? data; - } - catch - { - return data; - } - } - - private static async Task GetOrCreateGlobalUser(this DbService context, ulong userId) - { - var userdata = await context.AccountGlobals.FindAsync(userId).ConfigureAwait(false); - if (userdata != null) return userdata; - - var data = new AccountGlobal().DefaultAccountGlobal(userId); - try - { - await context.AccountGlobals.AddAsync(data); - await context.SaveChangesAsync(); - await Task.Delay(20); - var toReturn = await context.AccountGlobals.FindAsync(userId); - return toReturn ?? data; - } - catch - { - return data; - } - } - } -} diff --git a/Hanekawa.Database/Extensions/AchievementExtension.cs b/Hanekawa.Database/Extensions/AchievementExtension.cs deleted file mode 100644 index 931172ec..00000000 --- a/Hanekawa.Database/Extensions/AchievementExtension.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Achievement; - -namespace Hanekawa.Database.Extensions -{ - public static partial class DbExtensions - { - public static async Task GetOrCreateAchievementProgress(this DbService context, CachedMember user, - int type) - { - var check = await context.AchievementTrackers.FindAsync(type, user.Id.RawValue).ConfigureAwait(false); - if (check != null) return check; - var data = new AchievementTracker - { - Count = 0, - Type = type, - UserId = user.Id.RawValue - }; - try - { - await context.AchievementTrackers.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.AchievementTrackers.FindAsync(type, user.Id.RawValue).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateAchievementProgress(this DbService context, ulong userId, - int type) - { - var check = await context.AchievementTrackers.FindAsync(type, userId).ConfigureAwait(false); - if (check != null) return check; - var data = new AchievementTracker - { - Count = 0, - Type = type, - UserId = userId - }; - try - { - await context.AchievementTrackers.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.AchievementTrackers.FindAsync(type, userId).ConfigureAwait(false); - } - catch - { - return data; - } - } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Extensions/AdministrationExtension.cs b/Hanekawa.Database/Extensions/AdministrationExtension.cs deleted file mode 100644 index 30aca2ae..00000000 --- a/Hanekawa.Database/Extensions/AdministrationExtension.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Moderation; -using Hanekawa.Shared; -using Microsoft.EntityFrameworkCore; - -namespace Hanekawa.Database.Extensions -{ - public static partial class DbExtensions - { - public static async Task CreateCaseId(this DbService context, CachedUser user, CachedGuild guild, - DateTime time, ModAction action) - { - var counter = await context.ModLogs.CountAsync(x => x.GuildId == guild.Id.RawValue).ConfigureAwait(false); - var data = new ModLog - { - Id = counter + 1, - GuildId = guild.Id.RawValue, - UserId = user.Id.RawValue, - Date = time, - Action = action.ToString() - }; - await context.ModLogs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.ModLogs.FirstOrDefaultAsync(x => - x.Date == time && x.UserId == user.Id.RawValue && x.GuildId == guild.Id.RawValue).ConfigureAwait(false); - } - - public static async Task CreateReport(this DbService context, CachedUser user, CachedGuild guild, - DateTime time) - { - var counter = await context.Reports.CountAsync(x => x.GuildId == guild.Id.RawValue).ConfigureAwait(false); - var nr = counter == 0 ? 1 : counter + 1; - - var data = new Report - { - Id = nr, - GuildId = guild.Id.RawValue, - UserId = user.Id.RawValue, - Status = true, - Date = time - }; - await context.Reports.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.Reports.FirstOrDefaultAsync(x => x.Date == time).ConfigureAwait(false); - } - } -} diff --git a/Hanekawa.Database/Extensions/ClubExtension.cs b/Hanekawa.Database/Extensions/ClubExtension.cs deleted file mode 100644 index c4426c94..00000000 --- a/Hanekawa.Database/Extensions/ClubExtension.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Club; -using Microsoft.EntityFrameworkCore; - -namespace Hanekawa.Database.Extensions -{ - public static partial class DbExtensions - { - public static async Task CreateClub(this DbService context, CachedUser user, CachedGuild guild, - string name, DateTimeOffset time) - { - var data = new ClubInformation - { - GuildId = guild.Id.RawValue, - LeaderId = user.Id.RawValue, - Name = name, - CreationDate = time, - Channel = null, - Description = null, - AdMessage = null, - AutoAdd = false, - ImageUrl = null, - Public = false, - IconUrl = null - }; - await context.ClubInfos.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.ClubInfos.FirstOrDefaultAsync(x => x.GuildId == guild.Id.RawValue && x.LeaderId == user.Id.RawValue).ConfigureAwait(false); - } - - public static async Task GetClubAsync(this DbService context, CachedMember user, int id) - { - var check = await context.ClubInfos.FirstOrDefaultAsync(x => x.Id == id && x.GuildId == user.Guild.Id.RawValue).ConfigureAwait(false); - return check; - } - } -} diff --git a/Hanekawa.Database/Extensions/ConfigExtension.cs b/Hanekawa.Database/Extensions/ConfigExtension.cs deleted file mode 100644 index 47a886de..00000000 --- a/Hanekawa.Database/Extensions/ConfigExtension.cs +++ /dev/null @@ -1,337 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Database.Tables.Music; -using Hanekawa.Database.Tables.Premium; - -namespace Hanekawa.Database.Extensions -{ - public static class ConfigExtension - { - public static async Task GetOrCreateGuildConfigAsync(this DbService context, CachedGuild guild) => - await GetOrCreateGuildConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateGuildConfigAsync(this DbService context, ulong guild) - { - var response = await context.GuildConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new GuildConfig().DefaultGuildConfig(guild); - try - { - await context.GuildConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.GuildConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static GuildConfig GetOrCreateGuildConfig(this DbService context, CachedGuild guild) => - GetOrCreateGuildConfig(context, guild.Id.RawValue); - - public static GuildConfig GetOrCreateGuildConfig(this DbService context, ulong guild) - { - var response = context.GuildConfigs.Find(guild); - if (response != null) return response; - - var data = new GuildConfig().DefaultGuildConfig(guild); - try - { - context.GuildConfigs.Add(data); - context.GuildConfigs.Update(data); - context.SaveChanges(); - return context.GuildConfigs.Find(guild); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateAdminConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateAdminConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateAdminConfigAsync(this DbService context, ulong guild) - { - var response = await context.AdminConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new AdminConfig().DefaultAdminConfig(guild); - try - { - await context.AdminConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.AdminConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateBoardConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateBoardConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateBoardConfigAsync(this DbService context, ulong guild) - { - var response = await context.BoardConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new BoardConfig().DefaultBoardConfig(guild); - try - { - await context.BoardConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.BoardConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateChannelConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateChannelConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateChannelConfigAsync(this DbService context, ulong guild) - { - var response = await context.ChannelConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new ChannelConfig().DefaultChannelConfig(guild); - try - { - await context.ChannelConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.ChannelConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateClubConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateClubConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateClubConfigAsync(this DbService context, ulong guild) - { - var response = await context.ClubConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - var data = new ClubConfig().DefaultClubConfig(guild); - try - { - await context.ClubConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.ClubConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateCurrencyConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateCurrencyConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateCurrencyConfigAsync(this DbService context, ulong guild) - { - var response = await context.CurrencyConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - var data = new CurrencyConfig().DefaultCurrencyConfig(guild); - try - { - await context.CurrencyConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.CurrencyConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateLevelConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateLevelConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateLevelConfigAsync(this DbService context, ulong guild) - { - var response = await context.LevelConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - var data = new LevelConfig().DefaultLevelConfig(guild); - try - { - await context.LevelConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.LevelConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateLoggingConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateLoggingConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateLoggingConfigAsync(this DbService context, ulong guild) - { - var response = await context.LoggingConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new LoggingConfig().DefaultLoggingConfig(guild); - try - { - await context.LoggingConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.LoggingConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateSuggestionConfigAsync(this DbService context, - IGuild guild) => - await GetOrCreateSuggestionConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateSuggestionConfigAsync(this DbService context, ulong guild) - { - var response = await context.SuggestionConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new SuggestionConfig().DefaultSuggestionConfig(guild); - try - { - await context.SuggestionConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.SuggestionConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateWelcomeConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateWelcomeConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateWelcomeConfigAsync(this DbService context, ulong guild) - { - var response = await context.WelcomeConfigs.FindAsync(guild).ConfigureAwait(false); - if (response != null) return response; - - var data = new WelcomeConfig().DefaultWelcomeConfig(guild); - try - { - await context.WelcomeConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.WelcomeConfigs.FindAsync(guild).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateDropConfig(this DbService context, IGuild guild) => - await GetOrCreateDropConfig(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateDropConfig(this DbService context, ulong guildId) - { - var response = await context.DropConfigs.FindAsync(guildId).ConfigureAwait(false); - if (response != null) return response; - var data = new DropConfig().DefaultDropConfig(guildId); - try - { - await context.DropConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.DropConfigs.FindAsync(guildId).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateMusicConfig(this DbService context, CachedGuild guild) => - await GetOrCreateMusicConfig(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateMusicConfig(this DbService context, ulong guildId) - { - var response = await context.MusicConfigs.FindAsync(guildId).ConfigureAwait(false); - if (response != null) return response; - var data = new MusicConfig { GuildId = guildId }; - try - { - await context.MusicConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.MusicConfigs.FindAsync(guildId).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateMvpConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateMvpConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateMvpConfigAsync(this DbService context, ulong guildId) - { - var response = await context.MvpConfigs.FindAsync(guildId).ConfigureAwait(false); - if (response != null) return response; - var data = new MvpConfig - { - GuildId = guildId, - RoleId = null, - Count = 5, - Day = DayOfWeek.Wednesday - }; - try - { - await context.MvpConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.MvpConfigs.FindAsync(guildId).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateBoostConfigAsync(this DbService context, IGuild guild) => - await GetOrCreateBoostConfigAsync(context, guild.Id.RawValue).ConfigureAwait(false); - - public static async Task GetOrCreateBoostConfigAsync(this DbService context, ulong guildId) - { - var response = await context.BoostConfigs.FindAsync(guildId).ConfigureAwait(false); - if (response != null) return response; - var data = new BoostConfig - { - GuildId = guildId, - Message = null, - ChannelId = null, - CreditGain = 0, - ExpGain = 0, - SpecialCreditGain = 0 - }; - try - { - await context.BoostConfigs.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.BoostConfigs.FindAsync(guildId).ConfigureAwait(false); - } - catch - { - return data; - } - } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Extensions/DbExtensions.cs b/Hanekawa.Database/Extensions/DbExtensions.cs deleted file mode 100644 index c3020af4..00000000 --- a/Hanekawa.Database/Extensions/DbExtensions.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.BoardConfig; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Database.Tables.Moderation; -using Microsoft.EntityFrameworkCore; - -namespace Hanekawa.Database.Extensions -{ - public static partial class DbExtensions - { - public static async Task GetOrCreateEventParticipant(this DbService context, CachedMember user) - { - var userdata = await context.EventPayouts.FindAsync(user.Guild.Id.RawValue, user.Id.RawValue).ConfigureAwait(false); - if (userdata != null) return userdata; - - var data = new EventPayout - { - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Amount = 0 - }; - try - { - await context.EventPayouts.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.EventPayouts.FindAsync(user.Guild.Id.RawValue, user.Id.RawValue).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task GetOrCreateBoard(this DbService context, CachedGuild guild, IMessage msg) - { - var check = await context.Boards.FindAsync(guild.Id.RawValue, msg.Id.RawValue).ConfigureAwait(false); - if (check != null) return check; - - var data = new Board - { - GuildId = guild.Id.RawValue, - MessageId = msg.Id.RawValue, - StarAmount = 0, - Boarded = null, - UserId = msg.Author.Id.RawValue - }; - try - { - await context.Boards.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.Boards.FindAsync(guild.Id.RawValue, msg.Id.RawValue).ConfigureAwait(false); - } - catch - { - return data; - } - } - - public static async Task CreateSuggestion(this DbService context, IUser user, CachedGuild guild, - DateTime time) - { - var counter = await context.Suggestions.CountAsync(x => x.GuildId == guild.Id.RawValue).ConfigureAwait(false); - var nr = counter == 0 ? 1 : counter + 1; - - var data = new Suggestion - { - Id = nr, - GuildId = guild.Id.RawValue, - Date = time, - UserId = user.Id.RawValue, - Status = true - }; - try - { - await context.Suggestions.AddAsync(data).ConfigureAwait(false); - await context.SaveChangesAsync().ConfigureAwait(false); - return await context.Suggestions.FirstOrDefaultAsync(x => x.Date == time).ConfigureAwait(false); - } - catch - { - return data; - } - } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Extensions/DefaultConfig.cs b/Hanekawa.Database/Extensions/DefaultConfig.cs deleted file mode 100644 index 89c5d1df..00000000 --- a/Hanekawa.Database/Extensions/DefaultConfig.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Collections.Generic; -using Disqord; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Database.Tables.Config.Guild; - -namespace Hanekawa.Database.Extensions -{ - internal static class DefaultConfig - { - internal static GuildConfig DefaultGuildConfig(this GuildConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.Prefix = "h."; - cfg.MusicVcChannel = null; - cfg.MusicChannel = null; - cfg.Premium = false; - cfg.AnimeAirChannel = null; - cfg.AutomaticEventSchedule = false; - cfg.EmbedColor = 10181046; - return cfg; - } - - internal static AdminConfig DefaultAdminConfig(this AdminConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.FilterAllInv = true; - cfg.FilterInvites = false; - cfg.FilterUrls = false; - cfg.IgnoreAllChannels = false; - cfg.MuteRole = null; - cfg.MentionCountFilter = null; - cfg.EmoteCountFilter = null; - cfg.FilterMsgLength = null; - return cfg; - } - - internal static BoardConfig DefaultBoardConfig(this BoardConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.Channel = null; - cfg.Emote = null; - return cfg; - } - - internal static ChannelConfig DefaultChannelConfig(this ChannelConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.DesignChannel = null; - cfg.EventChannel = null; - cfg.EventSchedulerChannel = null; - cfg.ModChannel = null; - cfg.QuestionAndAnswerChannel = null; - cfg.ReportChannel = null; - return cfg; - } - - internal static ClubConfig DefaultClubConfig(this ClubConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.AdvertisementChannel = null; - cfg.AutoPrune = false; - cfg.ChannelCategory = null; - cfg.ChannelRequiredAmount = 4; - cfg.ChannelRequiredLevel = 10; - cfg.EnableVoiceChannel = false; - cfg.RoleEnabled = true; - return cfg; - } - - internal static CurrencyConfig DefaultCurrencyConfig(this CurrencyConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.CurrencyName = "Credit"; - cfg.CurrencySign = "$"; - cfg.EmoteCurrency = false; - cfg.SpecialCurrencyName = "Special credit"; - cfg.SpecialCurrencySign = "$"; - cfg.SpecialEmoteCurrency = false; - return cfg; - } - - internal static LevelConfig DefaultLevelConfig(this LevelConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.TextExpMultiplier = 1; - cfg.TextExpEnabled = true; - cfg.VoiceExpMultiplier = 1; - cfg.VoiceExpEnabled = true; - cfg.StackLvlRoles = true; - cfg.ExpDisabled = false; - cfg.Decay = false; - return cfg; - } - - internal static LoggingConfig DefaultLoggingConfig(this LoggingConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.LogMsg = null; - cfg.LogJoin = null; - cfg.LogBan = null; - cfg.LogAvi = null; - cfg.LogAutoMod = null; - cfg.LogWarn = null; - cfg.LogVoice = null; - return cfg; - } - - internal static SuggestionConfig DefaultSuggestionConfig(this SuggestionConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.Channel = null; - cfg.EmoteYes = "<:1yes:403870491749777411>"; - cfg.EmoteNo = "<:2no:403870492206825472>"; - return cfg; - } - - internal static WelcomeConfig DefaultWelcomeConfig(this WelcomeConfig cfg, ulong guild) - { - cfg.GuildId = guild; - cfg.Channel = null; - cfg.Banner = false; - cfg.Limit = 5; - cfg.Message = null; - cfg.Reward = null; - cfg.TimeToDelete = null; - cfg.AutoDelOnLeave = false; - cfg.IgnoreNew = null; - return cfg; - } - - internal static Account DefaultAccount(this Account account, ulong guild, ulong user) - { - account.UserId = user; - account.GuildId = guild; - account.Active = true; - account.Class = 1; - account.Credit = 0; - account.CreditSpecial = 0; - account.DailyCredit = DateTime.UtcNow; - account.GameKillAmount = 0; - account.RepCooldown = DateTime.UtcNow; - account.Exp = 0; - account.VoiceExpTime = DateTime.UtcNow; - account.TotalExp = 0; - account.Level = 1; - account.Sessions = 0; - account.StatVoiceTime = TimeSpan.Zero; - account.ChannelVoiceTime = DateTime.UtcNow; - account.StatMessages = 0; - account.Rep = 0; - account.ProfilePic = null; - account.StarGiven = 0; - account.StarReceived = 0; - return account; - } - - internal static AccountGlobal DefaultAccountGlobal(this AccountGlobal account, ulong userId) - { - account.UserId = userId; - account.Exp = 0; - account.TotalExp = 0; - account.Level = 1; - account.Rep = 0; - account.StarGive = 0; - account.StarReceive = 0; - account.Credit = 0; - account.UserColor = (uint)Color.Purple.RawValue; - return account; - } - - internal static DropConfig DefaultDropConfig(this DropConfig cfg, ulong guildId) - { - cfg.GuildId = guildId; - cfg.Emote = "<:realsip:429809346222882836>"; - return cfg; - } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Extensions/HungerGameExtension.cs b/Hanekawa.Database/Extensions/HungerGameExtension.cs deleted file mode 100644 index 83b167ad..00000000 --- a/Hanekawa.Database/Extensions/HungerGameExtension.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Shared.Game.HungerGame; - -namespace Hanekawa.Database.Extensions -{ - public static class HungerGameExtension - { - public static async Task GetOrCreateHungerGameStatus(this DbService db, CachedGuild guild) => - await GetOrCreateHungerGameStatus(db, guild.Id.RawValue); - - public static async Task GetOrCreateHungerGameStatus(this DbService db, ulong guildId) - { - var response = await db.HungerGameStatus.FindAsync(guildId); - if (response != null) return response; - var data = new HungerGameStatus - { - GuildId = guildId, - SignUpChannel = null, - EventChannel = null, - EmoteMessageFormat = "<:Rooree:761209568365248513>", - Stage = HungerGameStage.Closed, - SignUpStart = DateTimeOffset.UtcNow, - SignUpMessage = null, - GameId = null, - - ExpReward = 0, - CreditReward = 0, - SpecialCreditReward = 0, - RoleReward = null - }; - await db.HungerGameStatus.AddAsync(data); - await db.SaveChangesAsync(); - response = await db.HungerGameStatus.FindAsync(guildId); - return response ?? data; - } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Hanekawa.Database.csproj b/Hanekawa.Database/Hanekawa.Database.csproj deleted file mode 100644 index 73f96f78..00000000 --- a/Hanekawa.Database/Hanekawa.Database.csproj +++ /dev/null @@ -1,63 +0,0 @@ - - - - net5.0 - 8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - - diff --git a/Hanekawa.Database/Migrations/20190224222819_initial.Designer.cs b/Hanekawa.Database/Migrations/20190224222819_initial.Designer.cs deleted file mode 100644 index 668672dd..00000000 --- a/Hanekawa.Database/Migrations/20190224222819_initial.Designer.cs +++ /dev/null @@ -1,1045 +0,0 @@ -// - -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20190224222819_initial")] - partial class initial - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Account.Account", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Active"); - - b.Property("ChannelVoiceTime"); - - b.Property("Class"); - - b.Property("Credit"); - - b.Property("CreditSpecial"); - - b.Property("DailyCredit"); - - b.Property("Exp"); - - b.Property("FirstMessage"); - - b.Property("GameKillAmount"); - - b.Property("LastMessage"); - - b.Property("Level"); - - b.Property("ProfilePic"); - - b.Property("Rep"); - - b.Property("RepCooldown"); - - b.Property("Sessions"); - - b.Property("StarGiven"); - - b.Property("StarReceived"); - - b.Property("StatMessages"); - - b.Property("StatVoiceTime"); - - b.Property("TotalExp"); - - b.Property("VoiceExpTime"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd(); - - b.Property("Credit"); - - b.Property("Exp"); - - b.Property("Level"); - - b.Property("Rep"); - - b.Property("StarGive"); - - b.Property("StarReceive"); - - b.Property("TotalExp"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("ItemId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DateAdded"); - - b.Property("GuildId"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementDifficulty", b => - { - b.Property("DifficultyId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("DifficultyId"); - - b.ToTable("AchievementDifficulties"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd(); - - b.Property("AchievementNameId"); - - b.Property("Description"); - - b.Property("DifficultyId"); - - b.Property("Global"); - - b.Property("Hidden"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Once"); - - b.Property("Points"); - - b.Property("Requirement"); - - b.Property("Reward"); - - b.Property("TypeId"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("DifficultyId"); - - b.HasIndex("TypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd(); - - b.Property("Description"); - - b.Property("Name"); - - b.Property("Stackable"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Count"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId"); - - b.Property("UserId"); - - b.Property("TypeId"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Reason"); - - b.Property("ResponsibleUser"); - - b.Property("Unban"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Administration.EventSchedule", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Description"); - - b.Property("DesignerClaim"); - - b.Property("Host"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Posted"); - - b.Property("Time"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("EventSchedules"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Administration.WhitelistDesign", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("WhitelistDesigns"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Administration.WhitelistEvent", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("WhitelistEvents"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId"); - - b.Property("MessageId"); - - b.Property("Boarded"); - - b.Property("StarAmount"); - - b.Property("UserId"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ChanceAvoid"); - - b.Property("ChanceCrit"); - - b.Property("LevelRequirement"); - - b.Property("ModifierAvoidance"); - - b.Property("ModifierCriticalChance"); - - b.Property("ModifierDamage"); - - b.Property("ModifierHealth"); - - b.Property("Name"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DefaultDamage"); - - b.Property("DefaultHealth"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClassId"); - - b.Property("CreditGain"); - - b.Property("Damage"); - - b.Property("Elite"); - - b.Property("ExpGain"); - - b.Property("Health"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Rare"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("BlackListUser"); - - b.Property("IssuedUser"); - - b.Property("Reason"); - - b.Property("Time"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("AdMessage"); - - b.Property("AutoAdd"); - - b.Property("Channel"); - - b.Property("CreationDate"); - - b.Property("Description"); - - b.Property("GuildId"); - - b.Property("IconUrl"); - - b.Property("ImageUrl"); - - b.Property("LeaderId"); - - b.Property("Name"); - - b.Property("Public"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("JoinDate"); - - b.Property("Rank"); - - b.Property("UserId"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("EmoteCountFilter"); - - b.Property("FilterAllInv"); - - b.Property("FilterInvites"); - - b.Property("FilterMsgLength"); - - b.Property("FilterUrls"); - - b.Property("IgnoreAllChannels"); - - b.Property("MentionCountFilter"); - - b.Property("MuteRole"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("DesignChannel"); - - b.Property("EventChannel"); - - b.Property("EventSchedulerChannel"); - - b.Property("ModChannel"); - - b.Property("QuestionAndAnswerChannel"); - - b.Property("ReportChannel"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AdvertisementChannel"); - - b.Property("AutoPrune"); - - b.Property("ChannelCategory"); - - b.Property("ChannelRequiredAmount"); - - b.Property("ChannelRequiredLevel"); - - b.Property("EnableVoiceChannel"); - - b.Property("RoleEnabled"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("CurrencyName"); - - b.Property("CurrencySign"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName"); - - b.Property("SpecialCurrencySign"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ExpMultiplier"); - - b.Property("StackLvlRoles"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("LogAutoMod"); - - b.Property("LogAvi"); - - b.Property("LogBan"); - - b.Property("LogJoin"); - - b.Property("LogMsg"); - - b.Property("LogWarn"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("EmoteNo"); - - b.Property("EmoteYes"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AutoDelOnLeave"); - - b.Property("Banner"); - - b.Property("Channel"); - - b.Property("Limit"); - - b.Property("Message"); - - b.Property("TimeToDelete"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AnimeAirChannel"); - - b.Property("AutomaticEventSchedule"); - - b.Property("EmbedColor"); - - b.Property("MusicChannel"); - - b.Property("MusicVcChannel"); - - b.Property("Prefix"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ChannelId"); - - b.Property("MessageId"); - - b.Property("Multiplier"); - - b.Property("Time"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("Category"); - - b.Property("Channel"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId"); - - b.Property("Level"); - - b.Property("Role"); - - b.Property("Stackable"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.NudeServiceChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("InHouse"); - - b.Property("Tolerance"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("NudeServiceChannels"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Exclusive"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.SingleNudeServiceChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("InHouse"); - - b.Property("Level"); - - b.Property("Tolerance"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("SingleNudeServiceChannels"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.SpamIgnore", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("SpamIgnores"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.UrlFilter", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("UrlFilters"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId"); - - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("UploadTimeOffset"); - - b.Property("Uploader"); - - b.Property("Url"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Action"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("ModId"); - - b.Property("Response"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId"); - - b.Property("GuildId"); - - b.Property("Time"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Moderation.QuestionAndAnswer", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("QuestionAndAnswers"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Moderation.Report", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Attachment"); - - b.Property("Date"); - - b.Property("Message"); - - b.Property("MessageId"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Moderation.Warn", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Moderator") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("MuteTimer"); - - b.Property("Reason"); - - b.Property("Time"); - - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Valid"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BackgroundUrl"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Profile.ProfileConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Height"); - - b.Property("Name"); - - b.Property("NameWidth"); - - b.Property("Value"); - - b.Property("ValueWidth"); - - b.HasKey("Id"); - - b.ToTable("ProfileConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Price"); - - b.Property("SpecialCredit"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Addons.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Addons.Database.Tables.Achievement.AchievementDifficulty", "AchievementDifficulty") - .WithMany() - .HasForeignKey("DifficultyId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Addons.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("TypeId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Hanekawa.Addons.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Addons.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20190224222819_initial.cs b/Hanekawa.Database/Migrations/20190224222819_initial.cs deleted file mode 100644 index 9e24dcf4..00000000 --- a/Hanekawa.Database/Migrations/20190224222819_initial.cs +++ /dev/null @@ -1,1038 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class initial : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AccountGlobals", - columns: table => new - { - UserId = table.Column(nullable: false), - Level = table.Column(nullable: false), - Exp = table.Column(nullable: false), - TotalExp = table.Column(nullable: false), - Rep = table.Column(nullable: false), - Credit = table.Column(nullable: false), - StarReceive = table.Column(nullable: false), - StarGive = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AccountGlobals", x => x.UserId); - }); - - migrationBuilder.CreateTable( - name: "Accounts", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Active = table.Column(nullable: false), - Credit = table.Column(nullable: false), - CreditSpecial = table.Column(nullable: false), - DailyCredit = table.Column(nullable: false), - Level = table.Column(nullable: false), - Exp = table.Column(nullable: false), - TotalExp = table.Column(nullable: false), - VoiceExpTime = table.Column(nullable: false), - Class = table.Column(nullable: false), - ProfilePic = table.Column(nullable: true), - Rep = table.Column(nullable: false), - RepCooldown = table.Column(nullable: false), - GameKillAmount = table.Column(nullable: false), - FirstMessage = table.Column(nullable: true), - LastMessage = table.Column(nullable: false), - StatVoiceTime = table.Column(nullable: false), - Sessions = table.Column(nullable: false), - StatMessages = table.Column(nullable: false), - StarGiven = table.Column(nullable: false), - StarReceived = table.Column(nullable: false), - ChannelVoiceTime = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Accounts", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "AchievementDifficulties", - columns: table => new - { - DifficultyId = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AchievementDifficulties", x => x.DifficultyId); - }); - - migrationBuilder.CreateTable( - name: "AchievementNames", - columns: table => new - { - AchievementNameId = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true), - Description = table.Column(nullable: true), - Stackable = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AchievementNames", x => x.AchievementNameId); - }); - - migrationBuilder.CreateTable( - name: "AchievementTrackers", - columns: table => new - { - Type = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Count = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AchievementTrackers", x => new { x.Type, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "AchievementTypes", - columns: table => new - { - TypeId = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AchievementTypes", x => x.TypeId); - }); - - migrationBuilder.CreateTable( - name: "AdminConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - MuteRole = table.Column(nullable: true), - FilterInvites = table.Column(nullable: false), - IgnoreAllChannels = table.Column(nullable: false), - FilterMsgLength = table.Column(nullable: true), - FilterUrls = table.Column(nullable: false), - FilterAllInv = table.Column(nullable: false), - EmoteCountFilter = table.Column(nullable: true), - MentionCountFilter = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AdminConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "Backgrounds", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - BackgroundUrl = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Backgrounds", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Blacklists", - columns: table => new - { - GuildId = table.Column(nullable: false), - Reason = table.Column(nullable: true), - ResponsibleUser = table.Column(nullable: false), - Unban = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Blacklists", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "BoardConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - Emote = table.Column(nullable: true), - Channel = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_BoardConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "Boards", - columns: table => new - { - GuildId = table.Column(nullable: false), - MessageId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - StarAmount = table.Column(nullable: false), - Boarded = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Boards", x => new { x.GuildId, x.MessageId }); - }); - - migrationBuilder.CreateTable( - name: "ChannelConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - ReportChannel = table.Column(nullable: true), - EventChannel = table.Column(nullable: true), - EventSchedulerChannel = table.Column(nullable: true), - ModChannel = table.Column(nullable: true), - DesignChannel = table.Column(nullable: true), - QuestionAndAnswerChannel = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ChannelConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "ClubBlacklists", - columns: table => new - { - ClubId = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - BlackListUser = table.Column(nullable: false), - IssuedUser = table.Column(nullable: false), - Reason = table.Column(nullable: true), - Time = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ClubBlacklists", x => new { x.ClubId, x.GuildId, x.BlackListUser }); - }); - - migrationBuilder.CreateTable( - name: "ClubConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelCategory = table.Column(nullable: true), - AdvertisementChannel = table.Column(nullable: true), - EnableVoiceChannel = table.Column(nullable: false), - ChannelRequiredAmount = table.Column(nullable: false), - ChannelRequiredLevel = table.Column(nullable: false), - AutoPrune = table.Column(nullable: false), - RoleEnabled = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ClubConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "ClubInfos", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - GuildId = table.Column(nullable: false), - LeaderId = table.Column(nullable: false), - Name = table.Column(nullable: true), - Description = table.Column(nullable: true), - IconUrl = table.Column(nullable: true), - ImageUrl = table.Column(nullable: true), - Public = table.Column(nullable: false), - AutoAdd = table.Column(nullable: false), - AdMessage = table.Column(nullable: true), - Channel = table.Column(nullable: true), - Role = table.Column(nullable: true), - CreationDate = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ClubInfos", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "ClubPlayers", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - ClubId = table.Column(nullable: false), - Rank = table.Column(nullable: false), - JoinDate = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ClubPlayers", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "CurrencyConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - EmoteCurrency = table.Column(nullable: false, defaultValue: false), - CurrencyName = table.Column(nullable: true), - CurrencySign = table.Column(nullable: true), - SpecialEmoteCurrency = table.Column(nullable: false, defaultValue: false), - SpecialCurrencyName = table.Column(nullable: true), - SpecialCurrencySign = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_CurrencyConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "EventPayouts", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Amount = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EventPayouts", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "EventSchedules", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Host = table.Column(nullable: false), - DesignerClaim = table.Column(nullable: true), - Name = table.Column(nullable: true), - ImageUrl = table.Column(nullable: true), - Description = table.Column(nullable: true), - Time = table.Column(nullable: false), - Posted = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EventSchedules", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "GameClasses", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true), - LevelRequirement = table.Column(nullable: false), - ChanceAvoid = table.Column(nullable: false), - ChanceCrit = table.Column(nullable: false), - ModifierHealth = table.Column(nullable: false), - ModifierDamage = table.Column(nullable: false), - ModifierAvoidance = table.Column(nullable: false), - ModifierCriticalChance = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GameClasses", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "GameConfigs", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - DefaultHealth = table.Column(nullable: false), - DefaultDamage = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GameConfigs", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "GameEnemies", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true), - Elite = table.Column(nullable: false), - Rare = table.Column(nullable: false), - ImageUrl = table.Column(nullable: true), - Health = table.Column(nullable: false), - Damage = table.Column(nullable: false), - ClassId = table.Column(nullable: false), - ExpGain = table.Column(nullable: false), - CreditGain = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GameEnemies", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "GuildConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - Prefix = table.Column(nullable: true), - Premium = table.Column(nullable: false, defaultValue: false), - EmbedColor = table.Column(nullable: false), - AnimeAirChannel = table.Column(nullable: true), - AutomaticEventSchedule = table.Column(nullable: false), - MusicChannel = table.Column(nullable: true), - MusicVcChannel = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_GuildConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "IgnoreChannels", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_IgnoreChannels", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "Inventories", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - ItemId = table.Column(nullable: false), - Amount = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Inventories", x => new { x.GuildId, x.UserId, x.ItemId }); - }); - - migrationBuilder.CreateTable( - name: "Items", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - GuildId = table.Column(nullable: false), - Role = table.Column(nullable: false), - DateAdded = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Items", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "LevelConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - ExpMultiplier = table.Column(nullable: false), - StackLvlRoles = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_LevelConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "LevelExpEvents", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: true), - MessageId = table.Column(nullable: true), - Multiplier = table.Column(nullable: false), - Time = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_LevelExpEvents", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "LevelExpReductions", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false), - Channel = table.Column(nullable: false), - Category = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_LevelExpReductions", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "LevelRewards", - columns: table => new - { - GuildId = table.Column(nullable: false), - Level = table.Column(nullable: false), - Role = table.Column(nullable: false), - Stackable = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_LevelRewards", x => new { x.GuildId, x.Level }); - }); - - migrationBuilder.CreateTable( - name: "LoggingConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - LogJoin = table.Column(nullable: true), - LogMsg = table.Column(nullable: true), - LogBan = table.Column(nullable: true), - LogAvi = table.Column(nullable: true), - LogWarn = table.Column(nullable: true), - LogAutoMod = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_LoggingConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "LootChannels", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_LootChannels", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "ModLogs", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Action = table.Column(nullable: true), - MessageId = table.Column(nullable: false), - ModId = table.Column(nullable: true), - Response = table.Column(nullable: true), - Date = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ModLogs", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "MuteTimers", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Time = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MuteTimers", x => new { x.UserId, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "NudeServiceChannels", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false), - Tolerance = table.Column(nullable: false), - InHouse = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_NudeServiceChannels", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "ProfileConfigs", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true), - Value = table.Column(nullable: true), - Height = table.Column(nullable: false), - NameWidth = table.Column(nullable: false), - ValueWidth = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ProfileConfigs", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "QuestionAndAnswers", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Status = table.Column(nullable: false), - MessageId = table.Column(nullable: true), - ResponseUser = table.Column(nullable: true), - Response = table.Column(nullable: true), - Date = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_QuestionAndAnswers", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "Reports", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - MessageId = table.Column(nullable: true), - Status = table.Column(nullable: false), - Message = table.Column(nullable: true), - Attachment = table.Column(nullable: true), - Date = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Reports", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "SelfAssignAbleRoles", - columns: table => new - { - GuildId = table.Column(nullable: false), - RoleId = table.Column(nullable: false), - Exclusive = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_SelfAssignAbleRoles", x => new { x.GuildId, x.RoleId }); - }); - - migrationBuilder.CreateTable( - name: "ServerStores", - columns: table => new - { - GuildId = table.Column(nullable: false), - RoleId = table.Column(nullable: false), - Price = table.Column(nullable: false), - SpecialCredit = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ServerStores", x => new { x.GuildId, x.RoleId }); - }); - - migrationBuilder.CreateTable( - name: "SingleNudeServiceChannels", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false), - Level = table.Column(nullable: true), - Tolerance = table.Column(nullable: true), - InHouse = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_SingleNudeServiceChannels", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "SpamIgnores", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_SpamIgnores", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "SuggestionConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - Channel = table.Column(nullable: true), - EmoteYes = table.Column(nullable: true), - EmoteNo = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_SuggestionConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "Suggestions", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Status = table.Column(nullable: false), - MessageId = table.Column(nullable: true), - ResponseUser = table.Column(nullable: true), - Response = table.Column(nullable: true), - Date = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Suggestions", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "UrlFilters", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_UrlFilters", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "Warns", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Type = table.Column(nullable: false), - Reason = table.Column(nullable: true), - Time = table.Column(nullable: false), - Moderator = table.Column(nullable: false), - Valid = table.Column(nullable: false), - MuteTimer = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Warns", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "WelcomeBanners", - columns: table => new - { - GuildId = table.Column(nullable: false), - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Url = table.Column(nullable: true), - Uploader = table.Column(nullable: false), - UploadTimeOffset = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WelcomeBanners", x => new { x.GuildId, x.Id }); - }); - - migrationBuilder.CreateTable( - name: "WelcomeConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - Channel = table.Column(nullable: true), - Limit = table.Column(nullable: false), - Banner = table.Column(nullable: false), - Message = table.Column(nullable: true), - TimeToDelete = table.Column(nullable: true), - AutoDelOnLeave = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WelcomeConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "WhitelistDesigns", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WhitelistDesigns", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "WhitelistEvents", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WhitelistEvents", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "Achievements", - columns: table => new - { - AchievementId = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(nullable: true), - Description = table.Column(nullable: true), - Requirement = table.Column(nullable: false), - Once = table.Column(nullable: false), - Reward = table.Column(nullable: true), - Points = table.Column(nullable: false), - ImageUrl = table.Column(nullable: true), - Hidden = table.Column(nullable: false), - Global = table.Column(nullable: false), - AchievementNameId = table.Column(nullable: false), - TypeId = table.Column(nullable: false), - DifficultyId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Achievements", x => x.AchievementId); - table.ForeignKey( - name: "FK_Achievements_AchievementNames_AchievementNameId", - column: x => x.AchievementNameId, - principalTable: "AchievementNames", - principalColumn: "AchievementNameId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Achievements_AchievementDifficulties_DifficultyId", - column: x => x.DifficultyId, - principalTable: "AchievementDifficulties", - principalColumn: "DifficultyId", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Achievements_AchievementTypes_TypeId", - column: x => x.TypeId, - principalTable: "AchievementTypes", - principalColumn: "TypeId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AchievementUnlocks", - columns: table => new - { - AchievementId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - TypeId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AchievementUnlocks", x => new { x.AchievementId, x.UserId }); - table.ForeignKey( - name: "FK_AchievementUnlocks_Achievements_AchievementId", - column: x => x.AchievementId, - principalTable: "Achievements", - principalColumn: "AchievementId", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_Achievements_AchievementNameId", - table: "Achievements", - column: "AchievementNameId"); - - migrationBuilder.CreateIndex( - name: "IX_Achievements_DifficultyId", - table: "Achievements", - column: "DifficultyId"); - - migrationBuilder.CreateIndex( - name: "IX_Achievements_TypeId", - table: "Achievements", - column: "TypeId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AccountGlobals"); - - migrationBuilder.DropTable( - name: "Accounts"); - - migrationBuilder.DropTable( - name: "AchievementTrackers"); - - migrationBuilder.DropTable( - name: "AchievementUnlocks"); - - migrationBuilder.DropTable( - name: "AdminConfigs"); - - migrationBuilder.DropTable( - name: "Backgrounds"); - - migrationBuilder.DropTable( - name: "Blacklists"); - - migrationBuilder.DropTable( - name: "BoardConfigs"); - - migrationBuilder.DropTable( - name: "Boards"); - - migrationBuilder.DropTable( - name: "ChannelConfigs"); - - migrationBuilder.DropTable( - name: "ClubBlacklists"); - - migrationBuilder.DropTable( - name: "ClubConfigs"); - - migrationBuilder.DropTable( - name: "ClubInfos"); - - migrationBuilder.DropTable( - name: "ClubPlayers"); - - migrationBuilder.DropTable( - name: "CurrencyConfigs"); - - migrationBuilder.DropTable( - name: "EventPayouts"); - - migrationBuilder.DropTable( - name: "EventSchedules"); - - migrationBuilder.DropTable( - name: "GameClasses"); - - migrationBuilder.DropTable( - name: "GameConfigs"); - - migrationBuilder.DropTable( - name: "GameEnemies"); - - migrationBuilder.DropTable( - name: "GuildConfigs"); - - migrationBuilder.DropTable( - name: "IgnoreChannels"); - - migrationBuilder.DropTable( - name: "Inventories"); - - migrationBuilder.DropTable( - name: "Items"); - - migrationBuilder.DropTable( - name: "LevelConfigs"); - - migrationBuilder.DropTable( - name: "LevelExpEvents"); - - migrationBuilder.DropTable( - name: "LevelExpReductions"); - - migrationBuilder.DropTable( - name: "LevelRewards"); - - migrationBuilder.DropTable( - name: "LoggingConfigs"); - - migrationBuilder.DropTable( - name: "LootChannels"); - - migrationBuilder.DropTable( - name: "ModLogs"); - - migrationBuilder.DropTable( - name: "MuteTimers"); - - migrationBuilder.DropTable( - name: "NudeServiceChannels"); - - migrationBuilder.DropTable( - name: "ProfileConfigs"); - - migrationBuilder.DropTable( - name: "QuestionAndAnswers"); - - migrationBuilder.DropTable( - name: "Reports"); - - migrationBuilder.DropTable( - name: "SelfAssignAbleRoles"); - - migrationBuilder.DropTable( - name: "ServerStores"); - - migrationBuilder.DropTable( - name: "SingleNudeServiceChannels"); - - migrationBuilder.DropTable( - name: "SpamIgnores"); - - migrationBuilder.DropTable( - name: "SuggestionConfigs"); - - migrationBuilder.DropTable( - name: "Suggestions"); - - migrationBuilder.DropTable( - name: "UrlFilters"); - - migrationBuilder.DropTable( - name: "Warns"); - - migrationBuilder.DropTable( - name: "WelcomeBanners"); - - migrationBuilder.DropTable( - name: "WelcomeConfigs"); - - migrationBuilder.DropTable( - name: "WhitelistDesigns"); - - migrationBuilder.DropTable( - name: "WhitelistEvents"); - - migrationBuilder.DropTable( - name: "Achievements"); - - migrationBuilder.DropTable( - name: "AchievementNames"); - - migrationBuilder.DropTable( - name: "AchievementDifficulties"); - - migrationBuilder.DropTable( - name: "AchievementTypes"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20190507065249_LoggingUpdate.Designer.cs b/Hanekawa.Database/Migrations/20190507065249_LoggingUpdate.Designer.cs deleted file mode 100644 index 381fe7bf..00000000 --- a/Hanekawa.Database/Migrations/20190507065249_LoggingUpdate.Designer.cs +++ /dev/null @@ -1,1084 +0,0 @@ -// -using System; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20190507065249_LoggingUpdate")] - partial class LoggingUpdate - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .HasAnnotation("ProductVersion", "2.2.4-servicing-10062") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Active"); - - b.Property("ChannelVoiceTime"); - - b.Property("Class"); - - b.Property("Credit"); - - b.Property("CreditSpecial"); - - b.Property("DailyCredit"); - - b.Property("Exp"); - - b.Property("FirstMessage"); - - b.Property("GameKillAmount"); - - b.Property("LastMessage"); - - b.Property("Level"); - - b.Property("ProfilePic"); - - b.Property("Rep"); - - b.Property("RepCooldown"); - - b.Property("Sessions"); - - b.Property("StarGiven"); - - b.Property("StarReceived"); - - b.Property("StatMessages"); - - b.Property("StatVoiceTime"); - - b.Property("TotalExp"); - - b.Property("VoiceExpTime"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd(); - - b.Property("Credit"); - - b.Property("Exp"); - - b.Property("Level"); - - b.Property("Rep"); - - b.Property("StarGive"); - - b.Property("StarReceive"); - - b.Property("TotalExp"); - - b.Property("UserColor"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("ItemId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DateAdded"); - - b.Property("GuildId"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementDifficulty", b => - { - b.Property("DifficultyId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("DifficultyId"); - - b.ToTable("AchievementDifficulties"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd(); - - b.Property("AchievementNameId"); - - b.Property("Description"); - - b.Property("DifficultyId"); - - b.Property("Global"); - - b.Property("Hidden"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Once"); - - b.Property("Points"); - - b.Property("Requirement"); - - b.Property("Reward"); - - b.Property("TypeId"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("DifficultyId"); - - b.HasIndex("TypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd(); - - b.Property("Description"); - - b.Property("Name"); - - b.Property("Stackable"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Count"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId"); - - b.Property("UserId"); - - b.Property("TypeId"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Reason"); - - b.Property("ResponsibleUser"); - - b.Property("Unban"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.EventSchedule", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Description"); - - b.Property("DesignerClaim"); - - b.Property("Host"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Posted"); - - b.Property("Time"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("EventSchedules"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.WhitelistDesign", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("WhitelistDesigns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.WhitelistEvent", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("WhitelistEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId"); - - b.Property("MessageId"); - - b.Property("Boarded"); - - b.Property("StarAmount"); - - b.Property("UserId"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ChanceAvoid"); - - b.Property("ChanceCrit"); - - b.Property("LevelRequirement"); - - b.Property("ModifierAvoidance"); - - b.Property("ModifierCriticalChance"); - - b.Property("ModifierDamage"); - - b.Property("ModifierHealth"); - - b.Property("Name"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DefaultDamage"); - - b.Property("DefaultHealth"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClassId"); - - b.Property("CreditGain"); - - b.Property("Damage"); - - b.Property("Elite"); - - b.Property("ExpGain"); - - b.Property("Health"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Rare"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("BlackListUser"); - - b.Property("IssuedUser"); - - b.Property("Reason"); - - b.Property("Time"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("AdMessage"); - - b.Property("AutoAdd"); - - b.Property("Channel"); - - b.Property("CreationDate"); - - b.Property("Description"); - - b.Property("GuildId"); - - b.Property("IconUrl"); - - b.Property("ImageUrl"); - - b.Property("LeaderId"); - - b.Property("Name"); - - b.Property("Public"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("JoinDate"); - - b.Property("Rank"); - - b.Property("UserId"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("EmoteCountFilter"); - - b.Property("FilterAllInv"); - - b.Property("FilterInvites"); - - b.Property("FilterMsgLength"); - - b.Property("FilterUrls"); - - b.Property("IgnoreAllChannels"); - - b.Property("MentionCountFilter"); - - b.Property("MuteRole"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("DesignChannel"); - - b.Property("EventChannel"); - - b.Property("EventSchedulerChannel"); - - b.Property("ModChannel"); - - b.Property("QuestionAndAnswerChannel"); - - b.Property("ReportChannel"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AdvertisementChannel"); - - b.Property("AutoPrune"); - - b.Property("ChannelCategory"); - - b.Property("ChannelRequiredAmount"); - - b.Property("ChannelRequiredLevel"); - - b.Property("EnableVoiceChannel"); - - b.Property("RoleEnabled"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("CurrencyName"); - - b.Property("CurrencySign"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName"); - - b.Property("SpecialCurrencySign"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ExpMultiplier"); - - b.Property("StackLvlRoles"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("LogAutoMod"); - - b.Property("LogAvi"); - - b.Property("LogBan"); - - b.Property("LogJoin"); - - b.Property("LogMsg"); - - b.Property("LogVoice") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("LogWarn"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("EmoteNo"); - - b.Property("EmoteYes"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AutoDelOnLeave"); - - b.Property("Banner"); - - b.Property("Channel"); - - b.Property("Limit"); - - b.Property("Message"); - - b.Property("TimeToDelete"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AnimeAirChannel"); - - b.Property("AutomaticEventSchedule"); - - b.Property("EmbedColor"); - - b.Property("MusicChannel"); - - b.Property("MusicVcChannel"); - - b.Property("Prefix"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ChannelId"); - - b.Property("MessageId"); - - b.Property("Multiplier"); - - b.Property("Time"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("Category"); - - b.Property("Channel"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId"); - - b.Property("Level"); - - b.Property("Role"); - - b.Property("Stackable"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.NudeServiceChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("InHouse"); - - b.Property("Tolerance"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("NudeServiceChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Exclusive"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SingleNudeServiceChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("InHouse"); - - b.Property("Level"); - - b.Property("Tolerance"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("SingleNudeServiceChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SpamIgnore", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("SpamIgnores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.UrlFilter", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("UrlFilters"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId"); - - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("UploadTimeOffset"); - - b.Property("Uploader"); - - b.Property("Url"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("CallSite"); - - b.Property("Exception"); - - b.Property("Level"); - - b.Property("Logger"); - - b.Property("Message"); - - b.Property("TimeStamp"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Action"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("ModId"); - - b.Property("Response"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId"); - - b.Property("GuildId"); - - b.Property("Time"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.QuestionAndAnswer", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("QuestionAndAnswers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Attachment"); - - b.Property("Date"); - - b.Property("Message"); - - b.Property("MessageId"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Moderator") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("MuteTimer"); - - b.Property("Reason"); - - b.Property("Time"); - - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Valid"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BackgroundUrl"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.ProfileConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Height"); - - b.Property("Name"); - - b.Property("NameWidth"); - - b.Property("Value"); - - b.Property("ValueWidth"); - - b.HasKey("Id"); - - b.ToTable("ProfileConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Price"); - - b.Property("SpecialCredit"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementDifficulty", "AchievementDifficulty") - .WithMany() - .HasForeignKey("DifficultyId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("TypeId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20190507065249_LoggingUpdate.cs b/Hanekawa.Database/Migrations/20190507065249_LoggingUpdate.cs deleted file mode 100644 index 37c6c6b5..00000000 --- a/Hanekawa.Database/Migrations/20190507065249_LoggingUpdate.cs +++ /dev/null @@ -1,69 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class LoggingUpdate : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "LogVoice", - table: "LoggingConfigs", - nullable: true); - - migrationBuilder.AddColumn( - name: "UserColor", - table: "AccountGlobals", - nullable: false, - defaultValue: 0); - - migrationBuilder.CreateTable( - name: "DropConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - Emote = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_DropConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "Logs", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - TimeStamp = table.Column(nullable: true), - Level = table.Column(nullable: true), - Message = table.Column(nullable: true), - Logger = table.Column(nullable: true), - CallSite = table.Column(nullable: true), - Exception = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Logs", x => x.Id); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "DropConfigs"); - - migrationBuilder.DropTable( - name: "Logs"); - - migrationBuilder.DropColumn( - name: "LogVoice", - table: "LoggingConfigs"); - - migrationBuilder.DropColumn( - name: "UserColor", - table: "AccountGlobals"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20190609173946_UpdateBotRewriteTwo.Designer.cs b/Hanekawa.Database/Migrations/20190609173946_UpdateBotRewriteTwo.Designer.cs deleted file mode 100644 index cf7e8364..00000000 --- a/Hanekawa.Database/Migrations/20190609173946_UpdateBotRewriteTwo.Designer.cs +++ /dev/null @@ -1,1118 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20190609173946_UpdateBotRewriteTwo")] - partial class UpdateBotRewriteTwo - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .HasAnnotation("ProductVersion", "2.2.4-servicing-10062") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Active"); - - b.Property("ChannelVoiceTime"); - - b.Property("Class"); - - b.Property("Credit"); - - b.Property("CreditSpecial"); - - b.Property("DailyCredit"); - - b.Property("Exp"); - - b.Property("FirstMessage"); - - b.Property("GameKillAmount"); - - b.Property("LastMessage"); - - b.Property("Level"); - - b.Property("ProfilePic"); - - b.Property("Rep"); - - b.Property("RepCooldown"); - - b.Property("Sessions"); - - b.Property("StarGiven"); - - b.Property("StarReceived"); - - b.Property("StatMessages"); - - b.Property("StatVoiceTime"); - - b.Property("TotalExp"); - - b.Property("VoiceExpTime"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd(); - - b.Property("Credit"); - - b.Property("Exp"); - - b.Property("Level"); - - b.Property("Rep"); - - b.Property("StarGive"); - - b.Property("StarReceive"); - - b.Property("TotalExp"); - - b.Property("UserColor"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("ItemId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DateAdded"); - - b.Property("GuildId"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementDifficulty", b => - { - b.Property("DifficultyId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("DifficultyId"); - - b.ToTable("AchievementDifficulties"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd(); - - b.Property("AchievementNameId"); - - b.Property("Description"); - - b.Property("DifficultyId"); - - b.Property("Global"); - - b.Property("Hidden"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Once"); - - b.Property("Points"); - - b.Property("Requirement"); - - b.Property("Reward"); - - b.Property("TypeId"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("DifficultyId"); - - b.HasIndex("TypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd(); - - b.Property("Description"); - - b.Property("Name"); - - b.Property("Stackable"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Count"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId"); - - b.Property("UserId"); - - b.Property("TypeId"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Reason"); - - b.Property("ResponsibleUser"); - - b.Property("Unban"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.EventSchedule", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Description"); - - b.Property("DesignerClaim"); - - b.Property("Host"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Posted"); - - b.Property("Time"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("EventSchedules"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.WhitelistDesign", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("WhitelistDesigns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.WhitelistEvent", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("WhitelistEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId"); - - b.Property("MessageId"); - - b.Property("Boarded"); - - b.Property("StarAmount"); - - b.Property("UserId"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ChanceAvoid"); - - b.Property("ChanceCrit"); - - b.Property("LevelRequirement"); - - b.Property("ModifierAvoidance"); - - b.Property("ModifierCriticalChance"); - - b.Property("ModifierDamage"); - - b.Property("ModifierHealth"); - - b.Property("Name"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DefaultDamage"); - - b.Property("DefaultHealth"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClassId"); - - b.Property("CreditGain"); - - b.Property("Damage"); - - b.Property("Elite"); - - b.Property("ExpGain"); - - b.Property("Health"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Rare"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("BlackListUser"); - - b.Property("IssuedUser"); - - b.Property("Reason"); - - b.Property("Time"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("AdMessage"); - - b.Property("AutoAdd"); - - b.Property("Channel"); - - b.Property("CreationDate"); - - b.Property("Description"); - - b.Property("GuildId"); - - b.Property("IconUrl"); - - b.Property("ImageUrl"); - - b.Property("LeaderId"); - - b.Property("Name"); - - b.Property("Public"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("JoinDate"); - - b.Property("Rank"); - - b.Property("UserId"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("EmoteCountFilter"); - - b.Property("FilterAllInv"); - - b.Property("FilterInvites"); - - b.Property("FilterMsgLength"); - - b.Property("FilterUrls"); - - b.Property("IgnoreAllChannels"); - - b.Property("MentionCountFilter"); - - b.Property("MuteRole"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("DesignChannel"); - - b.Property("EventChannel"); - - b.Property("EventSchedulerChannel"); - - b.Property("ModChannel"); - - b.Property("QuestionAndAnswerChannel"); - - b.Property("ReportChannel"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AdvertisementChannel"); - - b.Property("AutoPrune"); - - b.Property("ChannelCategory"); - - b.Property("ChannelRequiredAmount"); - - b.Property("ChannelRequiredLevel"); - - b.Property("EnableVoiceChannel"); - - b.Property("RoleEnabled"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("CurrencyName"); - - b.Property("CurrencySign"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName"); - - b.Property("SpecialCurrencySign"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ExpMultiplier"); - - b.Property("StackLvlRoles"); - - b.Property("VoiceExpEnabled"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("LogAutoMod"); - - b.Property("LogAvi"); - - b.Property("LogBan"); - - b.Property("LogJoin"); - - b.Property("LogMsg"); - - b.Property("LogVoice") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("LogWarn"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("EmoteNo"); - - b.Property("EmoteYes"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AutoDelOnLeave"); - - b.Property("Banner"); - - b.Property("Channel"); - - b.Property("IgnoreNew"); - - b.Property("Limit"); - - b.Property("Message"); - - b.Property("TimeToDelete"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AnimeAirChannel"); - - b.Property("AutomaticEventSchedule"); - - b.Property("EmbedColor"); - - b.Property("MusicChannel"); - - b.Property("MusicVcChannel"); - - b.Property>("PrefixList"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ChannelId"); - - b.Property("MessageId"); - - b.Property("Multiplier"); - - b.Property("Time"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("Category"); - - b.Property("Channel"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId"); - - b.Property("Level"); - - b.Property("Role"); - - b.Property("Stackable"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.NudeServiceChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("InHouse"); - - b.Property("Tolerance"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("NudeServiceChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Exclusive"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SingleNudeServiceChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("InHouse"); - - b.Property("Level"); - - b.Property("Tolerance"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("SingleNudeServiceChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SpamIgnore", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("SpamIgnores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.UrlFilter", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("UrlFilters"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId"); - - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("IsNsfw"); - - b.Property("UploadTimeOffset"); - - b.Property("Uploader"); - - b.Property("Url"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("CallSite"); - - b.Property("Exception"); - - b.Property("Level"); - - b.Property("Logger"); - - b.Property("Message"); - - b.Property("TimeStamp"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Action"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("ModId"); - - b.Property("Response"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId"); - - b.Property("GuildId"); - - b.Property("Time"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.QuestionAndAnswer", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("QuestionAndAnswers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Attachment"); - - b.Property("Date"); - - b.Property("Message"); - - b.Property("MessageId"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Moderator") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("MuteTimer"); - - b.Property("Reason"); - - b.Property("Time"); - - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Valid"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("TextChId"); - - b.Property("VoiceChId"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId"); - - b.Property("Name"); - - b.Property>("Songs"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BackgroundUrl"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.ProfileConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("Height"); - - b.Property("Name"); - - b.Property("NameWidth"); - - b.Property("Value"); - - b.Property("ValueWidth"); - - b.HasKey("Id"); - - b.ToTable("ProfileConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Price"); - - b.Property("SpecialCredit"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementDifficulty", "AchievementDifficulty") - .WithMany() - .HasForeignKey("DifficultyId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("TypeId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20190609173946_UpdateBotRewriteTwo.cs b/Hanekawa.Database/Migrations/20190609173946_UpdateBotRewriteTwo.cs deleted file mode 100644 index 8e359439..00000000 --- a/Hanekawa.Database/Migrations/20190609173946_UpdateBotRewriteTwo.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Hanekawa.Database.Migrations -{ - public partial class UpdateBotRewriteTwo : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Prefix", - table: "GuildConfigs"); - - migrationBuilder.AddColumn( - name: "IgnoreNew", - table: "WelcomeConfigs", - nullable: true); - - migrationBuilder.AddColumn( - name: "IsNsfw", - table: "WelcomeBanners", - nullable: false, - defaultValue: false); - - migrationBuilder.AlterColumn( - name: "ExpMultiplier", - table: "LevelConfigs", - nullable: false, - oldClrType: typeof(int)); - - migrationBuilder.AddColumn( - name: "VoiceExpEnabled", - table: "LevelConfigs", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn>( - name: "PrefixList", - table: "GuildConfigs", - nullable: true); - - migrationBuilder.CreateTable( - name: "MusicConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - TextChId = table.Column(nullable: true), - VoiceChId = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_MusicConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "Playlists", - columns: table => new - { - GuildId = table.Column(nullable: false), - Name = table.Column(nullable: false), - Songs = table.Column>(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Playlists", x => new { x.GuildId, x.Name }); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "MusicConfigs"); - - migrationBuilder.DropTable( - name: "Playlists"); - - migrationBuilder.DropColumn( - name: "IgnoreNew", - table: "WelcomeConfigs"); - - migrationBuilder.DropColumn( - name: "IsNsfw", - table: "WelcomeBanners"); - - migrationBuilder.DropColumn( - name: "VoiceExpEnabled", - table: "LevelConfigs"); - - migrationBuilder.DropColumn( - name: "PrefixList", - table: "GuildConfigs"); - - migrationBuilder.AlterColumn( - name: "ExpMultiplier", - table: "LevelConfigs", - nullable: false, - oldClrType: typeof(double)); - - migrationBuilder.AddColumn( - name: "Prefix", - table: "GuildConfigs", - nullable: true); - } - } -} diff --git a/Hanekawa.Database/Migrations/20190814114059_UpdateBotRewriteThree.Designer.cs b/Hanekawa.Database/Migrations/20190814114059_UpdateBotRewriteThree.Designer.cs deleted file mode 100644 index a2dbd1e5..00000000 --- a/Hanekawa.Database/Migrations/20190814114059_UpdateBotRewriteThree.Designer.cs +++ /dev/null @@ -1,1029 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20190814114059_UpdateBotRewriteThree")] - partial class UpdateBotRewriteThree - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) - .HasAnnotation("ProductVersion", "2.2.6-servicing-10079") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Active"); - - b.Property("ChannelVoiceTime"); - - b.Property("Class"); - - b.Property("Credit"); - - b.Property("CreditSpecial"); - - b.Property("DailyCredit"); - - b.Property("Exp"); - - b.Property("FirstMessage"); - - b.Property("GameKillAmount"); - - b.Property("LastMessage"); - - b.Property("Level"); - - b.Property("ProfilePic"); - - b.Property("Rep"); - - b.Property("RepCooldown"); - - b.Property("Sessions"); - - b.Property("StarGiven"); - - b.Property("StarReceived"); - - b.Property("StatMessages"); - - b.Property("StatVoiceTime"); - - b.Property("TotalExp"); - - b.Property("VoiceExpTime"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd(); - - b.Property("Credit"); - - b.Property("Exp"); - - b.Property("Level"); - - b.Property("Rep"); - - b.Property("StarGive"); - - b.Property("StarReceive"); - - b.Property("TotalExp"); - - b.Property("UserColor"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Highlights"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("ItemId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("CriticalIncrease"); - - b.Property("DamageIncrease"); - - b.Property("DateAdded"); - - b.Property("GuildId"); - - b.Property("HealthIncrease"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Role"); - - b.Property("Sell"); - - b.Property("Type") - .IsRequired(); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementDifficulty", b => - { - b.Property("DifficultyId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("DifficultyId"); - - b.ToTable("AchievementDifficulties"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd(); - - b.Property("AchievementNameId"); - - b.Property("Description"); - - b.Property("DifficultyId"); - - b.Property("Global"); - - b.Property("Hidden"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Once"); - - b.Property("Points"); - - b.Property("Requirement"); - - b.Property("Reward"); - - b.Property("TypeId"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("DifficultyId"); - - b.HasIndex("TypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd(); - - b.Property("Description"); - - b.Property("Name"); - - b.Property("Stackable"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Count"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd(); - - b.Property("Name"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId"); - - b.Property("UserId"); - - b.Property("TypeId"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("GuildId"); - - b.Property("Type"); - - b.Property("UploadTimeOffset"); - - b.Property("Uploader"); - - b.Property("Url"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Reason"); - - b.Property("ResponsibleUser"); - - b.Property("Unban"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId"); - - b.Property("MessageId"); - - b.Property("Boarded"); - - b.Property("StarAmount"); - - b.Property("UserId"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ChanceAvoid"); - - b.Property("ChanceCrit"); - - b.Property("LevelRequirement"); - - b.Property("ModifierAvoidance"); - - b.Property("ModifierCriticalChance"); - - b.Property("ModifierDamage"); - - b.Property("ModifierHealth"); - - b.Property("Name"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("DefaultDamage"); - - b.Property("DefaultHealth"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClassId"); - - b.Property("CreditGain"); - - b.Property("Damage"); - - b.Property("Elite"); - - b.Property("ExpGain"); - - b.Property("Health"); - - b.Property("ImageUrl"); - - b.Property("Name"); - - b.Property("Rare"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("BlackListUser"); - - b.Property("IssuedUser"); - - b.Property("Reason"); - - b.Property("Time"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("AdMessage"); - - b.Property("AutoAdd"); - - b.Property("Channel"); - - b.Property("CreationDate"); - - b.Property("Description"); - - b.Property("GuildId"); - - b.Property("IconUrl"); - - b.Property("ImageUrl"); - - b.Property("LeaderId"); - - b.Property("Name"); - - b.Property("Public"); - - b.Property("Role"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("ClubId"); - - b.Property("GuildId"); - - b.Property("JoinDate"); - - b.Property("Rank"); - - b.Property("UserId"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId"); - - b.Property("UserId"); - - b.Property("Amount"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("EmoteCountFilter"); - - b.Property("FilterAllInv"); - - b.Property("FilterInvites"); - - b.Property("FilterMsgLength"); - - b.Property("FilterUrls"); - - b.Property("IgnoreAllChannels"); - - b.Property("MentionCountFilter"); - - b.Property("MuteRole"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("DesignChannel"); - - b.Property("EventChannel"); - - b.Property("EventSchedulerChannel"); - - b.Property("ModChannel"); - - b.Property("QuestionAndAnswerChannel"); - - b.Property("ReportChannel"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AdvertisementChannel"); - - b.Property("AutoPrune"); - - b.Property("ChannelCategory"); - - b.Property("ChannelRequiredAmount"); - - b.Property("ChannelRequiredLevel"); - - b.Property("EnableVoiceChannel"); - - b.Property("RoleEnabled"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("CurrencyName"); - - b.Property("CurrencySign"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName"); - - b.Property("SpecialCurrencySign"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Emote"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ExpDisabled"); - - b.Property("StackLvlRoles"); - - b.Property("TextExpEnabled"); - - b.Property("TextExpMultiplier"); - - b.Property("VoiceExpEnabled"); - - b.Property("VoiceExpMultiplier"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("LogAutoMod"); - - b.Property("LogAvi"); - - b.Property("LogBan"); - - b.Property("LogJoin"); - - b.Property("LogMsg"); - - b.Property("LogVoice") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("LogWarn"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("Channel"); - - b.Property("EmoteNo"); - - b.Property("EmoteYes"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AutoDelOnLeave"); - - b.Property("Banner"); - - b.Property("Channel"); - - b.Property("IgnoreNew"); - - b.Property("Limit"); - - b.Property("Message"); - - b.Property("Reward"); - - b.Property("TimeToDelete"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("AnimeAirChannel"); - - b.Property("AutomaticEventSchedule"); - - b.Property("EmbedColor"); - - b.Property("MusicChannel"); - - b.Property("MusicVcChannel"); - - b.Property("Prefix"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("ChannelId"); - - b.Property("MessageId"); - - b.Property("Multiplier"); - - b.Property("Time"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.Property("ChannelType") - .IsRequired(); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId"); - - b.Property("Level"); - - b.Property("Role"); - - b.Property("Stackable"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId"); - - b.Property("ChannelId"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Exclusive"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId"); - - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("IsNsfw"); - - b.Property("UploadTimeOffset"); - - b.Property("Uploader"); - - b.Property("Url"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("CallSite"); - - b.Property("Exception"); - - b.Property("Level"); - - b.Property("Logger"); - - b.Property("Message"); - - b.Property("TimeStamp"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Action"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("ModId"); - - b.Property("Response"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId"); - - b.Property("GuildId"); - - b.Property("Time"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Attachment"); - - b.Property("Date"); - - b.Property("Message"); - - b.Property("MessageId"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Date"); - - b.Property("MessageId"); - - b.Property("Response"); - - b.Property("ResponseUser"); - - b.Property("Status"); - - b.Property("UserId"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id"); - - b.Property("GuildId"); - - b.Property("Moderator") - .HasConversion(new ValueConverter(v => default(decimal), v => default(decimal), new ConverterMappingHints(precision: 20, scale: 0))); - - b.Property("MuteTimer"); - - b.Property("Reason"); - - b.Property("Time"); - - b.Property("Type"); - - b.Property("UserId"); - - b.Property("Valid"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd(); - - b.Property("TextChId"); - - b.Property("VoiceChId"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId"); - - b.Property("Name"); - - b.Property>("Songs"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd(); - - b.Property("BackgroundUrl"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId"); - - b.Property("RoleId"); - - b.Property("Price"); - - b.Property("SpecialCredit"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementDifficulty", "AchievementDifficulty") - .WithMany() - .HasForeignKey("DifficultyId") - .OnDelete(DeleteBehavior.Cascade); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("TypeId") - .OnDelete(DeleteBehavior.Cascade); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20190814114059_UpdateBotRewriteThree.cs b/Hanekawa.Database/Migrations/20190814114059_UpdateBotRewriteThree.cs deleted file mode 100644 index 7285cd50..00000000 --- a/Hanekawa.Database/Migrations/20190814114059_UpdateBotRewriteThree.cs +++ /dev/null @@ -1,413 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class UpdateBotRewriteThree : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "EventSchedules"); - - migrationBuilder.DropTable( - name: "NudeServiceChannels"); - - migrationBuilder.DropTable( - name: "ProfileConfigs"); - - migrationBuilder.DropTable( - name: "QuestionAndAnswers"); - - migrationBuilder.DropTable( - name: "SingleNudeServiceChannels"); - - migrationBuilder.DropTable( - name: "SpamIgnores"); - - migrationBuilder.DropTable( - name: "UrlFilters"); - - migrationBuilder.DropTable( - name: "WhitelistDesigns"); - - migrationBuilder.DropTable( - name: "WhitelistEvents"); - - migrationBuilder.DropColumn( - name: "Category", - table: "LevelExpReductions"); - - migrationBuilder.DropColumn( - name: "Channel", - table: "LevelExpReductions"); - - migrationBuilder.DropColumn( - name: "PrefixList", - table: "GuildConfigs"); - - migrationBuilder.RenameColumn( - name: "ExpMultiplier", - table: "LevelConfigs", - newName: "VoiceExpMultiplier"); - - migrationBuilder.AddColumn( - name: "Reward", - table: "WelcomeConfigs", - nullable: true); - - migrationBuilder.AddColumn( - name: "ChannelType", - table: "LevelExpReductions", - nullable: false, - defaultValue: ""); - - migrationBuilder.AlterColumn( - name: "Multiplier", - table: "LevelExpEvents", - nullable: false, - oldClrType: typeof(int)); - - migrationBuilder.AddColumn( - name: "ExpDisabled", - table: "LevelConfigs", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn( - name: "TextExpEnabled", - table: "LevelConfigs", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn( - name: "TextExpMultiplier", - table: "LevelConfigs", - nullable: false, - defaultValue: 0.0); - - migrationBuilder.AlterColumn( - name: "Role", - table: "Items", - nullable: true, - oldClrType: typeof(long)); - - migrationBuilder.AlterColumn( - name: "GuildId", - table: "Items", - nullable: true, - oldClrType: typeof(long)); - - migrationBuilder.AddColumn( - name: "CriticalIncrease", - table: "Items", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "DamageIncrease", - table: "Items", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "HealthIncrease", - table: "Items", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "ImageUrl", - table: "Items", - nullable: true); - - migrationBuilder.AddColumn( - name: "Name", - table: "Items", - nullable: true); - - migrationBuilder.AddColumn( - name: "Sell", - table: "Items", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "Type", - table: "Items", - nullable: false, - defaultValue: ""); - - migrationBuilder.AddColumn( - name: "Prefix", - table: "GuildConfigs", - nullable: true); - - migrationBuilder.CreateTable( - name: "ApprovalQueues", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - GuildId = table.Column(nullable: false), - Uploader = table.Column(nullable: false), - Url = table.Column(nullable: true), - Type = table.Column(nullable: false), - UploadTimeOffset = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ApprovalQueues", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "Highlights", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Highlights = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Highlights", x => new { x.GuildId, x.UserId }); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "ApprovalQueues"); - - migrationBuilder.DropTable( - name: "Highlights"); - - migrationBuilder.DropColumn( - name: "Reward", - table: "WelcomeConfigs"); - - migrationBuilder.DropColumn( - name: "ChannelType", - table: "LevelExpReductions"); - - migrationBuilder.DropColumn( - name: "ExpDisabled", - table: "LevelConfigs"); - - migrationBuilder.DropColumn( - name: "TextExpEnabled", - table: "LevelConfigs"); - - migrationBuilder.DropColumn( - name: "TextExpMultiplier", - table: "LevelConfigs"); - - migrationBuilder.DropColumn( - name: "CriticalIncrease", - table: "Items"); - - migrationBuilder.DropColumn( - name: "DamageIncrease", - table: "Items"); - - migrationBuilder.DropColumn( - name: "HealthIncrease", - table: "Items"); - - migrationBuilder.DropColumn( - name: "ImageUrl", - table: "Items"); - - migrationBuilder.DropColumn( - name: "Name", - table: "Items"); - - migrationBuilder.DropColumn( - name: "Sell", - table: "Items"); - - migrationBuilder.DropColumn( - name: "Type", - table: "Items"); - - migrationBuilder.DropColumn( - name: "Prefix", - table: "GuildConfigs"); - - migrationBuilder.RenameColumn( - name: "VoiceExpMultiplier", - table: "LevelConfigs", - newName: "ExpMultiplier"); - - migrationBuilder.AddColumn( - name: "Category", - table: "LevelExpReductions", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn( - name: "Channel", - table: "LevelExpReductions", - nullable: false, - defaultValue: false); - - migrationBuilder.AlterColumn( - name: "Multiplier", - table: "LevelExpEvents", - nullable: false, - oldClrType: typeof(double)); - - migrationBuilder.AlterColumn( - name: "Role", - table: "Items", - nullable: false, - oldClrType: typeof(long), - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "GuildId", - table: "Items", - nullable: false, - oldClrType: typeof(long), - oldNullable: true); - - migrationBuilder.AddColumn>( - name: "PrefixList", - table: "GuildConfigs", - nullable: true); - - migrationBuilder.CreateTable( - name: "EventSchedules", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Description = table.Column(nullable: true), - DesignerClaim = table.Column(nullable: true), - Host = table.Column(nullable: false), - ImageUrl = table.Column(nullable: true), - Name = table.Column(nullable: true), - Posted = table.Column(nullable: false), - Time = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_EventSchedules", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "NudeServiceChannels", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false), - InHouse = table.Column(nullable: false), - Tolerance = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_NudeServiceChannels", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "ProfileConfigs", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Height = table.Column(nullable: false), - Name = table.Column(nullable: true), - NameWidth = table.Column(nullable: false), - Value = table.Column(nullable: true), - ValueWidth = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ProfileConfigs", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "QuestionAndAnswers", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Date = table.Column(nullable: false), - MessageId = table.Column(nullable: true), - Response = table.Column(nullable: true), - ResponseUser = table.Column(nullable: true), - Status = table.Column(nullable: false), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_QuestionAndAnswers", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "SingleNudeServiceChannels", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false), - InHouse = table.Column(nullable: false), - Level = table.Column(nullable: true), - Tolerance = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_SingleNudeServiceChannels", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "SpamIgnores", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_SpamIgnores", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "UrlFilters", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_UrlFilters", x => new { x.GuildId, x.ChannelId }); - }); - - migrationBuilder.CreateTable( - name: "WhitelistDesigns", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WhitelistDesigns", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "WhitelistEvents", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WhitelistEvents", x => new { x.GuildId, x.UserId }); - }); - } - } -} diff --git a/Hanekawa.Database/Migrations/20200818133804_AddedHungerGameAndMvp.Designer.cs b/Hanekawa.Database/Migrations/20200818133804_AddedHungerGameAndMvp.Designer.cs deleted file mode 100644 index f271c761..00000000 --- a/Hanekawa.Database/Migrations/20200818133804_AddedHungerGameAndMvp.Designer.cs +++ /dev/null @@ -1,1526 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200818133804_AddedHungerGameAndMvp")] - partial class AddedHungerGameAndMvp - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.6") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200818133804_AddedHungerGameAndMvp.cs b/Hanekawa.Database/Migrations/20200818133804_AddedHungerGameAndMvp.cs deleted file mode 100644 index 3431d559..00000000 --- a/Hanekawa.Database/Migrations/20200818133804_AddedHungerGameAndMvp.cs +++ /dev/null @@ -1,343 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class AddedHungerGameAndMvp : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Achievements_AchievementDifficulties_DifficultyId", - table: "Achievements"); - - migrationBuilder.DropForeignKey( - name: "FK_Achievements_AchievementTypes_TypeId", - table: "Achievements"); - - migrationBuilder.DropTable( - name: "AchievementDifficulties"); - - migrationBuilder.DropIndex( - name: "IX_Achievements_DifficultyId", - table: "Achievements"); - - migrationBuilder.DropIndex( - name: "IX_Achievements_TypeId", - table: "Achievements"); - - migrationBuilder.DropColumn( - name: "DifficultyId", - table: "Achievements"); - - migrationBuilder.AddColumn( - name: "HungerGameChannel", - table: "GuildConfigs", - nullable: true); - - migrationBuilder.AddColumn( - name: "MvpChannel", - table: "GuildConfigs", - nullable: true); - - migrationBuilder.AlterColumn( - name: "Type", - table: "ApprovalQueues", - nullable: false, - oldClrType: typeof(int), - oldType: "integer"); - - migrationBuilder.AddColumn( - name: "AchievementDifficulty", - table: "Achievements", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "AchievementTypeTypeId", - table: "Achievements", - nullable: true); - - migrationBuilder.AddColumn( - name: "MvpCount", - table: "Accounts", - nullable: false, - defaultValue: 0); - - migrationBuilder.AddColumn( - name: "MvpOptOut", - table: "Accounts", - nullable: false, - defaultValue: false); - - migrationBuilder.CreateTable( - name: "GameHistory", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - GuildId = table.Column(nullable: false), - Winner = table.Column(nullable: true), - Active = table.Column(nullable: false), - Start = table.Column(nullable: false), - End = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_GameHistory", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HgItems", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Name = table.Column(nullable: true), - Amount = table.Column(nullable: false), - GiveOrTake = table.Column(nullable: false), - Ammo = table.Column(nullable: false), - BleedEffect = table.Column(nullable: false), - HealOverTime = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HgItems", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HgParticipants", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Name = table.Column(nullable: true), - Avatar = table.Column(nullable: true), - Alive = table.Column(nullable: false), - Health = table.Column(nullable: false), - Stamina = table.Column(nullable: false), - Hunger = table.Column(nullable: false), - Thirst = table.Column(nullable: false), - Tiredness = table.Column(nullable: false), - Bleeding = table.Column(nullable: false), - LatestMove = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HgParticipants", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "MvpConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - Day = table.Column(nullable: false), - RoleId = table.Column(nullable: true), - Count = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_MvpConfigs", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "HgInventories", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - UserGuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Count = table.Column(nullable: false), - ItemId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HgInventories", x => x.Id); - table.ForeignKey( - name: "FK_HgInventories_HgItems_ItemId", - column: x => x.ItemId, - principalTable: "HgItems", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_HgInventories_HgParticipants_UserGuildId_UserId", - columns: x => new { x.UserGuildId, x.UserId }, - principalTable: "HgParticipants", - principalColumns: new[] { "GuildId", "UserId" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.InsertData( - table: "Backgrounds", - columns: new[] { "Id", "BackgroundUrl" }, - values: new object[,] - { - { 1, "https://i.imgur.com/epIb29P.png" }, - { 2, "https://i.imgur.com/04PbzvT.png" }, - { 3, "https://i.imgur.com/5ojmh76.png" }, - { 4, "https://i.imgur.com/OAMpNDh.png" }, - { 5, "https://i.imgur.com/KXO5bx5.png" }, - { 6, "https://i.imgur.com/5h5zZ7C.png" } - }); - - migrationBuilder.CreateIndex( - name: "IX_Achievements_AchievementTypeTypeId", - table: "Achievements", - column: "AchievementTypeTypeId"); - - migrationBuilder.CreateIndex( - name: "IX_HgInventories_ItemId", - table: "HgInventories", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_HgInventories_UserGuildId_UserId", - table: "HgInventories", - columns: new[] { "UserGuildId", "UserId" }); - - migrationBuilder.AddForeignKey( - name: "FK_Achievements_AchievementTypes_AchievementTypeTypeId", - table: "Achievements", - column: "AchievementTypeTypeId", - principalTable: "AchievementTypes", - principalColumn: "TypeId", - onDelete: ReferentialAction.Restrict); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Achievements_AchievementTypes_AchievementTypeTypeId", - table: "Achievements"); - - migrationBuilder.DropTable( - name: "GameHistory"); - - migrationBuilder.DropTable( - name: "HgInventories"); - - migrationBuilder.DropTable( - name: "MvpConfigs"); - - migrationBuilder.DropTable( - name: "HgItems"); - - migrationBuilder.DropTable( - name: "HgParticipants"); - - migrationBuilder.DropIndex( - name: "IX_Achievements_AchievementTypeTypeId", - table: "Achievements"); - - migrationBuilder.DeleteData( - table: "Backgrounds", - keyColumn: "Id", - keyValue: 1); - - migrationBuilder.DeleteData( - table: "Backgrounds", - keyColumn: "Id", - keyValue: 2); - - migrationBuilder.DeleteData( - table: "Backgrounds", - keyColumn: "Id", - keyValue: 3); - - migrationBuilder.DeleteData( - table: "Backgrounds", - keyColumn: "Id", - keyValue: 4); - - migrationBuilder.DeleteData( - table: "Backgrounds", - keyColumn: "Id", - keyValue: 5); - - migrationBuilder.DeleteData( - table: "Backgrounds", - keyColumn: "Id", - keyValue: 6); - - migrationBuilder.DropColumn( - name: "HungerGameChannel", - table: "GuildConfigs"); - - migrationBuilder.DropColumn( - name: "MvpChannel", - table: "GuildConfigs"); - - migrationBuilder.DropColumn( - name: "AchievementDifficulty", - table: "Achievements"); - - migrationBuilder.DropColumn( - name: "AchievementTypeTypeId", - table: "Achievements"); - - migrationBuilder.DropColumn( - name: "MvpCount", - table: "Accounts"); - - migrationBuilder.DropColumn( - name: "MvpOptOut", - table: "Accounts"); - - migrationBuilder.AlterColumn( - name: "Type", - table: "ApprovalQueues", - type: "integer", - nullable: false, - oldClrType: typeof(string)); - - migrationBuilder.AddColumn( - name: "DifficultyId", - table: "Achievements", - type: "integer", - nullable: false, - defaultValue: 0); - - migrationBuilder.CreateTable( - name: "AchievementDifficulties", - columns: table => new - { - DifficultyId = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn), - Name = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AchievementDifficulties", x => x.DifficultyId); - }); - - migrationBuilder.CreateIndex( - name: "IX_Achievements_DifficultyId", - table: "Achievements", - column: "DifficultyId"); - - migrationBuilder.CreateIndex( - name: "IX_Achievements_TypeId", - table: "Achievements", - column: "TypeId"); - - migrationBuilder.AddForeignKey( - name: "FK_Achievements_AchievementDifficulties_DifficultyId", - table: "Achievements", - column: "DifficultyId", - principalTable: "AchievementDifficulties", - principalColumn: "DifficultyId", - onDelete: ReferentialAction.Cascade); - - migrationBuilder.AddForeignKey( - name: "FK_Achievements_AchievementTypes_TypeId", - table: "Achievements", - column: "TypeId", - principalTable: "AchievementTypes", - principalColumn: "TypeId", - onDelete: ReferentialAction.Cascade); - } - } -} diff --git a/Hanekawa.Database/Migrations/20200825144503_VoiceRole.Designer.cs b/Hanekawa.Database/Migrations/20200825144503_VoiceRole.Designer.cs deleted file mode 100644 index b571c7b3..00000000 --- a/Hanekawa.Database/Migrations/20200825144503_VoiceRole.Designer.cs +++ /dev/null @@ -1,1542 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200825144503_VoiceRole")] - partial class VoiceRole - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200825144503_VoiceRole.cs b/Hanekawa.Database/Migrations/20200825144503_VoiceRole.cs deleted file mode 100644 index 7e15d142..00000000 --- a/Hanekawa.Database/Migrations/20200825144503_VoiceRole.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Hanekawa.Database.Migrations -{ - public partial class VoiceRole : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "VoiceRoles", - columns: table => new - { - GuildId = table.Column(nullable: false), - VoiceId = table.Column(nullable: false), - RoleId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_VoiceRoles", x => new { x.GuildId, x.VoiceId }); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "VoiceRoles"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20200901214406_self-assignable-rework.Designer.cs b/Hanekawa.Database/Migrations/20200901214406_self-assignable-rework.Designer.cs deleted file mode 100644 index f73c446e..00000000 --- a/Hanekawa.Database/Migrations/20200901214406_self-assignable-rework.Designer.cs +++ /dev/null @@ -1,1554 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200901214406_self-assignable-rework")] - partial class selfassignablerework - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200901214406_self-assignable-rework.cs b/Hanekawa.Database/Migrations/20200901214406_self-assignable-rework.cs deleted file mode 100644 index 9cb02f98..00000000 --- a/Hanekawa.Database/Migrations/20200901214406_self-assignable-rework.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Hanekawa.Database.Migrations -{ - public partial class selfassignablerework : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "EmoteMessageFormat", - table: "SelfAssignAbleRoles", - nullable: true); - - migrationBuilder.AddColumn( - name: "EmoteReactFormat", - table: "SelfAssignAbleRoles", - nullable: true); - - migrationBuilder.AddColumn( - name: "SelfAssignableChannel", - table: "ChannelConfigs", - nullable: true); - - migrationBuilder.AddColumn( - name: "SelfAssignableMessages", - table: "ChannelConfigs", - nullable: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "EmoteMessageFormat", - table: "SelfAssignAbleRoles"); - - migrationBuilder.DropColumn( - name: "EmoteReactFormat", - table: "SelfAssignAbleRoles"); - - migrationBuilder.DropColumn( - name: "SelfAssignableChannel", - table: "ChannelConfigs"); - - migrationBuilder.DropColumn( - name: "SelfAssignableMessages", - table: "ChannelConfigs"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20200904185231_boost.Designer.cs b/Hanekawa.Database/Migrations/20200904185231_boost.Designer.cs deleted file mode 100644 index 4fa5505b..00000000 --- a/Hanekawa.Database/Migrations/20200904185231_boost.Designer.cs +++ /dev/null @@ -1,1585 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200904185231_boost")] - partial class boost - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200904185231_boost.cs b/Hanekawa.Database/Migrations/20200904185231_boost.cs deleted file mode 100644 index 31aa885d..00000000 --- a/Hanekawa.Database/Migrations/20200904185231_boost.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class boost : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "BoostExpMultiplier", - table: "LevelConfigs", - nullable: false, - defaultValue: 1.0); - - migrationBuilder.CreateTable( - name: "BoostConfigs", - columns: table => new - { - GuildId = table.Column(nullable: false), - ChannelId = table.Column(nullable: true), - Message = table.Column(nullable: true), - CreditGain = table.Column(nullable: false), - SpecialCreditGain = table.Column(nullable: false), - ExpGain = table.Column(nullable: false) - }, - constraints: table => { table.PrimaryKey("PK_BoostConfigs", x => x.GuildId); }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "BoostConfigs"); - - migrationBuilder.DropColumn( - name: "BoostExpMultiplier", - table: "LevelConfigs"); - } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Migrations/20200904194551_MvpTweak.Designer.cs b/Hanekawa.Database/Migrations/20200904194551_MvpTweak.Designer.cs deleted file mode 100644 index 8fe71395..00000000 --- a/Hanekawa.Database/Migrations/20200904194551_MvpTweak.Designer.cs +++ /dev/null @@ -1,1590 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200904194551_MvpTweak")] - partial class MvpTweak - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200904194551_MvpTweak.cs b/Hanekawa.Database/Migrations/20200904194551_MvpTweak.cs deleted file mode 100644 index 07b29ab6..00000000 --- a/Hanekawa.Database/Migrations/20200904194551_MvpTweak.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class MvpTweak : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "Disabled", - table: "MvpConfigs", - nullable: false, - defaultValue: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "Disabled", - table: "MvpConfigs"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20200906103600_DblVoteRewards.Designer.cs b/Hanekawa.Database/Migrations/20200906103600_DblVoteRewards.Designer.cs deleted file mode 100644 index baea49c7..00000000 --- a/Hanekawa.Database/Migrations/20200906103600_DblVoteRewards.Designer.cs +++ /dev/null @@ -1,1644 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200906103600_DblVoteRewards")] - partial class DblVoteRewards - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DslAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DslAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200906103600_DblVoteRewards.cs b/Hanekawa.Database/Migrations/20200906103600_DblVoteRewards.cs deleted file mode 100644 index db47e66c..00000000 --- a/Hanekawa.Database/Migrations/20200906103600_DblVoteRewards.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class DblVoteRewards : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "DblAuths", - columns: table => new - { - GuildId = table.Column(nullable: false), - AuthKey = table.Column(nullable: false), - ExpGain = table.Column(nullable: false), - CreditGain = table.Column(nullable: false), - SpecialCredit = table.Column(nullable: false), - RoleIdReward = table.Column(nullable: true), - Message = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_DslAuths", x => x.GuildId); - }); - - migrationBuilder.CreateTable( - name: "VoteLogs", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Time = table.Column(nullable: false), - Type = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_VoteLogs", x => x.Id); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "DblAuths"); - - migrationBuilder.DropTable( - name: "VoteLogs"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20200921211009_AutomatedMessage.Designer.cs b/Hanekawa.Database/Migrations/20200921211009_AutomatedMessage.Designer.cs deleted file mode 100644 index f3f1acd5..00000000 --- a/Hanekawa.Database/Migrations/20200921211009_AutomatedMessage.Designer.cs +++ /dev/null @@ -1,1669 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20200921211009_AutomatedMessage")] - partial class AutomatedMessage - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.GameHistory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("End") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Start") - .HasColumnType("timestamp with time zone"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("GameHistory"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("UserGuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.HasKey("Id"); - - b.HasIndex("ItemId"); - - b.HasIndex("UserGuildId", "UserId"); - - b.ToTable("HgInventories"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Ammo") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.Property("BleedEffect") - .HasColumnType("boolean"); - - b.Property("GiveOrTake") - .HasColumnType("integer"); - - b.Property("HealOverTime") - .HasColumnType("boolean"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HgItems"); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Participant", b => - { - b.Property("GuildId") - .HasColumnType("numeric(20,0)"); - - b.Property("UserId") - .HasColumnType("numeric(20,0)"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("Hunger") - .HasColumnType("integer"); - - b.Property("LatestMove") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stamina") - .HasColumnType("integer"); - - b.Property("Thirst") - .HasColumnType("integer"); - - b.Property("Tiredness") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HgParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.HungerGames.Entity.Inventory", b => - { - b.HasOne("Hanekawa.HungerGames.Entity.Item", "Item") - .WithMany("Inventories") - .HasForeignKey("ItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.HungerGames.Entity.Participant", "User") - .WithMany("Inventory") - .HasForeignKey("UserGuildId", "UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20200921211009_AutomatedMessage.cs b/Hanekawa.Database/Migrations/20200921211009_AutomatedMessage.cs deleted file mode 100644 index 1cde74d2..00000000 --- a/Hanekawa.Database/Migrations/20200921211009_AutomatedMessage.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Hanekawa.Database.Migrations -{ - public partial class AutomatedMessage : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AutoMessages", - columns: table => new - { - GuildId = table.Column(nullable: false), - Name = table.Column(nullable: false), - Creator = table.Column(nullable: false), - ChannelId = table.Column(nullable: false), - Message = table.Column(nullable: true), - Interval = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AutoMessages", x => new { x.GuildId, x.Name }); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AutoMessages"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20201002172901_HungerGames.Designer.cs b/Hanekawa.Database/Migrations/20201002172901_HungerGames.Designer.cs deleted file mode 100644 index f2ca3c82..00000000 --- a/Hanekawa.Database/Migrations/20201002172901_HungerGames.Designer.cs +++ /dev/null @@ -1,1878 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20201002172901_HungerGames")] - partial class HungerGames - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.7") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGame", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Alive") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Participants") - .HasColumnType("integer"); - - b.Property("Round") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("HungerGames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameCustomChar", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("HungerGameCustomChars"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameDefault", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HungerGameDefaults"); - - b.HasData( - new - { - Id = 1L, - Avatar = "https://i.imgur.com/XMjW8Qn.png", - Name = "Dia" - }, - new - { - Id = 2L, - Avatar = "https://i.imgur.com/7URjbvT.png", - Name = "Kanan" - }, - new - { - Id = 3L, - Avatar = "https://i.imgur.com/tPDON9P.png", - Name = "Yoshiko" - }, - new - { - Id = 4L, - Avatar = "https://i.imgur.com/dcB1loo.png", - Name = "Kongou" - }, - new - { - Id = 5L, - Avatar = "https://i.imgur.com/7GC7FvJ.png", - Name = "Haruna" - }, - new - { - Id = 6L, - Avatar = "https://i.imgur.com/8748bUL.png", - Name = "Yamato" - }, - new - { - Id = 7L, - Avatar = "https://i.imgur.com/VLsezdF.png", - Name = "Akagi" - }, - new - { - Id = 8L, - Avatar = "https://i.imgur.com/eyt9k8E.png", - Name = "Kaga" - }, - new - { - Id = 9L, - Avatar = "https://i.imgur.com/4XYg6ch.png", - Name = "Zero Two" - }, - new - { - Id = 10L, - Avatar = "https://i.imgur.com/Nl6WsbP.png", - Name = "Echidna" - }, - new - { - Id = 11L, - Avatar = "https://i.imgur.com/kF9b4SJ.png", - Name = "Emilia" - }, - new - { - Id = 12L, - Avatar = "https://i.imgur.com/y3bb8Sk.png", - Name = "Rem" - }, - new - { - Id = 13L, - Avatar = "https://i.imgur.com/5CcdVBE.png", - Name = "Ram" - }, - new - { - Id = 14L, - Avatar = "https://i.imgur.com/0VYBYEg.png", - Name = "Gura" - }, - new - { - Id = 15L, - Avatar = "https://i.imgur.com/rYa5iYc.png", - Name = "Shiki" - }, - new - { - Id = 16L, - Avatar = "https://i.imgur.com/PT8SsVB.png", - Name = "Chika" - }, - new - { - Id = 17L, - Avatar = "https://i.imgur.com/5xR0ImK.png", - Name = "Sora" - }, - new - { - Id = 18L, - Avatar = "https://i.imgur.com/U0NlfJd.png", - Name = "Nobuna" - }, - new - { - Id = 19L, - Avatar = "https://i.imgur.com/CI9Osi5.png", - Name = "Akame" - }, - new - { - Id = 20L, - Avatar = "https://i.imgur.com/GhSG97V.png", - Name = "Shiina" - }, - new - { - Id = 21L, - Avatar = "https://i.imgur.com/VyJf95i.png", - Name = "Bocchi" - }, - new - { - Id = 22L, - Avatar = "https://i.imgur.com/bv5ao8Z.png", - Name = "Enterprise" - }, - new - { - Id = 23L, - Avatar = "https://i.imgur.com/HoNwKi9.png", - Name = "Chocola" - }, - new - { - Id = 24L, - Avatar = "https://i.imgur.com/aijxHla.png", - Name = "Vanilla" - }, - new - { - Id = 25L, - Avatar = "https://i.imgur.com/Wxhd5WY.png", - Name = "Shiro" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameHistory", b => - { - b.Property("GameId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("Date") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("GameId"); - - b.ToTable("HungerGameHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameProfile", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Bot") - .HasColumnType("boolean"); - - b.Property("Bullets") - .HasColumnType("integer"); - - b.Property("FirstAid") - .HasColumnType("integer"); - - b.Property("Food") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("double precision"); - - b.Property("Hunger") - .HasColumnType("double precision"); - - b.Property("MeleeWeapon") - .HasColumnType("integer"); - - b.Property("Move") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("RangeWeapon") - .HasColumnType("integer"); - - b.Property("Stamina") - .HasColumnType("double precision"); - - b.Property("Thirst") - .HasColumnType("double precision"); - - b.Property("Tiredness") - .HasColumnType("double precision"); - - b.Property("Water") - .HasColumnType("integer"); - - b.Property("Weapons") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HungerGameProfiles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameStatus", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GameId") - .HasColumnType("uuid"); - - b.Property("RoleReward") - .HasColumnType("bigint"); - - b.Property("SignUpChannel") - .HasColumnType("bigint"); - - b.Property("SignUpMessage") - .HasColumnType("text"); - - b.Property("SignUpStart") - .HasColumnType("timestamp with time zone"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Stage") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("HungerGameStatus"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20201002172901_HungerGames.cs b/Hanekawa.Database/Migrations/20201002172901_HungerGames.cs deleted file mode 100644 index cb99d061..00000000 --- a/Hanekawa.Database/Migrations/20201002172901_HungerGames.cs +++ /dev/null @@ -1,283 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class HungerGames : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "GameHistory"); - - migrationBuilder.DropTable( - name: "HgInventories"); - - migrationBuilder.DropTable( - name: "HgItems"); - - migrationBuilder.DropTable( - name: "HgParticipants"); - - migrationBuilder.CreateTable( - name: "HungerGameCustomChars", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Name = table.Column(nullable: true), - Avatar = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_HungerGameCustomChars", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "HungerGameDefaults", - columns: table => new - { - Id = table.Column(nullable: false), - Name = table.Column(nullable: true), - Avatar = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_HungerGameDefaults", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HungerGameHistories", - columns: table => new - { - GameId = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Winner = table.Column(nullable: false), - Date = table.Column(nullable: false), - ExpReward = table.Column(nullable: false), - CreditReward = table.Column(nullable: false), - SpecialCreditReward = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HungerGameHistories", x => x.GameId); - }); - - migrationBuilder.CreateTable( - name: "HungerGameProfiles", - columns: table => new - { - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Bot = table.Column(nullable: false), - Name = table.Column(nullable: true), - Avatar = table.Column(nullable: true), - Alive = table.Column(nullable: false), - Health = table.Column(nullable: false), - Stamina = table.Column(nullable: false), - Bleeding = table.Column(nullable: false), - Hunger = table.Column(nullable: false), - Thirst = table.Column(nullable: false), - Tiredness = table.Column(nullable: false), - Move = table.Column(nullable: false), - Food = table.Column(nullable: false), - Water = table.Column(nullable: false), - FirstAid = table.Column(nullable: false), - Weapons = table.Column(nullable: false), - MeleeWeapon = table.Column(nullable: false), - RangeWeapon = table.Column(nullable: false), - Bullets = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HungerGameProfiles", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "HungerGames", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Round = table.Column(nullable: false), - Alive = table.Column(nullable: false), - Participants = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HungerGames", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HungerGameStatus", - columns: table => new - { - GuildId = table.Column(nullable: false), - SignUpChannel = table.Column(nullable: true), - EventChannel = table.Column(nullable: true), - EmoteMessageFormat = table.Column(nullable: true), - Stage = table.Column(nullable: false), - SignUpStart = table.Column(nullable: false), - SignUpMessage = table.Column(nullable: true), - GameId = table.Column(nullable: true), - ExpReward = table.Column(nullable: false), - CreditReward = table.Column(nullable: false), - SpecialCreditReward = table.Column(nullable: false), - RoleReward = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_HungerGameStatus", x => x.GuildId); - }); - - migrationBuilder.InsertData( - table: "HungerGameDefaults", - columns: new[] { "Id", "Avatar", "Name" }, - values: new object[,] - { - { 1L, "https://i.imgur.com/XMjW8Qn.png", "Dia" }, - { 23L, "https://i.imgur.com/HoNwKi9.png", "Chocola" }, - { 22L, "https://i.imgur.com/bv5ao8Z.png", "Enterprise" }, - { 21L, "https://i.imgur.com/VyJf95i.png", "Bocchi" }, - { 20L, "https://i.imgur.com/GhSG97V.png", "Shiina" }, - { 19L, "https://i.imgur.com/CI9Osi5.png", "Akame" }, - { 18L, "https://i.imgur.com/U0NlfJd.png", "Nobuna" }, - { 17L, "https://i.imgur.com/5xR0ImK.png", "Sora" }, - { 16L, "https://i.imgur.com/PT8SsVB.png", "Chika" }, - { 15L, "https://i.imgur.com/rYa5iYc.png", "Shiki" }, - { 14L, "https://i.imgur.com/0VYBYEg.png", "Gura" }, - { 24L, "https://i.imgur.com/aijxHla.png", "Vanilla" }, - { 13L, "https://i.imgur.com/5CcdVBE.png", "Ram" }, - { 11L, "https://i.imgur.com/kF9b4SJ.png", "Emilia" }, - { 10L, "https://i.imgur.com/Nl6WsbP.png", "Echidna" }, - { 9L, "https://i.imgur.com/4XYg6ch.png", "Zero Two" }, - { 8L, "https://i.imgur.com/eyt9k8E.png", "Kaga" }, - { 7L, "https://i.imgur.com/VLsezdF.png", "Akagi" }, - { 6L, "https://i.imgur.com/8748bUL.png", "Yamato" }, - { 5L, "https://i.imgur.com/7GC7FvJ.png", "Haruna" }, - { 4L, "https://i.imgur.com/dcB1loo.png", "Kongou" }, - { 3L, "https://i.imgur.com/tPDON9P.png", "Yoshiko" }, - { 2L, "https://i.imgur.com/7URjbvT.png", "Kanan" }, - { 12L, "https://i.imgur.com/y3bb8Sk.png", "Rem" }, - { 25L, "https://i.imgur.com/Wxhd5WY.png", "Shiro" } - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "HungerGameCustomChars"); - - migrationBuilder.DropTable( - name: "HungerGameDefaults"); - - migrationBuilder.DropTable( - name: "HungerGameHistories"); - - migrationBuilder.DropTable( - name: "HungerGameProfiles"); - - migrationBuilder.DropTable( - name: "HungerGames"); - - migrationBuilder.DropTable( - name: "HungerGameStatus"); - - migrationBuilder.CreateTable( - name: "GameHistory", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Active = table.Column(type: "boolean", nullable: false), - End = table.Column(type: "timestamp with time zone", nullable: true), - GuildId = table.Column(type: "bigint", nullable: false), - Start = table.Column(type: "timestamp with time zone", nullable: false), - Winner = table.Column(type: "bigint", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_GameHistory", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HgItems", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Ammo = table.Column(type: "integer", nullable: false), - Amount = table.Column(type: "integer", nullable: false), - BleedEffect = table.Column(type: "boolean", nullable: false), - GiveOrTake = table.Column(type: "integer", nullable: false), - HealOverTime = table.Column(type: "boolean", nullable: false), - Name = table.Column(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_HgItems", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "HgParticipants", - columns: table => new - { - GuildId = table.Column(type: "numeric(20,0)", nullable: false), - UserId = table.Column(type: "numeric(20,0)", nullable: false), - Alive = table.Column(type: "boolean", nullable: false), - Avatar = table.Column(type: "text", nullable: true), - Bleeding = table.Column(type: "boolean", nullable: false), - Health = table.Column(type: "integer", nullable: false), - Hunger = table.Column(type: "integer", nullable: false), - LatestMove = table.Column(type: "integer", nullable: false), - Name = table.Column(type: "text", nullable: true), - Stamina = table.Column(type: "integer", nullable: false), - Thirst = table.Column(type: "integer", nullable: false), - Tiredness = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HgParticipants", x => new { x.GuildId, x.UserId }); - }); - - migrationBuilder.CreateTable( - name: "HgInventories", - columns: table => new - { - Id = table.Column(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - Count = table.Column(type: "integer", nullable: false), - ItemId = table.Column(type: "integer", nullable: false), - UserGuildId = table.Column(type: "numeric(20,0)", nullable: false), - UserId = table.Column(type: "numeric(20,0)", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_HgInventories", x => x.Id); - table.ForeignKey( - name: "FK_HgInventories_HgItems_ItemId", - column: x => x.ItemId, - principalTable: "HgItems", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_HgInventories_HgParticipants_UserGuildId_UserId", - columns: x => new { x.UserGuildId, x.UserId }, - principalTable: "HgParticipants", - principalColumns: new[] { "GuildId", "UserId" }, - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_HgInventories_ItemId", - table: "HgInventories", - column: "ItemId"); - - migrationBuilder.CreateIndex( - name: "IX_HgInventories_UserGuildId_UserId", - table: "HgInventories", - columns: new[] { "UserGuildId", "UserId" }); - } - } -} diff --git a/Hanekawa.Database/Migrations/20201016233504_Giveaway.Designer.cs b/Hanekawa.Database/Migrations/20201016233504_Giveaway.Designer.cs deleted file mode 100644 index 85447c99..00000000 --- a/Hanekawa.Database/Migrations/20201016233504_Giveaway.Designer.cs +++ /dev/null @@ -1,2002 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20201016233504_Giveaway")] - partial class Giveaway - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.8") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGame", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Alive") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Participants") - .HasColumnType("integer"); - - b.Property("Round") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("HungerGames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameCustomChar", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("HungerGameCustomChars"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameDefault", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HungerGameDefaults"); - - b.HasData( - new - { - Id = 1L, - Avatar = "https://i.imgur.com/XMjW8Qn.png", - Name = "Dia" - }, - new - { - Id = 2L, - Avatar = "https://i.imgur.com/7URjbvT.png", - Name = "Kanan" - }, - new - { - Id = 3L, - Avatar = "https://i.imgur.com/tPDON9P.png", - Name = "Yoshiko" - }, - new - { - Id = 4L, - Avatar = "https://i.imgur.com/dcB1loo.png", - Name = "Kongou" - }, - new - { - Id = 5L, - Avatar = "https://i.imgur.com/7GC7FvJ.png", - Name = "Haruna" - }, - new - { - Id = 6L, - Avatar = "https://i.imgur.com/8748bUL.png", - Name = "Yamato" - }, - new - { - Id = 7L, - Avatar = "https://i.imgur.com/VLsezdF.png", - Name = "Akagi" - }, - new - { - Id = 8L, - Avatar = "https://i.imgur.com/eyt9k8E.png", - Name = "Kaga" - }, - new - { - Id = 9L, - Avatar = "https://i.imgur.com/4XYg6ch.png", - Name = "Zero Two" - }, - new - { - Id = 10L, - Avatar = "https://i.imgur.com/Nl6WsbP.png", - Name = "Echidna" - }, - new - { - Id = 11L, - Avatar = "https://i.imgur.com/kF9b4SJ.png", - Name = "Emilia" - }, - new - { - Id = 12L, - Avatar = "https://i.imgur.com/y3bb8Sk.png", - Name = "Rem" - }, - new - { - Id = 13L, - Avatar = "https://i.imgur.com/5CcdVBE.png", - Name = "Ram" - }, - new - { - Id = 14L, - Avatar = "https://i.imgur.com/0VYBYEg.png", - Name = "Gura" - }, - new - { - Id = 15L, - Avatar = "https://i.imgur.com/rYa5iYc.png", - Name = "Shiki" - }, - new - { - Id = 16L, - Avatar = "https://i.imgur.com/PT8SsVB.png", - Name = "Chika" - }, - new - { - Id = 17L, - Avatar = "https://i.imgur.com/5xR0ImK.png", - Name = "Sora" - }, - new - { - Id = 18L, - Avatar = "https://i.imgur.com/U0NlfJd.png", - Name = "Nobuna" - }, - new - { - Id = 19L, - Avatar = "https://i.imgur.com/CI9Osi5.png", - Name = "Akame" - }, - new - { - Id = 20L, - Avatar = "https://i.imgur.com/GhSG97V.png", - Name = "Shiina" - }, - new - { - Id = 21L, - Avatar = "https://i.imgur.com/VyJf95i.png", - Name = "Bocchi" - }, - new - { - Id = 22L, - Avatar = "https://i.imgur.com/bv5ao8Z.png", - Name = "Enterprise" - }, - new - { - Id = 23L, - Avatar = "https://i.imgur.com/HoNwKi9.png", - Name = "Chocola" - }, - new - { - Id = 24L, - Avatar = "https://i.imgur.com/aijxHla.png", - Name = "Vanilla" - }, - new - { - Id = 25L, - Avatar = "https://i.imgur.com/Wxhd5WY.png", - Name = "Shiro" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameHistory", b => - { - b.Property("GameId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("Date") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("GameId"); - - b.ToTable("HungerGameHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameProfile", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Bot") - .HasColumnType("boolean"); - - b.Property("Bullets") - .HasColumnType("integer"); - - b.Property("FirstAid") - .HasColumnType("integer"); - - b.Property("Food") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("double precision"); - - b.Property("Hunger") - .HasColumnType("double precision"); - - b.Property("MeleeWeapon") - .HasColumnType("integer"); - - b.Property("Move") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("RangeWeapon") - .HasColumnType("integer"); - - b.Property("Stamina") - .HasColumnType("double precision"); - - b.Property("Thirst") - .HasColumnType("double precision"); - - b.Property("Tiredness") - .HasColumnType("double precision"); - - b.Property("Water") - .HasColumnType("integer"); - - b.Property("Weapons") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HungerGameProfiles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameStatus", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GameId") - .HasColumnType("uuid"); - - b.Property("RoleReward") - .HasColumnType("bigint"); - - b.Property("SignUpChannel") - .HasColumnType("bigint"); - - b.Property("SignUpMessage") - .HasColumnType("text"); - - b.Property("SignUpStart") - .HasColumnType("timestamp with time zone"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Stage") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("HungerGameStatus"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountAgeRequirement") - .HasColumnType("interval"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("CloseAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ServerAgeRequirement") - .HasColumnType("interval"); - - b.Property("Stack") - .HasColumnType("boolean"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("WinnerAmount") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("Giveaways"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayHistory", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ClosedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint[]"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("GiveawayHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Entry") - .HasColumnType("timestamp with time zone"); - - b.Property("GiveawayId") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("GiveawayId"); - - b.ToTable("GiveawayParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.HasOne("Hanekawa.Database.Tables.Giveaway.Giveaway", "Giveaway") - .WithMany("Participants") - .HasForeignKey("GiveawayId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20201016233504_Giveaway.cs b/Hanekawa.Database/Migrations/20201016233504_Giveaway.cs deleted file mode 100644 index 742b22bd..00000000 --- a/Hanekawa.Database/Migrations/20201016233504_Giveaway.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class Giveaway : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "GiveawayHistories", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - IdNum = table.Column(nullable: false), - Creator = table.Column(nullable: false), - Winner = table.Column(nullable: true), - Name = table.Column(nullable: true), - Description = table.Column(nullable: true), - Type = table.Column(nullable: false), - CreatedAtOffset = table.Column(nullable: false), - ClosedAtOffset = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GiveawayHistories", x => new { x.Id, x.GuildId }); - }); - - migrationBuilder.CreateTable( - name: "Giveaways", - columns: table => new - { - Id = table.Column(nullable: false), - IdNum = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - Creator = table.Column(nullable: false), - Active = table.Column(nullable: false), - Stack = table.Column(nullable: false), - WinnerAmount = table.Column(nullable: false), - LevelRequirement = table.Column(nullable: true), - AccountAgeRequirement = table.Column(nullable: true), - ServerAgeRequirement = table.Column(nullable: true), - Name = table.Column(nullable: true), - Description = table.Column(nullable: true), - Type = table.Column(nullable: false), - CreatedAtOffset = table.Column(nullable: false), - CloseAtOffset = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Giveaways", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "GiveawayParticipants", - columns: table => new - { - Id = table.Column(nullable: false), - GuildId = table.Column(nullable: false), - UserId = table.Column(nullable: false), - Entry = table.Column(nullable: false), - GiveawayId = table.Column(nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GiveawayParticipants", x => x.Id); - table.ForeignKey( - name: "FK_GiveawayParticipants_Giveaways_GiveawayId", - column: x => x.GiveawayId, - principalTable: "Giveaways", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_GiveawayParticipants_GiveawayId", - table: "GiveawayParticipants", - column: "GiveawayId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "GiveawayHistories"); - - migrationBuilder.DropTable( - name: "GiveawayParticipants"); - - migrationBuilder.DropTable( - name: "Giveaways"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20201215150233_ReactionLogging.Designer.cs b/Hanekawa.Database/Migrations/20201215150233_ReactionLogging.Designer.cs deleted file mode 100644 index 4f040114..00000000 --- a/Hanekawa.Database/Migrations/20201215150233_ReactionLogging.Designer.cs +++ /dev/null @@ -1,2008 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20201215150233_ReactionLogging")] - partial class ReactionLogging - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) - .HasAnnotation("ProductVersion", "3.1.9") - .HasAnnotation("Relational:MaxIdentifierLength", 63); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGame", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Alive") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Participants") - .HasColumnType("integer"); - - b.Property("Round") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("HungerGames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameCustomChar", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("HungerGameCustomChars"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameDefault", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HungerGameDefaults"); - - b.HasData( - new - { - Id = 1L, - Avatar = "https://i.imgur.com/XMjW8Qn.png", - Name = "Dia" - }, - new - { - Id = 2L, - Avatar = "https://i.imgur.com/7URjbvT.png", - Name = "Kanan" - }, - new - { - Id = 3L, - Avatar = "https://i.imgur.com/tPDON9P.png", - Name = "Yoshiko" - }, - new - { - Id = 4L, - Avatar = "https://i.imgur.com/dcB1loo.png", - Name = "Kongou" - }, - new - { - Id = 5L, - Avatar = "https://i.imgur.com/7GC7FvJ.png", - Name = "Haruna" - }, - new - { - Id = 6L, - Avatar = "https://i.imgur.com/8748bUL.png", - Name = "Yamato" - }, - new - { - Id = 7L, - Avatar = "https://i.imgur.com/VLsezdF.png", - Name = "Akagi" - }, - new - { - Id = 8L, - Avatar = "https://i.imgur.com/eyt9k8E.png", - Name = "Kaga" - }, - new - { - Id = 9L, - Avatar = "https://i.imgur.com/4XYg6ch.png", - Name = "Zero Two" - }, - new - { - Id = 10L, - Avatar = "https://i.imgur.com/Nl6WsbP.png", - Name = "Echidna" - }, - new - { - Id = 11L, - Avatar = "https://i.imgur.com/kF9b4SJ.png", - Name = "Emilia" - }, - new - { - Id = 12L, - Avatar = "https://i.imgur.com/y3bb8Sk.png", - Name = "Rem" - }, - new - { - Id = 13L, - Avatar = "https://i.imgur.com/5CcdVBE.png", - Name = "Ram" - }, - new - { - Id = 14L, - Avatar = "https://i.imgur.com/0VYBYEg.png", - Name = "Gura" - }, - new - { - Id = 15L, - Avatar = "https://i.imgur.com/rYa5iYc.png", - Name = "Shiki" - }, - new - { - Id = 16L, - Avatar = "https://i.imgur.com/PT8SsVB.png", - Name = "Chika" - }, - new - { - Id = 17L, - Avatar = "https://i.imgur.com/5xR0ImK.png", - Name = "Sora" - }, - new - { - Id = 18L, - Avatar = "https://i.imgur.com/U0NlfJd.png", - Name = "Nobuna" - }, - new - { - Id = 19L, - Avatar = "https://i.imgur.com/CI9Osi5.png", - Name = "Akame" - }, - new - { - Id = 20L, - Avatar = "https://i.imgur.com/GhSG97V.png", - Name = "Shiina" - }, - new - { - Id = 21L, - Avatar = "https://i.imgur.com/VyJf95i.png", - Name = "Bocchi" - }, - new - { - Id = 22L, - Avatar = "https://i.imgur.com/bv5ao8Z.png", - Name = "Enterprise" - }, - new - { - Id = 23L, - Avatar = "https://i.imgur.com/HoNwKi9.png", - Name = "Chocola" - }, - new - { - Id = 24L, - Avatar = "https://i.imgur.com/aijxHla.png", - Name = "Vanilla" - }, - new - { - Id = 25L, - Avatar = "https://i.imgur.com/Wxhd5WY.png", - Name = "Shiro" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameHistory", b => - { - b.Property("GameId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("Date") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("GameId"); - - b.ToTable("HungerGameHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameProfile", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Bot") - .HasColumnType("boolean"); - - b.Property("Bullets") - .HasColumnType("integer"); - - b.Property("FirstAid") - .HasColumnType("integer"); - - b.Property("Food") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("double precision"); - - b.Property("Hunger") - .HasColumnType("double precision"); - - b.Property("MeleeWeapon") - .HasColumnType("integer"); - - b.Property("Move") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("RangeWeapon") - .HasColumnType("integer"); - - b.Property("Stamina") - .HasColumnType("double precision"); - - b.Property("Thirst") - .HasColumnType("double precision"); - - b.Property("Tiredness") - .HasColumnType("double precision"); - - b.Property("Water") - .HasColumnType("integer"); - - b.Property("Weapons") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HungerGameProfiles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameStatus", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GameId") - .HasColumnType("uuid"); - - b.Property("RoleReward") - .HasColumnType("bigint"); - - b.Property("SignUpChannel") - .HasColumnType("bigint"); - - b.Property("SignUpMessage") - .HasColumnType("text"); - - b.Property("SignUpStart") - .HasColumnType("timestamp with time zone"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Stage") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("HungerGameStatus"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogReaction") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.Property("ReactionWebhook") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountAgeRequirement") - .HasColumnType("interval"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("CloseAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ServerAgeRequirement") - .HasColumnType("interval"); - - b.Property("Stack") - .HasColumnType("boolean"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("WinnerAmount") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("Giveaways"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayHistory", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ClosedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint[]"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("GiveawayHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Entry") - .HasColumnType("timestamp with time zone"); - - b.Property("GiveawayId") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("GiveawayId"); - - b.ToTable("GiveawayParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.HasOne("Hanekawa.Database.Tables.Giveaway.Giveaway", "Giveaway") - .WithMany("Participants") - .HasForeignKey("GiveawayId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20201215150233_ReactionLogging.cs b/Hanekawa.Database/Migrations/20201215150233_ReactionLogging.cs deleted file mode 100644 index 493ed70f..00000000 --- a/Hanekawa.Database/Migrations/20201215150233_ReactionLogging.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Hanekawa.Database.Migrations -{ - public partial class ReactionLogging : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "LogReaction", - table: "LoggingConfigs", - nullable: true); - - migrationBuilder.AddColumn( - name: "ReactionWebhook", - table: "LoggingConfigs", - nullable: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "LogReaction", - table: "LoggingConfigs"); - - migrationBuilder.DropColumn( - name: "ReactionWebhook", - table: "LoggingConfigs"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20210114110438_WelcomeBannerUpdate.Designer.cs b/Hanekawa.Database/Migrations/20210114110438_WelcomeBannerUpdate.Designer.cs deleted file mode 100644 index 13537b36..00000000 --- a/Hanekawa.Database/Migrations/20210114110438_WelcomeBannerUpdate.Designer.cs +++ /dev/null @@ -1,2072 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20210114110438_WelcomeBannerUpdate")] - partial class WelcomeBannerUpdate - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .UseIdentityByDefaultColumns() - .HasAnnotation("Relational:MaxIdentifierLength", 63) - .HasAnnotation("ProductVersion", "5.0.1"); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGame", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Alive") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Participants") - .HasColumnType("integer"); - - b.Property("Round") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("HungerGames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameCustomChar", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("HungerGameCustomChars"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameDefault", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HungerGameDefaults"); - - b.HasData( - new - { - Id = 1L, - Avatar = "https://i.imgur.com/XMjW8Qn.png", - Name = "Dia" - }, - new - { - Id = 2L, - Avatar = "https://i.imgur.com/7URjbvT.png", - Name = "Kanan" - }, - new - { - Id = 3L, - Avatar = "https://i.imgur.com/tPDON9P.png", - Name = "Yoshiko" - }, - new - { - Id = 4L, - Avatar = "https://i.imgur.com/dcB1loo.png", - Name = "Kongou" - }, - new - { - Id = 5L, - Avatar = "https://i.imgur.com/7GC7FvJ.png", - Name = "Haruna" - }, - new - { - Id = 6L, - Avatar = "https://i.imgur.com/8748bUL.png", - Name = "Yamato" - }, - new - { - Id = 7L, - Avatar = "https://i.imgur.com/VLsezdF.png", - Name = "Akagi" - }, - new - { - Id = 8L, - Avatar = "https://i.imgur.com/eyt9k8E.png", - Name = "Kaga" - }, - new - { - Id = 9L, - Avatar = "https://i.imgur.com/4XYg6ch.png", - Name = "Zero Two" - }, - new - { - Id = 10L, - Avatar = "https://i.imgur.com/Nl6WsbP.png", - Name = "Echidna" - }, - new - { - Id = 11L, - Avatar = "https://i.imgur.com/kF9b4SJ.png", - Name = "Emilia" - }, - new - { - Id = 12L, - Avatar = "https://i.imgur.com/y3bb8Sk.png", - Name = "Rem" - }, - new - { - Id = 13L, - Avatar = "https://i.imgur.com/5CcdVBE.png", - Name = "Ram" - }, - new - { - Id = 14L, - Avatar = "https://i.imgur.com/0VYBYEg.png", - Name = "Gura" - }, - new - { - Id = 15L, - Avatar = "https://i.imgur.com/rYa5iYc.png", - Name = "Shiki" - }, - new - { - Id = 16L, - Avatar = "https://i.imgur.com/PT8SsVB.png", - Name = "Chika" - }, - new - { - Id = 17L, - Avatar = "https://i.imgur.com/5xR0ImK.png", - Name = "Sora" - }, - new - { - Id = 18L, - Avatar = "https://i.imgur.com/U0NlfJd.png", - Name = "Nobuna" - }, - new - { - Id = 19L, - Avatar = "https://i.imgur.com/CI9Osi5.png", - Name = "Akame" - }, - new - { - Id = 20L, - Avatar = "https://i.imgur.com/GhSG97V.png", - Name = "Shiina" - }, - new - { - Id = 21L, - Avatar = "https://i.imgur.com/VyJf95i.png", - Name = "Bocchi" - }, - new - { - Id = 22L, - Avatar = "https://i.imgur.com/bv5ao8Z.png", - Name = "Enterprise" - }, - new - { - Id = 23L, - Avatar = "https://i.imgur.com/HoNwKi9.png", - Name = "Chocola" - }, - new - { - Id = 24L, - Avatar = "https://i.imgur.com/aijxHla.png", - Name = "Vanilla" - }, - new - { - Id = 25L, - Avatar = "https://i.imgur.com/Wxhd5WY.png", - Name = "Shiro" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameHistory", b => - { - b.Property("GameId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("Date") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("GameId"); - - b.ToTable("HungerGameHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameProfile", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Bot") - .HasColumnType("boolean"); - - b.Property("Bullets") - .HasColumnType("integer"); - - b.Property("FirstAid") - .HasColumnType("integer"); - - b.Property("Food") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("double precision"); - - b.Property("Hunger") - .HasColumnType("double precision"); - - b.Property("MeleeWeapon") - .HasColumnType("integer"); - - b.Property("Move") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("RangeWeapon") - .HasColumnType("integer"); - - b.Property("Stamina") - .HasColumnType("double precision"); - - b.Property("Thirst") - .HasColumnType("double precision"); - - b.Property("Tiredness") - .HasColumnType("double precision"); - - b.Property("Water") - .HasColumnType("integer"); - - b.Property("Weapons") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HungerGameProfiles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameStatus", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GameId") - .HasColumnType("uuid"); - - b.Property("RoleReward") - .HasColumnType("bigint"); - - b.Property("SignUpChannel") - .HasColumnType("bigint"); - - b.Property("SignUpMessage") - .HasColumnType("text"); - - b.Property("SignUpStart") - .HasColumnType("timestamp with time zone"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Stage") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("HungerGameStatus"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogReaction") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.Property("ReactionWebhook") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AvatarSize") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(60); - - b.Property("AviPlaceX") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(10); - - b.Property("AviPlaceY") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(10); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("TextPlaceX") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(245); - - b.Property("TextPlaceY") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(40); - - b.Property("TextSize") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(33); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountAgeRequirement") - .HasColumnType("interval"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("CloseAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ServerAgeRequirement") - .HasColumnType("interval"); - - b.Property("Stack") - .HasColumnType("boolean"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("WinnerAmount") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("Giveaways"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayHistory", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ClosedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint[]"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("GiveawayHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Entry") - .HasColumnType("timestamp with time zone"); - - b.Property("GiveawayId") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("GiveawayId"); - - b.ToTable("GiveawayParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - - b.Navigation("AchievementName"); - - b.Navigation("AchievementType"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Achievement"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.HasOne("Hanekawa.Database.Tables.Giveaway.Giveaway", "Giveaway") - .WithMany("Participants") - .HasForeignKey("GiveawayId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Giveaway"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Navigation("Participants"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20210114110438_WelcomeBannerUpdate.cs b/Hanekawa.Database/Migrations/20210114110438_WelcomeBannerUpdate.cs deleted file mode 100644 index 9913471c..00000000 --- a/Hanekawa.Database/Migrations/20210114110438_WelcomeBannerUpdate.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - public partial class WelcomeBannerUpdate : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "AvatarSize", - table: "WelcomeBanners", - type: "integer", - nullable: false, - defaultValue: 60); - - migrationBuilder.AddColumn( - name: "AviPlaceX", - table: "WelcomeBanners", - type: "integer", - nullable: false, - defaultValue: 10); - - migrationBuilder.AddColumn( - name: "AviPlaceY", - table: "WelcomeBanners", - type: "integer", - nullable: false, - defaultValue: 10); - - migrationBuilder.AddColumn( - name: "TextPlaceX", - table: "WelcomeBanners", - type: "integer", - nullable: false, - defaultValue: 245); - - migrationBuilder.AddColumn( - name: "TextPlaceY", - table: "WelcomeBanners", - type: "integer", - nullable: false, - defaultValue: 40); - - migrationBuilder.AddColumn( - name: "TextSize", - table: "WelcomeBanners", - type: "integer", - nullable: false, - defaultValue: 33); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "AvatarSize", - table: "WelcomeBanners"); - - migrationBuilder.DropColumn( - name: "AviPlaceX", - table: "WelcomeBanners"); - - migrationBuilder.DropColumn( - name: "AviPlaceY", - table: "WelcomeBanners"); - - migrationBuilder.DropColumn( - name: "TextPlaceX", - table: "WelcomeBanners"); - - migrationBuilder.DropColumn( - name: "TextPlaceY", - table: "WelcomeBanners"); - - migrationBuilder.DropColumn( - name: "TextSize", - table: "WelcomeBanners"); - } - } -} diff --git a/Hanekawa.Database/Migrations/20210203075854_ExpDecay.Designer.cs b/Hanekawa.Database/Migrations/20210203075854_ExpDecay.Designer.cs deleted file mode 100644 index 2d6af033..00000000 --- a/Hanekawa.Database/Migrations/20210203075854_ExpDecay.Designer.cs +++ /dev/null @@ -1,2087 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - [Migration("20210203075854_ExpDecay")] - partial class ExpDecay - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .UseIdentityByDefaultColumns() - .HasAnnotation("Relational:MaxIdentifierLength", 63) - .HasAnnotation("ProductVersion", "5.0.2"); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Decay") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGame", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Alive") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Participants") - .HasColumnType("integer"); - - b.Property("Round") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("HungerGames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameCustomChar", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("HungerGameCustomChars"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameDefault", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HungerGameDefaults"); - - b.HasData( - new - { - Id = 1L, - Avatar = "https://i.imgur.com/XMjW8Qn.png", - Name = "Dia" - }, - new - { - Id = 2L, - Avatar = "https://i.imgur.com/7URjbvT.png", - Name = "Kanan" - }, - new - { - Id = 3L, - Avatar = "https://i.imgur.com/tPDON9P.png", - Name = "Yoshiko" - }, - new - { - Id = 4L, - Avatar = "https://i.imgur.com/dcB1loo.png", - Name = "Kongou" - }, - new - { - Id = 5L, - Avatar = "https://i.imgur.com/7GC7FvJ.png", - Name = "Haruna" - }, - new - { - Id = 6L, - Avatar = "https://i.imgur.com/8748bUL.png", - Name = "Yamato" - }, - new - { - Id = 7L, - Avatar = "https://i.imgur.com/VLsezdF.png", - Name = "Akagi" - }, - new - { - Id = 8L, - Avatar = "https://i.imgur.com/eyt9k8E.png", - Name = "Kaga" - }, - new - { - Id = 9L, - Avatar = "https://i.imgur.com/4XYg6ch.png", - Name = "Zero Two" - }, - new - { - Id = 10L, - Avatar = "https://i.imgur.com/Nl6WsbP.png", - Name = "Echidna" - }, - new - { - Id = 11L, - Avatar = "https://i.imgur.com/kF9b4SJ.png", - Name = "Emilia" - }, - new - { - Id = 12L, - Avatar = "https://i.imgur.com/y3bb8Sk.png", - Name = "Rem" - }, - new - { - Id = 13L, - Avatar = "https://i.imgur.com/5CcdVBE.png", - Name = "Ram" - }, - new - { - Id = 14L, - Avatar = "https://i.imgur.com/0VYBYEg.png", - Name = "Gura" - }, - new - { - Id = 15L, - Avatar = "https://i.imgur.com/rYa5iYc.png", - Name = "Shiki" - }, - new - { - Id = 16L, - Avatar = "https://i.imgur.com/PT8SsVB.png", - Name = "Chika" - }, - new - { - Id = 17L, - Avatar = "https://i.imgur.com/5xR0ImK.png", - Name = "Sora" - }, - new - { - Id = 18L, - Avatar = "https://i.imgur.com/U0NlfJd.png", - Name = "Nobuna" - }, - new - { - Id = 19L, - Avatar = "https://i.imgur.com/CI9Osi5.png", - Name = "Akame" - }, - new - { - Id = 20L, - Avatar = "https://i.imgur.com/GhSG97V.png", - Name = "Shiina" - }, - new - { - Id = 21L, - Avatar = "https://i.imgur.com/VyJf95i.png", - Name = "Bocchi" - }, - new - { - Id = 22L, - Avatar = "https://i.imgur.com/bv5ao8Z.png", - Name = "Enterprise" - }, - new - { - Id = 23L, - Avatar = "https://i.imgur.com/HoNwKi9.png", - Name = "Chocola" - }, - new - { - Id = 24L, - Avatar = "https://i.imgur.com/aijxHla.png", - Name = "Vanilla" - }, - new - { - Id = 25L, - Avatar = "https://i.imgur.com/Wxhd5WY.png", - Name = "Shiro" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameHistory", b => - { - b.Property("GameId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("Date") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("GameId"); - - b.ToTable("HungerGameHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameProfile", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Bot") - .HasColumnType("boolean"); - - b.Property("Bullets") - .HasColumnType("integer"); - - b.Property("FirstAid") - .HasColumnType("integer"); - - b.Property("Food") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("double precision"); - - b.Property("Hunger") - .HasColumnType("double precision"); - - b.Property("MeleeWeapon") - .HasColumnType("integer"); - - b.Property("Move") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("RangeWeapon") - .HasColumnType("integer"); - - b.Property("Stamina") - .HasColumnType("double precision"); - - b.Property("Thirst") - .HasColumnType("double precision"); - - b.Property("Tiredness") - .HasColumnType("double precision"); - - b.Property("Water") - .HasColumnType("integer"); - - b.Property("Weapons") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HungerGameProfiles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameStatus", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GameId") - .HasColumnType("uuid"); - - b.Property("RoleReward") - .HasColumnType("bigint"); - - b.Property("SignUpChannel") - .HasColumnType("bigint"); - - b.Property("SignUpMessage") - .HasColumnType("text"); - - b.Property("SignUpStart") - .HasColumnType("timestamp with time zone"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Stage") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("HungerGameStatus"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("Decay") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogReaction") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.Property("ReactionWebhook") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("NoDecay") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AvatarSize") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(60); - - b.Property("AviPlaceX") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(10); - - b.Property("AviPlaceY") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(10); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("TextPlaceX") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(245); - - b.Property("TextPlaceY") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(40); - - b.Property("TextSize") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(33); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountAgeRequirement") - .HasColumnType("interval"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("CloseAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ServerAgeRequirement") - .HasColumnType("interval"); - - b.Property("Stack") - .HasColumnType("boolean"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("WinnerAmount") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("Giveaways"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayHistory", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ClosedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint[]"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("GiveawayHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Entry") - .HasColumnType("timestamp with time zone"); - - b.Property("GiveawayId") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("GiveawayId"); - - b.ToTable("GiveawayParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - - b.Navigation("AchievementName"); - - b.Navigation("AchievementType"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Achievement"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.HasOne("Hanekawa.Database.Tables.Giveaway.Giveaway", "Giveaway") - .WithMany("Participants") - .HasForeignKey("GiveawayId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Giveaway"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Navigation("Participants"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Migrations/20210203075854_ExpDecay.cs b/Hanekawa.Database/Migrations/20210203075854_ExpDecay.cs deleted file mode 100644 index e7c51c91..00000000 --- a/Hanekawa.Database/Migrations/20210203075854_ExpDecay.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Hanekawa.Database.Migrations -{ - public partial class ExpDecay : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "NoDecay", - table: "LevelRewards", - type: "boolean", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn( - name: "Decay", - table: "LevelConfigs", - type: "boolean", - nullable: false, - defaultValue: false); - - migrationBuilder.AddColumn( - name: "Decay", - table: "Accounts", - type: "integer", - nullable: false, - defaultValue: 0); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "NoDecay", - table: "LevelRewards"); - - migrationBuilder.DropColumn( - name: "Decay", - table: "LevelConfigs"); - - migrationBuilder.DropColumn( - name: "Decay", - table: "Accounts"); - } - } -} diff --git a/Hanekawa.Database/Migrations/DbServiceModelSnapshot.cs b/Hanekawa.Database/Migrations/DbServiceModelSnapshot.cs deleted file mode 100644 index 5892a55e..00000000 --- a/Hanekawa.Database/Migrations/DbServiceModelSnapshot.cs +++ /dev/null @@ -1,2085 +0,0 @@ -// -using System; -using System.Collections.Generic; -using Hanekawa.Database; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace Hanekawa.Database.Migrations -{ - [DbContext(typeof(DbService))] - partial class DbServiceModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .UseIdentityByDefaultColumns() - .HasAnnotation("Relational:MaxIdentifierLength", 63) - .HasAnnotation("ProductVersion", "5.0.2"); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Account", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("ChannelVoiceTime") - .HasColumnType("timestamp without time zone"); - - b.Property("Class") - .HasColumnType("integer"); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("CreditSpecial") - .HasColumnType("integer"); - - b.Property("DailyCredit") - .HasColumnType("timestamp without time zone"); - - b.Property("Decay") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(0); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("FirstMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("GameKillAmount") - .HasColumnType("integer"); - - b.Property("LastMessage") - .HasColumnType("timestamp without time zone"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("MvpCount") - .HasColumnType("integer"); - - b.Property("MvpOptOut") - .HasColumnType("boolean"); - - b.Property("ProfilePic") - .HasColumnType("text"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("RepCooldown") - .HasColumnType("timestamp without time zone"); - - b.Property("Sessions") - .HasColumnType("integer"); - - b.Property("StarGiven") - .HasColumnType("integer"); - - b.Property("StarReceived") - .HasColumnType("integer"); - - b.Property("StatMessages") - .HasColumnType("bigint"); - - b.Property("StatVoiceTime") - .HasColumnType("interval"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("VoiceExpTime") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Accounts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.AccountGlobal", b => - { - b.Property("UserId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Credit") - .HasColumnType("integer"); - - b.Property("Exp") - .HasColumnType("integer"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("Rep") - .HasColumnType("integer"); - - b.Property("StarGive") - .HasColumnType("integer"); - - b.Property("StarReceive") - .HasColumnType("integer"); - - b.Property("TotalExp") - .HasColumnType("integer"); - - b.Property("UserColor") - .HasColumnType("integer"); - - b.HasKey("UserId"); - - b.ToTable("AccountGlobals"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Highlight", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Highlights") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("Highlights"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGame", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Alive") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Participants") - .HasColumnType("integer"); - - b.Property("Round") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("HungerGames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameCustomChar", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("HungerGameCustomChars"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameDefault", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("HungerGameDefaults"); - - b.HasData( - new - { - Id = 1L, - Avatar = "https://i.imgur.com/XMjW8Qn.png", - Name = "Dia" - }, - new - { - Id = 2L, - Avatar = "https://i.imgur.com/7URjbvT.png", - Name = "Kanan" - }, - new - { - Id = 3L, - Avatar = "https://i.imgur.com/tPDON9P.png", - Name = "Yoshiko" - }, - new - { - Id = 4L, - Avatar = "https://i.imgur.com/dcB1loo.png", - Name = "Kongou" - }, - new - { - Id = 5L, - Avatar = "https://i.imgur.com/7GC7FvJ.png", - Name = "Haruna" - }, - new - { - Id = 6L, - Avatar = "https://i.imgur.com/8748bUL.png", - Name = "Yamato" - }, - new - { - Id = 7L, - Avatar = "https://i.imgur.com/VLsezdF.png", - Name = "Akagi" - }, - new - { - Id = 8L, - Avatar = "https://i.imgur.com/eyt9k8E.png", - Name = "Kaga" - }, - new - { - Id = 9L, - Avatar = "https://i.imgur.com/4XYg6ch.png", - Name = "Zero Two" - }, - new - { - Id = 10L, - Avatar = "https://i.imgur.com/Nl6WsbP.png", - Name = "Echidna" - }, - new - { - Id = 11L, - Avatar = "https://i.imgur.com/kF9b4SJ.png", - Name = "Emilia" - }, - new - { - Id = 12L, - Avatar = "https://i.imgur.com/y3bb8Sk.png", - Name = "Rem" - }, - new - { - Id = 13L, - Avatar = "https://i.imgur.com/5CcdVBE.png", - Name = "Ram" - }, - new - { - Id = 14L, - Avatar = "https://i.imgur.com/0VYBYEg.png", - Name = "Gura" - }, - new - { - Id = 15L, - Avatar = "https://i.imgur.com/rYa5iYc.png", - Name = "Shiki" - }, - new - { - Id = 16L, - Avatar = "https://i.imgur.com/PT8SsVB.png", - Name = "Chika" - }, - new - { - Id = 17L, - Avatar = "https://i.imgur.com/5xR0ImK.png", - Name = "Sora" - }, - new - { - Id = 18L, - Avatar = "https://i.imgur.com/U0NlfJd.png", - Name = "Nobuna" - }, - new - { - Id = 19L, - Avatar = "https://i.imgur.com/CI9Osi5.png", - Name = "Akame" - }, - new - { - Id = 20L, - Avatar = "https://i.imgur.com/GhSG97V.png", - Name = "Shiina" - }, - new - { - Id = 21L, - Avatar = "https://i.imgur.com/VyJf95i.png", - Name = "Bocchi" - }, - new - { - Id = 22L, - Avatar = "https://i.imgur.com/bv5ao8Z.png", - Name = "Enterprise" - }, - new - { - Id = 23L, - Avatar = "https://i.imgur.com/HoNwKi9.png", - Name = "Chocola" - }, - new - { - Id = 24L, - Avatar = "https://i.imgur.com/aijxHla.png", - Name = "Vanilla" - }, - new - { - Id = 25L, - Avatar = "https://i.imgur.com/Wxhd5WY.png", - Name = "Shiro" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameHistory", b => - { - b.Property("GameId") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("Date") - .HasColumnType("timestamp with time zone"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint"); - - b.HasKey("GameId"); - - b.ToTable("HungerGameHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameProfile", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Alive") - .HasColumnType("boolean"); - - b.Property("Avatar") - .HasColumnType("text"); - - b.Property("Bleeding") - .HasColumnType("boolean"); - - b.Property("Bot") - .HasColumnType("boolean"); - - b.Property("Bullets") - .HasColumnType("integer"); - - b.Property("FirstAid") - .HasColumnType("integer"); - - b.Property("Food") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("double precision"); - - b.Property("Hunger") - .HasColumnType("double precision"); - - b.Property("MeleeWeapon") - .HasColumnType("integer"); - - b.Property("Move") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("RangeWeapon") - .HasColumnType("integer"); - - b.Property("Stamina") - .HasColumnType("double precision"); - - b.Property("Thirst") - .HasColumnType("double precision"); - - b.Property("Tiredness") - .HasColumnType("double precision"); - - b.Property("Water") - .HasColumnType("integer"); - - b.Property("Weapons") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("HungerGameProfiles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.HungerGame.HungerGameStatus", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("CreditReward") - .HasColumnType("integer"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("ExpReward") - .HasColumnType("integer"); - - b.Property("GameId") - .HasColumnType("uuid"); - - b.Property("RoleReward") - .HasColumnType("bigint"); - - b.Property("SignUpChannel") - .HasColumnType("bigint"); - - b.Property("SignUpMessage") - .HasColumnType("text"); - - b.Property("SignUpStart") - .HasColumnType("timestamp with time zone"); - - b.Property("SpecialCreditReward") - .HasColumnType("integer"); - - b.Property("Stage") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("HungerGameStatus"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Inventory", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("ItemId") - .HasColumnType("integer"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId", "ItemId"); - - b.ToTable("Inventories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Account.Item", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("CriticalIncrease") - .HasColumnType("integer"); - - b.Property("DamageIncrease") - .HasColumnType("integer"); - - b.Property("DateAdded") - .HasColumnType("timestamp with time zone"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("HealthIncrease") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Sell") - .HasColumnType("integer"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Items"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.Property("AchievementId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AchievementDifficulty") - .HasColumnType("integer"); - - b.Property("AchievementNameId") - .HasColumnType("integer"); - - b.Property("AchievementTypeTypeId") - .HasColumnType("integer"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Global") - .HasColumnType("boolean"); - - b.Property("Hidden") - .HasColumnType("boolean"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Once") - .HasColumnType("boolean"); - - b.Property("Points") - .HasColumnType("integer"); - - b.Property("Requirement") - .HasColumnType("integer"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId"); - - b.HasIndex("AchievementNameId"); - - b.HasIndex("AchievementTypeTypeId"); - - b.ToTable("Achievements"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementName", b => - { - b.Property("AchievementNameId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("AchievementNameId"); - - b.ToTable("AchievementNames"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementTracker", b => - { - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Count") - .HasColumnType("integer"); - - b.HasKey("Type", "UserId"); - - b.ToTable("AchievementTrackers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementType", b => - { - b.Property("TypeId") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("TypeId"); - - b.ToTable("AchievementTypes"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.Property("AchievementId") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("TypeId") - .HasColumnType("integer"); - - b.HasKey("AchievementId", "UserId"); - - b.ToTable("AchievementUnlocks"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.ApprovalQueue", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Type") - .IsRequired() - .HasColumnType("text"); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ApprovalQueues"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Administration.Blacklist", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("ResponsibleUser") - .HasColumnType("bigint"); - - b.Property("Unban") - .HasColumnType("timestamp with time zone"); - - b.HasKey("GuildId"); - - b.ToTable("Blacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.DblAuth", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AuthKey") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("RoleIdReward") - .HasColumnType("bigint"); - - b.Property("SpecialCredit") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("DblAuths"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Advertise.VoteLog", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.Property("Type") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("VoteLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.AutoMessage.AutoMessage", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Interval") - .HasColumnType("interval"); - - b.Property("Message") - .HasColumnType("text"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("AutoMessages"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BoardConfig.Board", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Boarded") - .HasColumnType("timestamp with time zone"); - - b.Property("StarAmount") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "MessageId"); - - b.ToTable("Boards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameClass", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ChanceAvoid") - .HasColumnType("integer"); - - b.Property("ChanceCrit") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("bigint"); - - b.Property("ModifierAvoidance") - .HasColumnType("double precision"); - - b.Property("ModifierCriticalChance") - .HasColumnType("double precision"); - - b.Property("ModifierDamage") - .HasColumnType("double precision"); - - b.Property("ModifierHealth") - .HasColumnType("double precision"); - - b.Property("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("GameClasses"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameConfig", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("DefaultDamage") - .HasColumnType("integer"); - - b.Property("DefaultHealth") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("GameConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.BotGame.GameEnemy", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ClassId") - .HasColumnType("integer"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("Damage") - .HasColumnType("integer"); - - b.Property("Elite") - .HasColumnType("boolean"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Health") - .HasColumnType("integer"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Rare") - .HasColumnType("boolean"); - - b.HasKey("Id"); - - b.ToTable("GameEnemies"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubBlacklist", b => - { - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("BlackListUser") - .HasColumnType("bigint"); - - b.Property("IssuedUser") - .HasColumnType("bigint"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp with time zone"); - - b.HasKey("ClubId", "GuildId", "BlackListUser"); - - b.ToTable("ClubBlacklists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubInformation", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AdMessage") - .HasColumnType("bigint"); - - b.Property("AutoAdd") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("CreationDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IconUrl") - .HasColumnType("text"); - - b.Property("ImageUrl") - .HasColumnType("text"); - - b.Property("LeaderId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Public") - .HasColumnType("boolean"); - - b.Property("Role") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubInfos"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Club.ClubUser", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("ClubId") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("JoinDate") - .HasColumnType("timestamp with time zone"); - - b.Property("Rank") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.ToTable("ClubPlayers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.EventPayout", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Amount") - .HasColumnType("integer"); - - b.HasKey("GuildId", "UserId"); - - b.ToTable("EventPayouts"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.AdminConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("EmoteCountFilter") - .HasColumnType("integer"); - - b.Property("FilterAllInv") - .HasColumnType("boolean"); - - b.Property("FilterInvites") - .HasColumnType("boolean"); - - b.Property("FilterMsgLength") - .HasColumnType("integer"); - - b.Property("FilterUrls") - .HasColumnType("boolean"); - - b.Property("IgnoreAllChannels") - .HasColumnType("boolean"); - - b.Property("MentionCountFilter") - .HasColumnType("integer"); - - b.Property("MuteRole") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("AdminConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoardConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("BoardConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.BoostConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("CreditGain") - .HasColumnType("integer"); - - b.Property("ExpGain") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("SpecialCreditGain") - .HasColumnType("integer"); - - b.HasKey("GuildId"); - - b.ToTable("BoostConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ChannelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("DesignChannel") - .HasColumnType("bigint"); - - b.Property("EventChannel") - .HasColumnType("bigint"); - - b.Property("EventSchedulerChannel") - .HasColumnType("bigint"); - - b.Property("ModChannel") - .HasColumnType("bigint"); - - b.Property("QuestionAndAnswerChannel") - .HasColumnType("bigint"); - - b.Property("ReportChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableChannel") - .HasColumnType("bigint"); - - b.Property("SelfAssignableMessages") - .HasColumnType("bigint[]"); - - b.HasKey("GuildId"); - - b.ToTable("ChannelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.ClubConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AdvertisementChannel") - .HasColumnType("bigint"); - - b.Property("AutoPrune") - .HasColumnType("boolean"); - - b.Property("ChannelCategory") - .HasColumnType("bigint"); - - b.Property("ChannelRequiredAmount") - .HasColumnType("integer"); - - b.Property("ChannelRequiredLevel") - .HasColumnType("integer"); - - b.Property("EnableVoiceChannel") - .HasColumnType("boolean"); - - b.Property("RoleEnabled") - .HasColumnType("boolean"); - - b.HasKey("GuildId"); - - b.ToTable("ClubConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.CurrencyConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("CurrencyName") - .HasColumnType("text"); - - b.Property("CurrencySign") - .HasColumnType("text"); - - b.Property("EmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("SpecialCurrencyName") - .HasColumnType("text"); - - b.Property("SpecialCurrencySign") - .HasColumnType("text"); - - b.Property("SpecialEmoteCurrency") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("CurrencyConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.DropConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Emote") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("DropConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LevelConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("BoostExpMultiplier") - .ValueGeneratedOnAdd() - .HasColumnType("double precision") - .HasDefaultValue(1.0); - - b.Property("Decay") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("ExpDisabled") - .HasColumnType("boolean"); - - b.Property("StackLvlRoles") - .HasColumnType("boolean"); - - b.Property("TextExpEnabled") - .HasColumnType("boolean"); - - b.Property("TextExpMultiplier") - .HasColumnType("double precision"); - - b.Property("VoiceExpEnabled") - .HasColumnType("boolean"); - - b.Property("VoiceExpMultiplier") - .HasColumnType("double precision"); - - b.HasKey("GuildId"); - - b.ToTable("LevelConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.LoggingConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("LogAutoMod") - .HasColumnType("bigint"); - - b.Property("LogAvi") - .HasColumnType("bigint"); - - b.Property("LogBan") - .HasColumnType("bigint"); - - b.Property("LogJoin") - .HasColumnType("bigint"); - - b.Property("LogMsg") - .HasColumnType("bigint"); - - b.Property("LogReaction") - .HasColumnType("bigint"); - - b.Property("LogVoice") - .HasColumnType("numeric(20,0)"); - - b.Property("LogWarn") - .HasColumnType("bigint"); - - b.Property("ReactionWebhook") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("LoggingConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.SuggestionConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("EmoteNo") - .HasColumnType("text"); - - b.Property("EmoteYes") - .HasColumnType("text"); - - b.HasKey("GuildId"); - - b.ToTable("SuggestionConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.Guild.WelcomeConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AutoDelOnLeave") - .HasColumnType("boolean"); - - b.Property("Banner") - .HasColumnType("boolean"); - - b.Property("Channel") - .HasColumnType("bigint"); - - b.Property("IgnoreNew") - .HasColumnType("timestamp with time zone"); - - b.Property("Limit") - .HasColumnType("integer"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("Reward") - .HasColumnType("integer"); - - b.Property("TimeToDelete") - .HasColumnType("interval"); - - b.HasKey("GuildId"); - - b.ToTable("WelcomeConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.GuildConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("AnimeAirChannel") - .HasColumnType("bigint"); - - b.Property("AutomaticEventSchedule") - .HasColumnType("boolean"); - - b.Property("EmbedColor") - .HasColumnType("integer"); - - b.Property("HungerGameChannel") - .HasColumnType("bigint"); - - b.Property("MusicChannel") - .HasColumnType("bigint"); - - b.Property("MusicVcChannel") - .HasColumnType("bigint"); - - b.Property("MvpChannel") - .HasColumnType("bigint"); - - b.Property("Prefix") - .HasColumnType("text"); - - b.Property("Premium") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.HasKey("GuildId"); - - b.ToTable("GuildConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.IgnoreChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("IgnoreChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpEvent", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Multiplier") - .HasColumnType("double precision"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("GuildId"); - - b.ToTable("LevelExpEvents"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelExpReduction", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.Property("ChannelType") - .IsRequired() - .HasColumnType("text"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LevelExpReductions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LevelReward", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Level") - .HasColumnType("integer"); - - b.Property("NoDecay") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(false); - - b.Property("Role") - .HasColumnType("bigint"); - - b.Property("Stackable") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "Level"); - - b.ToTable("LevelRewards"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.LootChannel", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ChannelId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "ChannelId"); - - b.ToTable("LootChannels"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.SelfAssignAbleRole", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("EmoteMessageFormat") - .HasColumnType("text"); - - b.Property("EmoteReactFormat") - .HasColumnType("text"); - - b.Property("Exclusive") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("SelfAssignAbleRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Config.WelcomeBanner", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("AvatarSize") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(60); - - b.Property("AviPlaceX") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(10); - - b.Property("AviPlaceY") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(10); - - b.Property("IsNsfw") - .HasColumnType("boolean"); - - b.Property("TextPlaceX") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(245); - - b.Property("TextPlaceY") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(40); - - b.Property("TextSize") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .HasDefaultValue(33); - - b.Property("UploadTimeOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Uploader") - .HasColumnType("bigint"); - - b.Property("Url") - .HasColumnType("text"); - - b.HasKey("GuildId", "Id"); - - b.ToTable("WelcomeBanners"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("AccountAgeRequirement") - .HasColumnType("interval"); - - b.Property("Active") - .HasColumnType("boolean"); - - b.Property("CloseAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("LevelRequirement") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("ServerAgeRequirement") - .HasColumnType("interval"); - - b.Property("Stack") - .HasColumnType("boolean"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("WinnerAmount") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("Giveaways"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayHistory", b => - { - b.Property("Id") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("ClosedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("CreatedAtOffset") - .HasColumnType("timestamp with time zone"); - - b.Property("Creator") - .HasColumnType("bigint"); - - b.Property("Description") - .HasColumnType("text"); - - b.Property("IdNum") - .HasColumnType("integer"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("Winner") - .HasColumnType("bigint[]"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("GiveawayHistories"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property("Entry") - .HasColumnType("timestamp with time zone"); - - b.Property("GiveawayId") - .HasColumnType("uuid"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id"); - - b.HasIndex("GiveawayId"); - - b.ToTable("GiveawayParticipants"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Internal.Log", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("CallSite") - .HasColumnType("text"); - - b.Property("Exception") - .HasColumnType("text"); - - b.Property("Level") - .HasColumnType("text"); - - b.Property("Logger") - .HasColumnType("text"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("TimeStamp") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Logs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.ModLog", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Action") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("ModId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("ModLogs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.MuteTimer", b => - { - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.HasKey("UserId", "GuildId"); - - b.ToTable("MuteTimers"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Report", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Attachment") - .HasColumnType("text"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("Message") - .HasColumnType("text"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Reports"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Suggestion", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Date") - .HasColumnType("timestamp without time zone"); - - b.Property("MessageId") - .HasColumnType("bigint"); - - b.Property("Response") - .HasColumnType("text"); - - b.Property("ResponseUser") - .HasColumnType("bigint"); - - b.Property("Status") - .HasColumnType("boolean"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Suggestions"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Moderation.Warn", b => - { - b.Property("Id") - .HasColumnType("integer"); - - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Moderator") - .HasColumnType("numeric(20,0)"); - - b.Property("MuteTimer") - .HasColumnType("interval"); - - b.Property("Reason") - .HasColumnType("text"); - - b.Property("Time") - .HasColumnType("timestamp without time zone"); - - b.Property("Type") - .HasColumnType("integer"); - - b.Property("UserId") - .HasColumnType("bigint"); - - b.Property("Valid") - .HasColumnType("boolean"); - - b.HasKey("Id", "GuildId"); - - b.ToTable("Warns"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.MusicConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("TextChId") - .HasColumnType("bigint"); - - b.Property("VoiceChId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MusicConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Music.Playlist", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("Name") - .HasColumnType("text"); - - b.Property>("Songs") - .HasColumnType("text[]"); - - b.HasKey("GuildId", "Name"); - - b.ToTable("Playlists"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Premium.MvpConfig", b => - { - b.Property("GuildId") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None); - - b.Property("Count") - .HasColumnType("integer"); - - b.Property("Day") - .IsRequired() - .HasColumnType("text"); - - b.Property("Disabled") - .ValueGeneratedOnAdd() - .HasColumnType("boolean") - .HasDefaultValue(true); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId"); - - b.ToTable("MvpConfigs"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Profile.Background", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property("BackgroundUrl") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Backgrounds"); - - b.HasData( - new - { - Id = 1, - BackgroundUrl = "https://i.imgur.com/epIb29P.png" - }, - new - { - Id = 2, - BackgroundUrl = "https://i.imgur.com/04PbzvT.png" - }, - new - { - Id = 3, - BackgroundUrl = "https://i.imgur.com/5ojmh76.png" - }, - new - { - Id = 4, - BackgroundUrl = "https://i.imgur.com/OAMpNDh.png" - }, - new - { - Id = 5, - BackgroundUrl = "https://i.imgur.com/KXO5bx5.png" - }, - new - { - Id = 6, - BackgroundUrl = "https://i.imgur.com/5h5zZ7C.png" - }); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Stores.ServerStore", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.Property("Price") - .HasColumnType("integer"); - - b.Property("SpecialCredit") - .HasColumnType("boolean"); - - b.HasKey("GuildId", "RoleId"); - - b.ToTable("ServerStores"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.VoiceRoles", b => - { - b.Property("GuildId") - .HasColumnType("bigint"); - - b.Property("VoiceId") - .HasColumnType("bigint"); - - b.Property("RoleId") - .HasColumnType("bigint"); - - b.HasKey("GuildId", "VoiceId"); - - b.ToTable("VoiceRoles"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementMeta", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementName", "AchievementName") - .WithMany() - .HasForeignKey("AchievementNameId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementType", "AchievementType") - .WithMany() - .HasForeignKey("AchievementTypeTypeId"); - - b.Navigation("AchievementName"); - - b.Navigation("AchievementType"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Achievement.AchievementUnlock", b => - { - b.HasOne("Hanekawa.Database.Tables.Achievement.AchievementMeta", "Achievement") - .WithMany() - .HasForeignKey("AchievementId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Achievement"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.GiveawayParticipant", b => - { - b.HasOne("Hanekawa.Database.Tables.Giveaway.Giveaway", "Giveaway") - .WithMany("Participants") - .HasForeignKey("GiveawayId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Giveaway"); - }); - - modelBuilder.Entity("Hanekawa.Database.Tables.Giveaway.Giveaway", b => - { - b.Navigation("Participants"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Hanekawa.Database/Tables/Account/Account.cs b/Hanekawa.Database/Tables/Account/Account.cs deleted file mode 100644 index 785a6952..00000000 --- a/Hanekawa.Database/Tables/Account/Account.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Account -{ - public class Account - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - - public bool Active { get; set; } = true; - - // Economy - public int Credit { get; set; } = 0; - public int CreditSpecial { get; set; } = 0; - - public DateTime DailyCredit { get; set; } = DateTime.UtcNow; - - // Level - public int Level { get; set; } = 1; - public int Exp { get; set; } = 0; - public int TotalExp { get; set; } = 0; - public int Decay { get; set; } = 0; - - public DateTime VoiceExpTime { get; set; } = DateTime.UtcNow; - - // Class Profile Role - public int Class { get; set; } = 1; - public string ProfilePic { get; set; } = null; - public int Rep { get; set; } = 0; - public DateTime RepCooldown { get; set; } = DateTime.UtcNow; - - public int GameKillAmount { get; set; } = 0; - - // Stats - public DateTime? FirstMessage { get; set; } = null; - public DateTime LastMessage { get; set; } = DateTime.UtcNow; - public TimeSpan StatVoiceTime { get; set; } = TimeSpan.Zero; - public int Sessions { get; set; } = 0; - public ulong StatMessages { get; set; } = 0; - - // Board - public int StarGiven { get; set; } = 0; - - public int StarReceived { get; set; } = 0; - - // Misc - public DateTime ChannelVoiceTime { get; set; } = DateTime.UtcNow; - - // Mvp - public int MvpCount { get; set; } = 0; - public bool MvpOptOut { get; set; } = false; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/AccountGlobal.cs b/Hanekawa.Database/Tables/Account/AccountGlobal.cs deleted file mode 100644 index 0cfe5f9d..00000000 --- a/Hanekawa.Database/Tables/Account/AccountGlobal.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Disqord; - -namespace Hanekawa.Database.Tables.Account -{ - public class AccountGlobal - { - public ulong UserId { get; set; } - public int Level { get; set; } = 1; - public int Exp { get; set; } = 0; - public int TotalExp { get; set; } = 0; - public int Rep { get; set; } = 0; - public int Credit { get; set; } = 0; - public int StarReceive { get; set; } = 0; - public int StarGive { get; set; } = 0; - public uint UserColor { get; set; } = (uint)Color.Purple.RawValue; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Achievement/AchievementDifficulty.cs b/Hanekawa.Database/Tables/Account/Achievement/AchievementDifficulty.cs deleted file mode 100644 index 4107edb9..00000000 --- a/Hanekawa.Database/Tables/Account/Achievement/AchievementDifficulty.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Database.Tables.Achievement -{ - public enum AchievementDifficulty - { - Normal, - Rare, - Epic, - Legendary - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Achievement/AchievementMeta.cs b/Hanekawa.Database/Tables/Account/Achievement/AchievementMeta.cs deleted file mode 100644 index 5608167f..00000000 --- a/Hanekawa.Database/Tables/Account/Achievement/AchievementMeta.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Hanekawa.Database.Tables.Achievement -{ - public class AchievementMeta - { - public int AchievementId { get; set; } - public string Name { get; set; } = "Test"; - public string Description { get; set; } = "Test"; - public int Requirement { get; set; } = 1; - public bool Once { get; set; } = true; - public int? Reward { get; set; } = null; - public int Points { get; set; } = 10; - public string ImageUrl { get; set; } = "test"; - public bool Hidden { get; set; } = false; - public bool Global { get; set; } = true; - - public int AchievementNameId { get; set; } - public AchievementName AchievementName { get; set; } - - public int TypeId { get; set; } - public AchievementType AchievementType { get; set; } - - public AchievementDifficulty AchievementDifficulty { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Achievement/AchievementName.cs b/Hanekawa.Database/Tables/Account/Achievement/AchievementName.cs deleted file mode 100644 index 523239a0..00000000 --- a/Hanekawa.Database/Tables/Account/Achievement/AchievementName.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Database.Tables.Achievement -{ - public class AchievementName - { - public int AchievementNameId { get; set; } - public string Name { get; set; } = "Test Name"; - public string Description { get; set; } = "Test Desc"; - public bool Stackable { get; set; } = false; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Achievement/AchievementTracker.cs b/Hanekawa.Database/Tables/Account/Achievement/AchievementTracker.cs deleted file mode 100644 index 8e14b2d5..00000000 --- a/Hanekawa.Database/Tables/Account/Achievement/AchievementTracker.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.Achievement -{ - public class AchievementTracker - { - public int Type { get; set; } - public ulong UserId { get; set; } - public int Count { get; set; } = 1; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Achievement/AchievementType.cs b/Hanekawa.Database/Tables/Account/Achievement/AchievementType.cs deleted file mode 100644 index c570627e..00000000 --- a/Hanekawa.Database/Tables/Account/Achievement/AchievementType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Database.Tables.Achievement -{ - public class AchievementType - { - public int TypeId { get; set; } - public string Name { get; set; } = "test"; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Achievement/AchievementUnlock.cs b/Hanekawa.Database/Tables/Account/Achievement/AchievementUnlock.cs deleted file mode 100644 index ecebff42..00000000 --- a/Hanekawa.Database/Tables/Account/Achievement/AchievementUnlock.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Hanekawa.Database.Tables.Achievement -{ - public class AchievementUnlock - { - public int AchievementId { get; set; } - public AchievementMeta Achievement { get; set; } - - public int TypeId { get; set; } - public ulong UserId { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Highlight.cs b/Hanekawa.Database/Tables/Account/Highlight.cs deleted file mode 100644 index 62a1afc7..00000000 --- a/Hanekawa.Database/Tables/Account/Highlight.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.Account -{ - public class Highlight - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public string[] Highlights { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/HungerGame/HungerGame.cs b/Hanekawa.Database/Tables/Account/HungerGame/HungerGame.cs deleted file mode 100644 index 177177e5..00000000 --- a/Hanekawa.Database/Tables/Account/HungerGame/HungerGame.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Account.HungerGame -{ - public class HungerGame - { - public Guid Id { get; set; } - public ulong GuildId { get; set; } - public int Round { get; set; } - public int Alive { get; set; } - public int Participants { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameCustomChar.cs b/Hanekawa.Database/Tables/Account/HungerGame/HungerGameCustomChar.cs deleted file mode 100644 index 03069ac4..00000000 --- a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameCustomChar.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Database.Tables.Account.HungerGame -{ - public class HungerGameCustomChar - { - public ulong Id { get; set; } - public ulong GuildId { get; set; } - public string Name { get; set; } - public string Avatar { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameDefault.cs b/Hanekawa.Database/Tables/Account/HungerGame/HungerGameDefault.cs deleted file mode 100644 index e2a6bd2a..00000000 --- a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameDefault.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.Account.HungerGame -{ - public class HungerGameDefault - { - public ulong Id { get; set; } - public string Name { get; set; } - public string Avatar { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameHistory.cs b/Hanekawa.Database/Tables/Account/HungerGame/HungerGameHistory.cs deleted file mode 100644 index ac03cef7..00000000 --- a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameHistory.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Account.HungerGame -{ - public class HungerGameHistory - { - public Guid GameId { get; set; } - public ulong GuildId { get; set; } - public ulong Winner { get; set; } - public DateTimeOffset Date { get; set; } - public int ExpReward { get; set; } = 0; - public int CreditReward { get; set; } = 0; - public int SpecialCreditReward { get; set; } = 0; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameProfile.cs b/Hanekawa.Database/Tables/Account/HungerGame/HungerGameProfile.cs deleted file mode 100644 index 3fd2a4b3..00000000 --- a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameProfile.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Hanekawa.Shared.Game.HungerGame; - -namespace Hanekawa.Database.Tables.Account.HungerGame -{ - public class HungerGameProfile - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public bool Bot { get; set; } = false; - - public string Name { get; set; } = "Test Unit"; - public string Avatar { get; set; } = null; - - public bool Alive { get; set; } = true; - public double Health { get; set; } = 100; - public double Stamina { get; set; } = 100; - public bool Bleeding { get; set; } = false; - - public double Hunger { get; set; } = 100; - public double Thirst { get; set; } = 100; - public double Tiredness { get; set; } = 0; - public ActionType Move { get; set; } = ActionType.None; - - public int Food { get; set; } = 0; - public int Water { get; set; } = 0; - public int FirstAid { get; set; } = 0; - public int Weapons { get; set; } = 0; - public int MeleeWeapon { get; set; } = 0; - public int RangeWeapon { get; set; } = 0; - public int Bullets { get; set; } = 0; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameStatus.cs b/Hanekawa.Database/Tables/Account/HungerGame/HungerGameStatus.cs deleted file mode 100644 index 2fb571e0..00000000 --- a/Hanekawa.Database/Tables/Account/HungerGame/HungerGameStatus.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using Hanekawa.Shared.Game.HungerGame; - -namespace Hanekawa.Database.Tables.Account.HungerGame -{ - public class HungerGameStatus - { - public ulong GuildId { get; set; } - public ulong? SignUpChannel { get; set; } = null; - public ulong? EventChannel { get; set; } = null; - public string EmoteMessageFormat { get; set; } - - public HungerGameStage Stage { get; set; } = HungerGameStage.Closed; - public DateTimeOffset SignUpStart { get; set; } - public string SignUpMessage { get; set; } - public Guid? GameId { get; set; } = null; - - // Rewards - public int ExpReward { get; set; } = 0; - public int CreditReward { get; set; } = 0; - public int SpecialCreditReward { get; set; } = 0; - public ulong? RoleReward { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Inventory.cs b/Hanekawa.Database/Tables/Account/Inventory.cs deleted file mode 100644 index 62494e92..00000000 --- a/Hanekawa.Database/Tables/Account/Inventory.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Database.Tables.Account -{ - public class Inventory - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public int ItemId { get; set; } - public int Amount { get; set; } = 1; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Item.cs b/Hanekawa.Database/Tables/Account/Item.cs deleted file mode 100644 index bb8c2dc2..00000000 --- a/Hanekawa.Database/Tables/Account/Item.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using Hanekawa.Shared; - -namespace Hanekawa.Database.Tables.Account -{ - public class Item - { - public int Id { get; set; } - public string Name { get; set; } - public int Sell { get; set; } - public ItemType Type { get; set; } = ItemType.Trash; - - public ulong? GuildId { get; set; } = null; - public ulong? Role { get; set; } = null; - - public int HealthIncrease { get; set; } = 0; - public int DamageIncrease { get; set; } = 0; - public int CriticalIncrease { get; set; } = 0; - - public string ImageUrl { get; set; } - - public DateTimeOffset DateAdded { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Profile/Background.cs b/Hanekawa.Database/Tables/Account/Profile/Background.cs deleted file mode 100644 index e4946dfa..00000000 --- a/Hanekawa.Database/Tables/Account/Profile/Background.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Database.Tables.Profile -{ - public class Background - { - public int Id { get; set; } - public string BackgroundUrl { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/ShipGame/GameClass.cs b/Hanekawa.Database/Tables/Account/ShipGame/GameClass.cs deleted file mode 100644 index 4e12d386..00000000 --- a/Hanekawa.Database/Tables/Account/ShipGame/GameClass.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Hanekawa.Database.Tables.BotGame -{ - public class GameClass - { - public int Id { get; set; } - public string Name { get; set; } = "test"; - public uint LevelRequirement { get; set; } = 1; - - public int ChanceAvoid { get; set; } = 2; - public int ChanceCrit { get; set; } = 2; - - public double ModifierHealth { get; set; } = 1.2; - public double ModifierDamage { get; set; } = 1.2; - public double ModifierAvoidance { get; set; } = 1.2; - public double ModifierCriticalChance { get; set; } = 1.2; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/ShipGame/GameConfig.cs b/Hanekawa.Database/Tables/Account/ShipGame/GameConfig.cs deleted file mode 100644 index 4e2662d4..00000000 --- a/Hanekawa.Database/Tables/Account/ShipGame/GameConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.BotGame -{ - public class GameConfig - { - public int Id { get; set; } - public int DefaultHealth { get; set; } = 10; - public int DefaultDamage { get; set; } = 1; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/ShipGame/GameEnemy.cs b/Hanekawa.Database/Tables/Account/ShipGame/GameEnemy.cs deleted file mode 100644 index 19d179a8..00000000 --- a/Hanekawa.Database/Tables/Account/ShipGame/GameEnemy.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Hanekawa.Database.Tables.BotGame -{ - public class GameEnemy - { - public int Id { get; set; } - public string Name { get; set; } = "test"; - - public bool Elite { get; set; } = false; - public bool Rare { get; set; } = false; - - public string ImageUrl { get; set; } = null; - - public int Health { get; set; } = 100; - public int Damage { get; set; } = 10; - - public int ClassId { get; set; } = 1; - - public int ExpGain { get; set; } = 10; - public int CreditGain { get; set; } = 10; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Account/Stores/ServerStore.cs b/Hanekawa.Database/Tables/Account/Stores/ServerStore.cs deleted file mode 100644 index 18709459..00000000 --- a/Hanekawa.Database/Tables/Account/Stores/ServerStore.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Database.Tables.Stores -{ - public class ServerStore - { - public ulong GuildId { get; set; } - public ulong RoleId { get; set; } - public int Price { get; set; } - public bool SpecialCredit { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Administration/ApprovalQueue.cs b/Hanekawa.Database/Tables/Administration/ApprovalQueue.cs deleted file mode 100644 index acd33de6..00000000 --- a/Hanekawa.Database/Tables/Administration/ApprovalQueue.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using Hanekawa.Shared; - -namespace Hanekawa.Database.Tables.Administration -{ - public class ApprovalQueue - { - // TODO: Add approval queue - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong Uploader { get; set; } - public string Url { get; set; } - public ApprovalQueueType Type { get; set; } - public DateTimeOffset UploadTimeOffset { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Administration/Blacklist.cs b/Hanekawa.Database/Tables/Administration/Blacklist.cs deleted file mode 100644 index 6c95a73c..00000000 --- a/Hanekawa.Database/Tables/Administration/Blacklist.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Administration -{ - public class Blacklist - { - public ulong GuildId { get; set; } - public string Reason { get; set; } = "No reason provided"; - public ulong ResponsibleUser { get; set; } - public DateTimeOffset? Unban { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Advertise/DblAuth.cs b/Hanekawa.Database/Tables/Advertise/DblAuth.cs deleted file mode 100644 index e9f68c8d..00000000 --- a/Hanekawa.Database/Tables/Advertise/DblAuth.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Advertise -{ - public class DblAuth - { - public ulong GuildId { get; set; } - public Guid AuthKey { get; set; } - - public int ExpGain { get; set; } = 0; - public int CreditGain { get; set; } = 0; - public int SpecialCredit { get; set; } = 0; - - public ulong? RoleIdReward { get; set; } = null; - public string Message { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Advertise/VoteLog.cs b/Hanekawa.Database/Tables/Advertise/VoteLog.cs deleted file mode 100644 index 84c99f7b..00000000 --- a/Hanekawa.Database/Tables/Advertise/VoteLog.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Advertise -{ - public class VoteLog - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public DateTimeOffset Time { get; set; } = DateTimeOffset.UtcNow; - public string Type { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/AutoMessage/AutoMessage.cs b/Hanekawa.Database/Tables/AutoMessage/AutoMessage.cs deleted file mode 100644 index 4c4c8a66..00000000 --- a/Hanekawa.Database/Tables/AutoMessage/AutoMessage.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.AutoMessage -{ - public class AutoMessage - { - public ulong GuildId { get; set; } - public ulong Creator { get; set; } - public ulong ChannelId { get; set; } - public string Name { get; set; } - public string Message { get; set; } - public TimeSpan Interval { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/BoardConfig/Board.cs b/Hanekawa.Database/Tables/BoardConfig/Board.cs deleted file mode 100644 index 052ba817..00000000 --- a/Hanekawa.Database/Tables/BoardConfig/Board.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.BoardConfig -{ - public class Board - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public ulong MessageId { get; set; } - public int StarAmount { get; set; } = 1; - public DateTimeOffset? Boarded { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Club/ClubBlacklist.cs b/Hanekawa.Database/Tables/Club/ClubBlacklist.cs deleted file mode 100644 index cfbc50f2..00000000 --- a/Hanekawa.Database/Tables/Club/ClubBlacklist.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Club -{ - public class ClubBlacklist - { - public int ClubId { get; set; } - public ulong GuildId { get; set; } - public ulong BlackListUser { get; set; } - public ulong IssuedUser { get; set; } - public string Reason { get; set; } = "No reason provided"; - public DateTimeOffset Time { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Club/ClubInformation.cs b/Hanekawa.Database/Tables/Club/ClubInformation.cs deleted file mode 100644 index 6c9bbceb..00000000 --- a/Hanekawa.Database/Tables/Club/ClubInformation.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Club -{ - public class ClubInformation - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong LeaderId { get; set; } - public string Name { get; set; } = "N/A"; - public string Description { get; set; } = "N/A"; - public string IconUrl { get; set; } - public string ImageUrl { get; set; } - public bool Public { get; set; } - public bool AutoAdd { get; set; } - public ulong? AdMessage { get; set; } - public ulong? Channel { get; set; } - public ulong? Role { get; set; } - public DateTimeOffset CreationDate { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Club/ClubUser.cs b/Hanekawa.Database/Tables/Club/ClubUser.cs deleted file mode 100644 index a4d162f4..00000000 --- a/Hanekawa.Database/Tables/Club/ClubUser.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Club -{ - public class ClubUser - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public int ClubId { get; set; } - public int Rank { get; set; } = 3; - public DateTimeOffset JoinDate { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/EventPayout.cs b/Hanekawa.Database/Tables/Config/EventPayout.cs deleted file mode 100644 index bd8fbba9..00000000 --- a/Hanekawa.Database/Tables/Config/EventPayout.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.Config -{ - public class EventPayout - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public int Amount { get; set; } = 100; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/Guild/AdminConfig.cs b/Hanekawa.Database/Tables/Config/Guild/AdminConfig.cs deleted file mode 100644 index 13373f7d..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/AdminConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class AdminConfig - { - public ulong GuildId { get; set; } - public ulong? MuteRole { get; set; } - public bool FilterInvites { get; set; } - public bool IgnoreAllChannels { get; set; } - public int? FilterMsgLength { get; set; } - public bool FilterUrls { get; set; } - public bool FilterAllInv { get; set; } - public int? EmoteCountFilter { get; set; } - public int? MentionCountFilter { get; set; } - } -} diff --git a/Hanekawa.Database/Tables/Config/Guild/BoardConfig.cs b/Hanekawa.Database/Tables/Config/Guild/BoardConfig.cs deleted file mode 100644 index d2dd754b..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/BoardConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class BoardConfig - { - public ulong GuildId { get; set; } - public string Emote { get; set; } - public ulong? Channel { get; set; } = null; - } -} diff --git a/Hanekawa.Database/Tables/Config/Guild/BoostConfig.cs b/Hanekawa.Database/Tables/Config/Guild/BoostConfig.cs deleted file mode 100644 index d718f960..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/BoostConfig.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class BoostConfig - { - public ulong GuildId { get; set; } - public ulong? ChannelId { get; set; } = null; - public string Message { get; set; } = null; - public int CreditGain { get; set; } = 0; - public int SpecialCreditGain { get; set; } = 0; - public int ExpGain { get; set; } = 0; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/Guild/ChannelConfig.cs b/Hanekawa.Database/Tables/Config/Guild/ChannelConfig.cs deleted file mode 100644 index 0cc7c225..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/ChannelConfig.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Generic; - -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class ChannelConfig - { - public ulong GuildId { get; set; } - public ulong? ReportChannel { get; set; } = null; - public ulong? EventChannel { get; set; } = null; - public ulong? EventSchedulerChannel { get; set; } = null; - public ulong? ModChannel { get; set; } = null; - public ulong? DesignChannel { get; set; } = null; - public ulong? QuestionAndAnswerChannel { get; set; } = null; - - public ulong? SelfAssignableChannel { get; set; } = null; - public ulong[] SelfAssignableMessages { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/Guild/ClubConfig.cs b/Hanekawa.Database/Tables/Config/Guild/ClubConfig.cs deleted file mode 100644 index 032f1db0..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/ClubConfig.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class ClubConfig - { - public ulong GuildId { get; set; } - public ulong? ChannelCategory { get; set; } = null; - public ulong? AdvertisementChannel { get; set; } = null; - public bool EnableVoiceChannel { get; set; } = false; - public int ChannelRequiredAmount { get; set; } = 4; - public int ChannelRequiredLevel { get; set; } = 40; - public bool AutoPrune { get; set; } = false; - public bool RoleEnabled { get; set; } = false; - } -} diff --git a/Hanekawa.Database/Tables/Config/Guild/CurrencyConfig.cs b/Hanekawa.Database/Tables/Config/Guild/CurrencyConfig.cs deleted file mode 100644 index 767caade..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/CurrencyConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class CurrencyConfig - { - public ulong GuildId { get; set; } - public bool EmoteCurrency { get; set; } = false; - public string CurrencyName { get; set; } = "Credit"; - public string CurrencySign { get; set; } = "$"; - public bool SpecialEmoteCurrency { get; set; } = false; - public string SpecialCurrencyName { get; set; } = "Special credit"; - public string SpecialCurrencySign { get; set; } = "$"; - } -} diff --git a/Hanekawa.Database/Tables/Config/Guild/DropConfig.cs b/Hanekawa.Database/Tables/Config/Guild/DropConfig.cs deleted file mode 100644 index 51aee424..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/DropConfig.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class DropConfig - { - public ulong GuildId { get; set; } - public string Emote { get; set; } - } -} diff --git a/Hanekawa.Database/Tables/Config/Guild/LevelConfig.cs b/Hanekawa.Database/Tables/Config/Guild/LevelConfig.cs deleted file mode 100644 index 0d13761b..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/LevelConfig.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class LevelConfig - { - public ulong GuildId { get; set; } - public double TextExpMultiplier { get; set; } = 1; - public double VoiceExpMultiplier { get; set; } = 1; - public double BoostExpMultiplier { get; set; } = 1; - public bool Decay { get; set; } = false; - public bool ExpDisabled { get; set; } = false; - public bool VoiceExpEnabled { get; set; } = true; - public bool TextExpEnabled { get; set; } = true; - public bool StackLvlRoles { get; set; } = true; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/Guild/LoggingConfig.cs b/Hanekawa.Database/Tables/Config/Guild/LoggingConfig.cs deleted file mode 100644 index 16daac12..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/LoggingConfig.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class LoggingConfig - { - public ulong GuildId { get; set; } - public ulong? LogJoin { get; set; } = null; - public ulong? LogMsg { get; set; } = null; - public ulong? LogBan { get; set; } = null; - public ulong? LogAvi { get; set; } = null; - public ulong? LogWarn { get; set; } = null; - public ulong? LogAutoMod { get; set; } = null; - public ulong? LogVoice { get; set; } = null; - public ulong? LogReaction { get; set; } = null; - public string ReactionWebhook { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/Guild/SuggestionConfig.cs b/Hanekawa.Database/Tables/Config/Guild/SuggestionConfig.cs deleted file mode 100644 index 4734998d..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/SuggestionConfig.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class SuggestionConfig - { - public ulong GuildId { get; set; } - public ulong? Channel { get; set; } = null; - public string EmoteYes { get; set; } - public string EmoteNo { get; set; } - } -} diff --git a/Hanekawa.Database/Tables/Config/Guild/WelcomeConfig.cs b/Hanekawa.Database/Tables/Config/Guild/WelcomeConfig.cs deleted file mode 100644 index 6d6ca11c..00000000 --- a/Hanekawa.Database/Tables/Config/Guild/WelcomeConfig.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Config.Guild -{ - public class WelcomeConfig - { - public ulong GuildId { get; set; } - public ulong? Channel { get; set; } = null; - public int Limit { get; set; } = 4; - public bool Banner { get; set; } = false; - public string Message { get; set; } - public int? Reward { get; set; } = null; - public TimeSpan? TimeToDelete { get; set; } = null; - public bool AutoDelOnLeave { get; set; } = false; - public DateTimeOffset? IgnoreNew { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/GuildConfig.cs b/Hanekawa.Database/Tables/Config/GuildConfig.cs deleted file mode 100644 index 37e92ef1..00000000 --- a/Hanekawa.Database/Tables/Config/GuildConfig.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; - -namespace Hanekawa.Database.Tables.Config -{ - public class GuildConfig - { - public ulong GuildId { get; set; } - public string Prefix { get; set; } = "h."; - public bool Premium { get; set; } = false; - public uint EmbedColor { get; set; } - - // Premium - public ulong? AnimeAirChannel { get; set; } = null; - public bool AutomaticEventSchedule { get; set; } = false; - public ulong? MvpChannel { get; set; } = null; - public ulong? HungerGameChannel { get; set; } = null; - - //Music Settings - public ulong? MusicChannel { get; set; } = null; - public ulong? MusicVcChannel { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/IgnoreChannel.cs b/Hanekawa.Database/Tables/Config/IgnoreChannel.cs deleted file mode 100644 index 023325f7..00000000 --- a/Hanekawa.Database/Tables/Config/IgnoreChannel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Database.Tables.Config -{ - public class IgnoreChannel - { - public ulong GuildId { get; set; } - public ulong ChannelId { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/LevelExpEvent.cs b/Hanekawa.Database/Tables/Config/LevelExpEvent.cs deleted file mode 100644 index b66008f1..00000000 --- a/Hanekawa.Database/Tables/Config/LevelExpEvent.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Config -{ - public class LevelExpEvent - { - public ulong GuildId { get; set; } - public ulong? ChannelId { get; set; } - public ulong? MessageId { get; set; } - public double Multiplier { get; set; } - public DateTime Time { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/LevelExpReduction.cs b/Hanekawa.Database/Tables/Config/LevelExpReduction.cs deleted file mode 100644 index e614169c..00000000 --- a/Hanekawa.Database/Tables/Config/LevelExpReduction.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Hanekawa.Shared; - -namespace Hanekawa.Database.Tables.Config -{ - public class LevelExpReduction - { - public ulong GuildId { get; set; } - public ulong ChannelId { get; set; } - public ChannelType ChannelType { get; set; } = ChannelType.Text; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/LevelReward.cs b/Hanekawa.Database/Tables/Config/LevelReward.cs deleted file mode 100644 index 5b509a90..00000000 --- a/Hanekawa.Database/Tables/Config/LevelReward.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Hanekawa.Database.Tables.Config -{ - public class LevelReward - { - public ulong GuildId { get; set; } - public int Level { get; set; } - public ulong Role { get; set; } - public bool Stackable { get; set; } = false; - public bool NoDecay { get; set; } = false; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/LootChannel.cs b/Hanekawa.Database/Tables/Config/LootChannel.cs deleted file mode 100644 index 54555f52..00000000 --- a/Hanekawa.Database/Tables/Config/LootChannel.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Database.Tables.Config -{ - public class LootChannel - { - public ulong GuildId { get; set; } - public ulong ChannelId { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/SelfAssignAbleRole.cs b/Hanekawa.Database/Tables/Config/SelfAssignAbleRole.cs deleted file mode 100644 index 78a297a5..00000000 --- a/Hanekawa.Database/Tables/Config/SelfAssignAbleRole.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Hanekawa.Database.Tables.Config -{ - public class SelfAssignAbleRole - { - public ulong GuildId { get; set; } - public ulong RoleId { get; set; } - public bool Exclusive { get; set; } = false; - - public string EmoteReactFormat { get; set; } - public string EmoteMessageFormat { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Config/WelcomeBanner.cs b/Hanekawa.Database/Tables/Config/WelcomeBanner.cs deleted file mode 100644 index 64576f80..00000000 --- a/Hanekawa.Database/Tables/Config/WelcomeBanner.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Config -{ - public class WelcomeBanner - { - public ulong GuildId { get; set; } - public int Id { get; set; } - public string Url { get; set; } - public ulong Uploader { get; set; } - public bool IsNsfw { get; set; } = false; - // Avatar configurations - public int AvatarSize { get; set; } = 60; - public int AviPlaceX { get; set; } = 10; - public int AviPlaceY { get; set; } = 10; - - // Name Placement - public int TextSize { get; set; } = 33; - public int TextPlaceX { get; set; } = 245; - public int TextPlaceY { get; set; } = 40; - - public DateTimeOffset UploadTimeOffset { get; set; } = DateTimeOffset.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Giveaway/Giveaway.cs b/Hanekawa.Database/Tables/Giveaway/Giveaway.cs deleted file mode 100644 index 54094208..00000000 --- a/Hanekawa.Database/Tables/Giveaway/Giveaway.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using Hanekawa.Shared; - -namespace Hanekawa.Database.Tables.Giveaway -{ - public class Giveaway - { - public Guid Id { get; set; } = Guid.NewGuid(); - public int IdNum { get; set; } // Number, incremented by number of giveaways in specific guilds - public ulong GuildId { get; set; } // Guild - public ulong Creator { get; set; } // Who created - public bool Active { get; set; } // Is giveaway active - public bool Stack { get; set; } = true; // Entries stack? - public int WinnerAmount { get; set; } = 1; - - // Requirements - public int? LevelRequirement { get; set; } = null; - public TimeSpan? AccountAgeRequirement { get; set; } = null; - public TimeSpan? ServerAgeRequirement { get; set; } = null; - - // Description of giveaway - public string Name { get; set; } = "Giveaway"; - public string Description { get; set; } = "Giveaway for this server"; - public GiveawayType Type { get; set; } - - // Timestamps - public DateTimeOffset CreatedAtOffset { get; set; } = DateTimeOffset.UtcNow; - public DateTimeOffset? CloseAtOffset { get; set; } = null; - - public virtual List Participants { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Giveaway/GiveawayHistory.cs b/Hanekawa.Database/Tables/Giveaway/GiveawayHistory.cs deleted file mode 100644 index a94ca406..00000000 --- a/Hanekawa.Database/Tables/Giveaway/GiveawayHistory.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Hanekawa.Shared; - -namespace Hanekawa.Database.Tables.Giveaway -{ - public class GiveawayHistory - { - public Guid Id { get; set; } - public int IdNum { get; set; } - public ulong GuildId { get; set; } - public ulong Creator { get; set; } // Who created - public ulong[] Winner { get; set; } - - public string Name { get; set; } = "Giveaway"; - public string Description { get; set; } = "Giveaway for this server"; - public GiveawayType Type { get; set; } - - public DateTimeOffset CreatedAtOffset { get; set; } - public DateTimeOffset ClosedAtOffset { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Giveaway/GiveawayParticipant.cs b/Hanekawa.Database/Tables/Giveaway/GiveawayParticipant.cs deleted file mode 100644 index 47577a9e..00000000 --- a/Hanekawa.Database/Tables/Giveaway/GiveawayParticipant.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Giveaway -{ - public class GiveawayParticipant - { - public Guid Id { get; set; } = Guid.NewGuid(); - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public DateTimeOffset Entry { get; set; } = DateTimeOffset.UtcNow; - - public Guid GiveawayId { get; set; } - public virtual Giveaway Giveaway { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Internal/Log.cs b/Hanekawa.Database/Tables/Internal/Log.cs deleted file mode 100644 index 45b2af5e..00000000 --- a/Hanekawa.Database/Tables/Internal/Log.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Hanekawa.Database.Tables.Internal -{ - public class Log - { - public int Id { get; set; } - public string TimeStamp { get; set; } - public string Level { get; set; } - public string Message { get; set; } - public string Logger { get; set; } - public string CallSite { get; set; } - public string Exception { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Moderation/Modlog.cs b/Hanekawa.Database/Tables/Moderation/Modlog.cs deleted file mode 100644 index 9ed71462..00000000 --- a/Hanekawa.Database/Tables/Moderation/Modlog.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Moderation -{ - public class ModLog - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public string Action { get; set; } = "Test"; - public ulong MessageId { get; set; } - public ulong? ModId { get; set; } - public string Response { get; set; } = "No response"; - public DateTime Date { get; set; } = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Moderation/MuteTimer.cs b/Hanekawa.Database/Tables/Moderation/MuteTimer.cs deleted file mode 100644 index 4282c980..00000000 --- a/Hanekawa.Database/Tables/Moderation/MuteTimer.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Moderation -{ - public class MuteTimer - { - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public DateTime Time { get; set; } = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Moderation/Report.cs b/Hanekawa.Database/Tables/Moderation/Report.cs deleted file mode 100644 index 21ef7e08..00000000 --- a/Hanekawa.Database/Tables/Moderation/Report.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Moderation -{ - public class Report - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public ulong? MessageId { get; set; } - public bool Status { get; set; } = false; - public string Message { get; set; } = "No message"; - public string Attachment { get; set; } = null; - public DateTime Date { get; set; } = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Moderation/Suggestion.cs b/Hanekawa.Database/Tables/Moderation/Suggestion.cs deleted file mode 100644 index 2e49e4fb..00000000 --- a/Hanekawa.Database/Tables/Moderation/Suggestion.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Moderation -{ - public class Suggestion - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public bool Status { get; set; } = false; - public ulong? MessageId { get; set; } - public ulong? ResponseUser { get; set; } - public string Response { get; set; } = "No response"; - public DateTime Date { get; set; } = DateTime.UtcNow; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Moderation/Warn.cs b/Hanekawa.Database/Tables/Moderation/Warn.cs deleted file mode 100644 index 50124955..00000000 --- a/Hanekawa.Database/Tables/Moderation/Warn.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using Hanekawa.Shared; - -namespace Hanekawa.Database.Tables.Moderation -{ - public class Warn - { - public int Id { get; set; } - public ulong GuildId { get; set; } - public ulong UserId { get; set; } - public WarnReason Type { get; set; } = WarnReason.Warned; - public string Reason { get; set; } = "No reason provided"; - public DateTime Time { get; set; } = DateTime.UtcNow; - public ulong Moderator { get; set; } - public bool Valid { get; set; } = true; - public TimeSpan? MuteTimer { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Music/MusicConfig.cs b/Hanekawa.Database/Tables/Music/MusicConfig.cs deleted file mode 100644 index 9ac8844d..00000000 --- a/Hanekawa.Database/Tables/Music/MusicConfig.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables.Music -{ - public class MusicConfig - { - public ulong GuildId { get; set; } - public ulong? TextChId { get; set; } = null; - public ulong? VoiceChId { get; set; } = null; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Music/Playlist.cs b/Hanekawa.Database/Tables/Music/Playlist.cs deleted file mode 100644 index 8af91304..00000000 --- a/Hanekawa.Database/Tables/Music/Playlist.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Hanekawa.Database.Tables.Music -{ - public class Playlist - { - public ulong GuildId { get; set; } - public string Name { get; set; } - public List Songs { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Premium/MvpConfig.cs b/Hanekawa.Database/Tables/Premium/MvpConfig.cs deleted file mode 100644 index e61d0c47..00000000 --- a/Hanekawa.Database/Tables/Premium/MvpConfig.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Hanekawa.Database.Tables.Premium -{ - public class MvpConfig - { - public ulong GuildId { get; set; } - public bool Disabled { get; set; } - public DayOfWeek Day { get; set; } = DayOfWeek.Wednesday; - public ulong? RoleId { get; set; } = null; - public int Count { get; set; } = 5; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/Quote/Quote.cs b/Hanekawa.Database/Tables/Quote/Quote.cs deleted file mode 100644 index 96cdfd22..00000000 --- a/Hanekawa.Database/Tables/Quote/Quote.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Hanekawa.Database.Tables.Quote -{ - public class Quote - { - public ulong GuildId { get; set; } - public string Key { get; set; } - public string Message { get; set; } - public DateTimeOffset Added { get; set; } = DateTimeOffset.UtcNow; - public ulong Creator { get; set; } - public List Triggers { get; set; } = new List(); - public int LevelCap { get; set; } = 0; - } -} \ No newline at end of file diff --git a/Hanekawa.Database/Tables/VoiceRoles.cs b/Hanekawa.Database/Tables/VoiceRoles.cs deleted file mode 100644 index 4423efc6..00000000 --- a/Hanekawa.Database/Tables/VoiceRoles.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Database.Tables -{ - public class VoiceRoles - { - public ulong GuildId { get; set; } - public ulong VoiceId { get; set; } - public ulong RoleId { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa.HungerGames/Cache/DefaultAvatar/DeathIndicator.png b/Hanekawa.HungerGames/Cache/DefaultAvatar/DeathIndicator.png deleted file mode 100644 index f7431f56..00000000 Binary files a/Hanekawa.HungerGames/Cache/DefaultAvatar/DeathIndicator.png and /dev/null differ diff --git a/Hanekawa.HungerGames/Cache/DefaultAvatar/Default.png b/Hanekawa.HungerGames/Cache/DefaultAvatar/Default.png deleted file mode 100644 index 10f01bca..00000000 Binary files a/Hanekawa.HungerGames/Cache/DefaultAvatar/Default.png and /dev/null differ diff --git a/Hanekawa.HungerGames/Hanekawa.HungerGames.csproj b/Hanekawa.HungerGames/Hanekawa.HungerGames.csproj deleted file mode 100644 index 1f861066..00000000 --- a/Hanekawa.HungerGames/Hanekawa.HungerGames.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - net5.0 - Library - - - - - - - - - - diff --git a/Hanekawa.Infrastructure/Caches/CacheKeyProvider.cs b/Hanekawa.Infrastructure/Caches/CacheKeyProvider.cs new file mode 100644 index 00000000..066b6cb1 --- /dev/null +++ b/Hanekawa.Infrastructure/Caches/CacheKeyProvider.cs @@ -0,0 +1,8 @@ +using Hanekawa.Interfaces; + +namespace Hanekawa.Infrastructure.Caches; + +public class CacheKeyProvider where T : ICached +{ + public string GetKey(string key) => $"{typeof(T).Name}:{key}"; +} \ No newline at end of file diff --git a/Hanekawa.Infrastructure/Caches/CacheService.cs b/Hanekawa.Infrastructure/Caches/CacheService.cs new file mode 100644 index 00000000..f3b977f0 --- /dev/null +++ b/Hanekawa.Infrastructure/Caches/CacheService.cs @@ -0,0 +1,92 @@ +using System; +using System.Text.Json; +using System.Threading.Tasks; +using Hanekawa.Application.Interfaces; +using Hanekawa.Interfaces; +using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.Logging; + +namespace Hanekawa.Infrastructure.Caches; + +internal class CacheService : ICacheContext +{ + private readonly IDistributedCache _cache; + private readonly ILogger _logger; + + public CacheService(IDistributedCache cache, ILogger logger) + { + _cache = cache; + _logger = logger; + } + + /// + public TEntity? Get(string key) + { + _logger.LogDebug("Retrieving cache value for key {Key} of type {CacheType}", key, nameof(TEntity)); + var value = _cache.GetString(key); + if (value is null) + { + _logger.LogDebug("Cache value for key {Key} of type {CacheType} not found", key, nameof(TEntity)); + return default; + } + + _logger.LogDebug("Cache value for key {Key} of type {CacheType} found", key, nameof(TEntity)); + return JsonSerializer.Deserialize(value); + } + + /// + public TEntity? Get(string key, TimeSpan expiration) + { + _logger.LogDebug("Retrieving cache value for key {Key} of type {CacheType}", key, nameof(TEntity)); + var value = _cache.GetString(key); + if (value is null) + { + _logger.LogDebug("Cache value for key {Key} of type {CacheType} not found", key, nameof(TEntity)); + return default; + } + + _logger.LogDebug("Cache value for key {Key} of type {CacheType} found", key, nameof(TEntity)); + return JsonSerializer.Deserialize(value); + } + + /// + public void Add(string key, TEntity value) + { + _logger.LogDebug("Adding cache value for key {Key} of type {CacheType}", key, nameof(TEntity)); + var options = new DistributedCacheEntryOptions(); + _cache.SetString(key, JsonSerializer.Serialize(value), options); + } + + /// + public void Add(string key, TEntity value, TimeSpan expiration) + { + _logger.LogDebug("Adding cache value for key {Key} of type {CacheType}", key, nameof(TEntity)); + var options = new DistributedCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = expiration + }; + _cache.SetString(key, JsonSerializer.Serialize(value), options); + } + + /// + public bool Remove(string key) + { + _logger.LogDebug("Removing cache value for key {Key}", key); + _cache.Remove(key); + return true; + } + + /// + public async ValueTask GetOrCreateAsync(string key, Func> factory) + { + var value = Get(key); + if (value is not null) + { + return await new ValueTask(value); + } + + var newValue = await factory(); + Add(key, newValue); + return await new ValueTask(newValue); + } +} \ No newline at end of file diff --git a/Hanekawa.Infrastructure/DbService.cs b/Hanekawa.Infrastructure/DbService.cs new file mode 100644 index 00000000..4b2d5cac --- /dev/null +++ b/Hanekawa.Infrastructure/DbService.cs @@ -0,0 +1,178 @@ +using System.Data; +using System.Data.Common; +using System.Threading; +using System.Threading.Tasks; +using Dapper; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Hanekawa.Entities.Club; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Internals; +using Hanekawa.Entities.Levels; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Infrastructure; + +internal class DbService : DbContext, IDbContext +{ + public DbService(DbContextOptions options) : base(options) { } + + public DbSet Warnings { get; set; } = null!; + public DbSet Logs { get; set; } = null!; + public DbSet ModerationLogs { get; set; } = null!; + public DbSet GuildConfigs { get; set; } = null!; + public DbSet Users { get; set; } = null!; + public DbSet LevelRequirements { get; set; } = null!; + public DbSet Clubs { get; set; } = null!; + public DbSet ClubMembers { get; set; } = null!; + public DbSet Items { get; set; } = null!; + public DbSet ItemTypes { get; set; } = null!; + + public async Task SaveChangesAsync(CancellationToken cancellationToken = default) + => await base.SaveChangesAsync(cancellationToken); + + public async Task EnsureDatabaseCreated(CancellationToken cancellationToken = default) + => await base.Database.EnsureCreatedAsync(cancellationToken); + + public async Task MigrateDatabaseAsync(CancellationToken cancellationToken = default) + => await base.Database.MigrateAsync(cancellationToken: cancellationToken); + + public DbConnection GetConnection() + { + return Database.GetDbConnection(); + } + public Task ExecuteQuery(string query, object? param = null, CancellationToken cancellationToken = default) + { + return Database.GetDbConnection() + .QueryFirstOrDefaultAsync(query, param, commandType: CommandType.Text); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(x => + { + x.HasKey(e => e.GuildId); + x.HasOne(e => e.GreetConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + x.HasOne(e => e.LevelConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + x.HasOne(e => e.LogConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + x.HasOne(e => e.AdminConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + x.HasOne(e => e.DropConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + x.HasOne(e => e.CurrencyConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + x.HasOne(e => e.BoostConfig) + .WithOne(e => e.GuildConfig) + .HasForeignKey(f => f.GuildId) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => new { e.GuildId, e.Id }); + x.HasOne(e => e.User) + .WithMany(e => e.GuildUsers) + .HasForeignKey(e => e.Id) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasMany(e => e.Images) + .WithOne(e => e.GreetConfig) + .HasForeignKey(e => e.GuildId) + .OnDelete(DeleteBehavior.Cascade); + }); + modelBuilder.Entity(x => + { + x.HasMany(e => e.Rewards) + .WithOne(e => e.LevelConfig) + .HasForeignKey(e => e.GuildId) + .OnDelete(DeleteBehavior.Cascade); + }); + modelBuilder.Entity(x => + { + x.HasKey(e => e.Level); + }); + modelBuilder.Entity(x => + { + x.HasKey(e => new { e.GuildId, e.Id }); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => new { e.GuildId, e.Name }); + x.HasIndex(e => new { e.GuildId, e.Name }).IsUnique(); + x.Property(e => e.Name).HasMaxLength(100); + x.Property(e => e.Description).HasMaxLength(1000); + x.HasMany(e => e.Members) + .WithOne(e => e.Club) + .HasForeignKey(e => new { e.GuildId, e.ClubName }) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => new { e.GuildId, e.ClubName, e.UserId }); + x.HasOne(e => e.User) + .WithMany() + .HasForeignKey(e => new { e.GuildId, e.UserId }) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => e.Id); + x.HasMany(e => e.Inventory) + .WithOne(e => e.User) + .HasForeignKey(e => e.UserId) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => new { e.UserId, e.ItemId }); + x.HasOne(e => e.Item) + .WithMany() + .HasForeignKey(e => e.ItemId) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => e.Id); + x.HasOne(e => e.Type) + .WithMany(e => e.Items) + .HasForeignKey(e => e.TypeId) + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity(x => + { + x.HasKey(e => e.Id); + x.Property(e => e.Name).HasMaxLength(50); + }); + } + + public Task ExecuteCommand(string command, object? param = null, CancellationToken cancellationToken = default) + { + return Database.GetDbConnection() + .ExecuteAsync(command, param, commandType: CommandType.Text); + } +} \ No newline at end of file diff --git a/Hanekawa.Infrastructure/DbServiceFactory.cs b/Hanekawa.Infrastructure/DbServiceFactory.cs new file mode 100644 index 00000000..a704c28f --- /dev/null +++ b/Hanekawa.Infrastructure/DbServiceFactory.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; + +namespace Hanekawa.Infrastructure; + +internal class DbServiceFactory : IDesignTimeDbContextFactory +{ + public DbService CreateDbContext(string[] args) + { + var builder = new DbContextOptionsBuilder(); + builder.UseNpgsql( + "Server=localhost; Port=5432; Database=hanekawa-development; Userid=postgres;Password=1023;"); + return new DbService(builder.Options); + } +} \ No newline at end of file diff --git a/Hanekawa.Infrastructure/DependencyInjection.cs b/Hanekawa.Infrastructure/DependencyInjection.cs new file mode 100644 index 00000000..0b9c6b2c --- /dev/null +++ b/Hanekawa.Infrastructure/DependencyInjection.cs @@ -0,0 +1,44 @@ +using System; +using Hanekawa.Application.Interfaces; +using Hanekawa.Infrastructure.Caches; +using Hanekawa.Infrastructure.Triggers; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using StackExchange.Redis; + +namespace Hanekawa.Infrastructure; + +public static class DependencyInjection +{ + public static IServiceCollection AddInfrastructureLayer(this IServiceCollection services, IConfiguration cfg) + { + services.AddStackExchangeRedisCache(x => + { + x.ConfigurationOptions = new ConfigurationOptions + { + ClientName = "Hanekawa", + AbortOnConnectFail = true, + Protocol = RedisProtocol.Resp3, + DefaultDatabase = 1, + User = "default" + }; + x.ConnectionMultiplexerFactory = async () => await ConnectionMultiplexer.ConnectAsync(cfg["redis"] + ?? throw new InvalidOperationException("Redis config is null")); + }); + services.AddScoped(); + services.AddDbContextPool(x => + { + x.UseNpgsql(cfg["connectionString"]); + x.EnableDetailedErrors(); + x.EnableSensitiveDataLogging(false); + x.UseTriggers(builder => + { + builder.AddTrigger(); + builder.AddTrigger(); + }); + }); + + return services; + } +} \ No newline at end of file diff --git a/Hanekawa.Infrastructure/Extensions/DbExtensions.cs b/Hanekawa.Infrastructure/Extensions/DbExtensions.cs new file mode 100644 index 00000000..4e2b8007 --- /dev/null +++ b/Hanekawa.Infrastructure/Extensions/DbExtensions.cs @@ -0,0 +1,50 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Threading.Tasks; +using Hanekawa.Application.Interfaces; +using Hanekawa.Interfaces; +using Microsoft.Extensions.DependencyInjection; + +namespace Hanekawa.Infrastructure.Extensions; + +public static class DbExtensions +{ + public static async ValueTask GetOrReceiveCacheAsync(this IServiceProvider serviceProvider, + ulong id, TimeSpan? timeSpan = null) where TEntity : class, ICached, new() + => await GetOrReceiveCacheAsync(serviceProvider.CreateScope(), id, timeSpan); + + public static async ValueTask GetOrReceiveCacheAsync(this IServiceScope serviceScope, + ulong key, TimeSpan? timeSpan = null) where TEntity : class, ICached, new() + { + var cache = serviceScope.ServiceProvider.GetRequiredService(); + var result = timeSpan.HasValue + ? cache.Get($"{nameof(TEntity)}-{key}", timeSpan.Value) + : cache.Get($"{nameof(TEntity)}-{key}"); + if (result is not null) return result; + + await using var db = serviceScope.ServiceProvider.GetRequiredService(); + result = await GetOrCreateEntityAsync(db, key); + + if (timeSpan.HasValue) + cache.Add($"{nameof(TEntity)}-{key}", result, timeSpan.Value); + else + cache.Add($"{nameof(TEntity)}-{key}", result); + + return result; + } + + public static async ValueTask GetOrCreateEntityAsync(this IDbContext context, + params ulong[] args) where TEntity : class, new() + { + if (context is not DbService dbService) + throw new ValidationException("This IDbContext isn't inherited by DbService"); + + var config = await dbService.FindAsync(args); + if (config is not null) return config; + + config = (TEntity)Activator.CreateInstance(typeof(TEntity), new { args })!; + await dbService.AddAsync(config); + await context.SaveChangesAsync(); + return (await dbService.FindAsync(args))!; + } +} \ No newline at end of file diff --git a/Hanekawa.Infrastructure/Hanekawa.Infrastructure.csproj b/Hanekawa.Infrastructure/Hanekawa.Infrastructure.csproj new file mode 100644 index 00000000..8de74f81 --- /dev/null +++ b/Hanekawa.Infrastructure/Hanekawa.Infrastructure.csproj @@ -0,0 +1,32 @@ + + + + net9.0 + preview + Hanekawa.Infrastructure + Hanekawa.Infrastructure + enable + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Hanekawa.Infrastructure/Migrations/20230327163157_Initial.Designer.cs b/Hanekawa.Infrastructure/Migrations/20230327163157_Initial.Designer.cs new file mode 100644 index 00000000..8be86027 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20230327163157_Initial.Designer.cs @@ -0,0 +1,238 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + [Migration("20230327163157_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("LevelUpDmEnabled") + .HasColumnType("boolean"); + + b.Property("LevelUpDmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("LevelUpMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("LevelUpMessageEnabled") + .HasColumnType("boolean"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("UserId"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Infrastructure.Tables.Internal.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("GreetConfig") + .IsRequired(); + + b.Navigation("LevelConfig") + .IsRequired(); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20230327163157_Initial.cs b/Hanekawa.Infrastructure/Migrations/20230327163157_Initial.cs new file mode 100644 index 00000000..6c5831d0 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20230327163157_Initial.cs @@ -0,0 +1,155 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + /// + public partial class Initial : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "GuildConfigs", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + Prefix = table.Column(type: "text", nullable: false), + Language = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GuildConfigs", x => x.GuildId); + }); + + migrationBuilder.CreateTable( + name: "Logs", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + TimeStamp = table.Column(type: "text", nullable: false), + Level = table.Column(type: "text", nullable: false), + Message = table.Column(type: "text", nullable: false), + Logger = table.Column(type: "text", nullable: false), + CallSite = table.Column(type: "text", nullable: false), + Exception = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Logs", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "User", + columns: table => new + { + UserId = table.Column(type: "numeric(20,0)", nullable: false), + PremiumExpiration = table.Column(type: "timestamp with time zone", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_User", x => x.UserId); + }); + + migrationBuilder.CreateTable( + name: "GreetConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + Message = table.Column(type: "text", nullable: false), + Channel = table.Column(type: "numeric(20,0)", nullable: true), + ImageEnabled = table.Column(type: "boolean", nullable: false), + ImageUrl = table.Column(type: "text", nullable: false), + DmEnabled = table.Column(type: "boolean", nullable: false), + DmMessage = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GreetConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_GreetConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "LevelConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + LevelEnabled = table.Column(type: "boolean", nullable: false), + LevelUpMessageEnabled = table.Column(type: "boolean", nullable: false), + LevelUpMessage = table.Column(type: "text", nullable: false), + LevelUpDmEnabled = table.Column(type: "boolean", nullable: false), + LevelUpDmMessage = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_LevelConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_LevelConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + UserId = table.Column(type: "numeric(20,0)", nullable: false), + Level = table.Column(type: "integer", nullable: false), + Experience = table.Column(type: "bigint", nullable: false), + DailyClaimed = table.Column(type: "timestamp with time zone", nullable: false), + DailyStreak = table.Column(type: "integer", nullable: false), + TotalVoiceTime = table.Column(type: "interval", nullable: false), + LastSeen = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => new { x.GuildId, x.UserId }); + table.ForeignKey( + name: "FK_Users_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "UserId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Users_UserId", + table: "Users", + column: "UserId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "GreetConfig"); + + migrationBuilder.DropTable( + name: "LevelConfig"); + + migrationBuilder.DropTable( + name: "Logs"); + + migrationBuilder.DropTable( + name: "Users"); + + migrationBuilder.DropTable( + name: "GuildConfigs"); + + migrationBuilder.DropTable( + name: "User"); + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20230328224948_Initial2.Designer.cs b/Hanekawa.Infrastructure/Migrations/20230328224948_Initial2.Designer.cs new file mode 100644 index 00000000..fd017384 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20230328224948_Initial2.Designer.cs @@ -0,0 +1,282 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + [Migration("20230328224948_Initial2")] + partial class Initial2 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uploader") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GreetImage"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("LevelUpDmEnabled") + .HasColumnType("boolean"); + + b.Property("LevelUpDmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("LevelUpMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("LevelUpMessageEnabled") + .HasColumnType("boolean"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("UserId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("UserId"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Infrastructure.Tables.Internal.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.HasOne("Hanekawa.Entities.Configs.GreetConfig", "GreetConfig") + .WithMany("Images") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Navigation("Images"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("GreetConfig") + .IsRequired(); + + b.Navigation("LevelConfig") + .IsRequired(); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20230328224948_Initial2.cs b/Hanekawa.Infrastructure/Migrations/20230328224948_Initial2.cs new file mode 100644 index 00000000..7531d778 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20230328224948_Initial2.cs @@ -0,0 +1,50 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + /// + public partial class Initial2 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "GreetImage", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + ImageUrl = table.Column(type: "text", nullable: false), + Uploader = table.Column(type: "numeric(20,0)", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GreetImage", x => x.Id); + table.ForeignKey( + name: "FK_GreetImage_GreetConfig_GuildId", + column: x => x.GuildId, + principalTable: "GreetConfig", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_GreetImage_GuildId", + table: "GreetImage", + column: "GuildId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "GreetImage"); + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20240903180743_UpdateLatestStuff.Designer.cs b/Hanekawa.Infrastructure/Migrations/20240903180743_UpdateLatestStuff.Designer.cs new file mode 100644 index 00000000..e3eab1db --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20240903180743_UpdateLatestStuff.Designer.cs @@ -0,0 +1,505 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + [Migration("20240903180743_UpdateLatestStuff")] + partial class UpdateLatestStuff + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.8") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxWarnings") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("AdminConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Blacklist") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.Property("Emote") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpReward") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("DropConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarSize") + .HasColumnType("integer"); + + b.Property("AvatarX") + .HasColumnType("integer"); + + b.Property("AvatarY") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uploader") + .HasColumnType("numeric(20,0)"); + + b.Property("UsernameSize") + .HasColumnType("real"); + + b.Property("UsernameX") + .HasColumnType("integer"); + + b.Property("UsernameY") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GreetImage"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("DecayEnabled") + .HasColumnType("boolean"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("Multiplier") + .HasColumnType("integer"); + + b.Property("MultiplierEnd") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinLeaveLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("MessageLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("VoiceLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId"); + + b.ToTable("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.GuildModerationLog", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("MessageId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Id"); + + b.ToTable("ModerationLogs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Internals.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelRequirement", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("Experience") + .HasColumnType("integer"); + + b.HasKey("Level"); + + b.ToTable("LevelRequirements"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Money") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Level"); + + b.HasIndex("GuildId"); + + b.ToTable("LevelReward"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("CurrentLevelExperience") + .HasColumnType("bigint"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("NextLevelExperience") + .HasColumnType("bigint"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "UserId"); + + b.HasIndex("UserId"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Valid") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("AdminConfig") + .HasForeignKey("Hanekawa.Entities.Configs.AdminConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("DropConfig") + .HasForeignKey("Hanekawa.Entities.Configs.DropConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.HasOne("Hanekawa.Entities.Configs.GreetConfig", "GreetConfig") + .WithMany("Images") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LogConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LogConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.HasOne("Hanekawa.Entities.Configs.LevelConfig", "LevelConfig") + .WithMany("Rewards") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Navigation("Images"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("AdminConfig"); + + b.Navigation("DropConfig"); + + b.Navigation("GreetConfig"); + + b.Navigation("LevelConfig"); + + b.Navigation("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Navigation("Rewards"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20240903180743_UpdateLatestStuff.cs b/Hanekawa.Infrastructure/Migrations/20240903180743_UpdateLatestStuff.cs new file mode 100644 index 00000000..3ff39ae2 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20240903180743_UpdateLatestStuff.cs @@ -0,0 +1,347 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + /// + public partial class UpdateLatestStuff : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "LevelUpDmEnabled", + table: "LevelConfig"); + + migrationBuilder.DropColumn( + name: "LevelUpDmMessage", + table: "LevelConfig"); + + migrationBuilder.DropColumn( + name: "LevelUpMessage", + table: "LevelConfig"); + + migrationBuilder.DropColumn( + name: "ImageUrl", + table: "GreetConfig"); + + migrationBuilder.RenameColumn( + name: "UserId", + table: "User", + newName: "Id"); + + migrationBuilder.RenameColumn( + name: "LevelUpMessageEnabled", + table: "LevelConfig", + newName: "DecayEnabled"); + + migrationBuilder.AddColumn( + name: "CurrentLevelExperience", + table: "Users", + type: "bigint", + nullable: false, + defaultValue: 0L); + + migrationBuilder.AddColumn( + name: "NextLevelExperience", + table: "Users", + type: "bigint", + nullable: false, + defaultValue: 0L); + + migrationBuilder.AddColumn( + name: "Multiplier", + table: "LevelConfig", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "MultiplierEnd", + table: "LevelConfig", + type: "timestamp with time zone", + nullable: false, + defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0))); + + migrationBuilder.AddColumn( + name: "AvatarSize", + table: "GreetImage", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "AvatarX", + table: "GreetImage", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "AvatarY", + table: "GreetImage", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "UsernameSize", + table: "GreetImage", + type: "real", + nullable: false, + defaultValue: 0f); + + migrationBuilder.AddColumn( + name: "UsernameX", + table: "GreetImage", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "UsernameY", + table: "GreetImage", + type: "integer", + nullable: false, + defaultValue: 0); + + migrationBuilder.CreateTable( + name: "AdminConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + MaxWarnings = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AdminConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_AdminConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "DropConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + Emote = table.Column(type: "text", nullable: false), + ExpReward = table.Column(type: "integer", nullable: false), + Blacklist = table.Column(type: "numeric(20,0)[]", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DropConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_DropConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "LevelRequirements", + columns: table => new + { + Level = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Experience = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_LevelRequirements", x => x.Level); + }); + + migrationBuilder.CreateTable( + name: "LevelReward", + columns: table => new + { + Level = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoleId = table.Column(type: "numeric(20,0)", nullable: true), + Money = table.Column(type: "integer", nullable: true), + GuildId = table.Column(type: "numeric(20,0)", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_LevelReward", x => x.Level); + table.ForeignKey( + name: "FK_LevelReward_LevelConfig_GuildId", + column: x => x.GuildId, + principalTable: "LevelConfig", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "LogConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + JoinLeaveLogChannelId = table.Column(type: "numeric(20,0)", nullable: true), + MessageLogChannelId = table.Column(type: "numeric(20,0)", nullable: true), + ModLogChannelId = table.Column(type: "numeric(20,0)", nullable: true), + VoiceLogChannelId = table.Column(type: "numeric(20,0)", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_LogConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_LogConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ModerationLogs", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false), + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + UserId = table.Column(type: "numeric(20,0)", nullable: false), + MessageId = table.Column(type: "numeric(20,0)", nullable: false), + ModeratorId = table.Column(type: "numeric(20,0)", nullable: true), + Reason = table.Column(type: "text", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ModerationLogs", x => new { x.GuildId, x.Id }); + }); + + migrationBuilder.CreateTable( + name: "Warnings", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + UserId = table.Column(type: "numeric(20,0)", nullable: false), + ModeratorId = table.Column(type: "numeric(20,0)", nullable: false), + Reason = table.Column(type: "text", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + Valid = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Warnings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_LevelReward_GuildId", + table: "LevelReward", + column: "GuildId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AdminConfig"); + + migrationBuilder.DropTable( + name: "DropConfig"); + + migrationBuilder.DropTable( + name: "LevelRequirements"); + + migrationBuilder.DropTable( + name: "LevelReward"); + + migrationBuilder.DropTable( + name: "LogConfig"); + + migrationBuilder.DropTable( + name: "ModerationLogs"); + + migrationBuilder.DropTable( + name: "Warnings"); + + migrationBuilder.DropColumn( + name: "CurrentLevelExperience", + table: "Users"); + + migrationBuilder.DropColumn( + name: "NextLevelExperience", + table: "Users"); + + migrationBuilder.DropColumn( + name: "Multiplier", + table: "LevelConfig"); + + migrationBuilder.DropColumn( + name: "MultiplierEnd", + table: "LevelConfig"); + + migrationBuilder.DropColumn( + name: "AvatarSize", + table: "GreetImage"); + + migrationBuilder.DropColumn( + name: "AvatarX", + table: "GreetImage"); + + migrationBuilder.DropColumn( + name: "AvatarY", + table: "GreetImage"); + + migrationBuilder.DropColumn( + name: "UsernameSize", + table: "GreetImage"); + + migrationBuilder.DropColumn( + name: "UsernameX", + table: "GreetImage"); + + migrationBuilder.DropColumn( + name: "UsernameY", + table: "GreetImage"); + + migrationBuilder.RenameColumn( + name: "Id", + table: "User", + newName: "UserId"); + + migrationBuilder.RenameColumn( + name: "DecayEnabled", + table: "LevelConfig", + newName: "LevelUpMessageEnabled"); + + migrationBuilder.AddColumn( + name: "LevelUpDmEnabled", + table: "LevelConfig", + type: "boolean", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "LevelUpDmMessage", + table: "LevelConfig", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "LevelUpMessage", + table: "LevelConfig", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "ImageUrl", + table: "GreetConfig", + type: "text", + nullable: false, + defaultValue: ""); + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20241211201216_LatestUpdateStuff.Designer.cs b/Hanekawa.Infrastructure/Migrations/20241211201216_LatestUpdateStuff.Designer.cs new file mode 100644 index 00000000..5390846e --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20241211201216_LatestUpdateStuff.Designer.cs @@ -0,0 +1,505 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + [Migration("20241211201216_LatestUpdateStuff")] + partial class LatestUpdateStuff + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxWarnings") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("AdminConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.PrimitiveCollection("Blacklist") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.Property("Emote") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpReward") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("DropConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarSize") + .HasColumnType("integer"); + + b.Property("AvatarX") + .HasColumnType("integer"); + + b.Property("AvatarY") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uploader") + .HasColumnType("numeric(20,0)"); + + b.Property("UsernameSize") + .HasColumnType("real"); + + b.Property("UsernameX") + .HasColumnType("integer"); + + b.Property("UsernameY") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GreetImage"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("DecayEnabled") + .HasColumnType("boolean"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("Multiplier") + .HasColumnType("integer"); + + b.Property("MultiplierEnd") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinLeaveLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("MessageLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("VoiceLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId"); + + b.ToTable("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.GuildModerationLog", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("MessageId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Id"); + + b.ToTable("ModerationLogs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Internals.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelRequirement", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("Experience") + .HasColumnType("integer"); + + b.HasKey("Level"); + + b.ToTable("LevelRequirements"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Money") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Level"); + + b.HasIndex("GuildId"); + + b.ToTable("LevelReward"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("numeric(20,0)"); + + b.Property("CurrentLevelExperience") + .HasColumnType("bigint"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("NextLevelExperience") + .HasColumnType("bigint"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "Id"); + + b.HasIndex("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Valid") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("AdminConfig") + .HasForeignKey("Hanekawa.Entities.Configs.AdminConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("DropConfig") + .HasForeignKey("Hanekawa.Entities.Configs.DropConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.HasOne("Hanekawa.Entities.Configs.GreetConfig", "GreetConfig") + .WithMany("Images") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LogConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LogConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.HasOne("Hanekawa.Entities.Configs.LevelConfig", "LevelConfig") + .WithMany("Rewards") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Navigation("Images"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("AdminConfig"); + + b.Navigation("DropConfig"); + + b.Navigation("GreetConfig"); + + b.Navigation("LevelConfig"); + + b.Navigation("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Navigation("Rewards"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20241211201216_LatestUpdateStuff.cs b/Hanekawa.Infrastructure/Migrations/20241211201216_LatestUpdateStuff.cs new file mode 100644 index 00000000..e4a60ffb --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20241211201216_LatestUpdateStuff.cs @@ -0,0 +1,62 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + /// + public partial class LatestUpdateStuff : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Users_User_UserId", + table: "Users"); + + migrationBuilder.RenameColumn( + name: "UserId", + table: "Users", + newName: "Id"); + + migrationBuilder.RenameIndex( + name: "IX_Users_UserId", + table: "Users", + newName: "IX_Users_Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Users_User_Id", + table: "Users", + column: "Id", + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Users_User_Id", + table: "Users"); + + migrationBuilder.RenameColumn( + name: "Id", + table: "Users", + newName: "UserId"); + + migrationBuilder.RenameIndex( + name: "IX_Users_Id", + table: "Users", + newName: "IX_Users_UserId"); + + migrationBuilder.AddForeignKey( + name: "FK_Users_User_UserId", + table: "Users", + column: "UserId", + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20241218101659_Currency.Designer.cs b/Hanekawa.Infrastructure/Migrations/20241218101659_Currency.Designer.cs new file mode 100644 index 00000000..402c3872 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20241218101659_Currency.Designer.cs @@ -0,0 +1,545 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + [Migration("20241218101659_Currency")] + partial class Currency + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxWarnings") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("AdminConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.CurrencyConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("CurrencyName") + .IsRequired() + .HasColumnType("text"); + + b.Property("CurrencySymbol") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsEmote") + .HasColumnType("boolean"); + + b.Property("SymbolAffix") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("CurrencyConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.PrimitiveCollection("Blacklist") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.Property("Emote") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpReward") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("DropConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarSize") + .HasColumnType("integer"); + + b.Property("AvatarX") + .HasColumnType("integer"); + + b.Property("AvatarY") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uploader") + .HasColumnType("numeric(20,0)"); + + b.Property("UsernameSize") + .HasColumnType("real"); + + b.Property("UsernameX") + .HasColumnType("integer"); + + b.Property("UsernameY") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GreetImage"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("DecayEnabled") + .HasColumnType("boolean"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("Multiplier") + .HasColumnType("integer"); + + b.Property("MultiplierEnd") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinLeaveLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("MessageLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("VoiceLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId"); + + b.ToTable("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.GuildModerationLog", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("MessageId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Id"); + + b.ToTable("ModerationLogs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Internals.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelRequirement", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("Experience") + .HasColumnType("integer"); + + b.HasKey("Level"); + + b.ToTable("LevelRequirements"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Money") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Level"); + + b.HasIndex("GuildId"); + + b.ToTable("LevelReward"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("numeric(20,0)"); + + b.Property("Currency") + .HasColumnType("bigint"); + + b.Property("CurrentLevelExperience") + .HasColumnType("bigint"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("NextLevelExperience") + .HasColumnType("bigint"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "Id"); + + b.HasIndex("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Valid") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("AdminConfig") + .HasForeignKey("Hanekawa.Entities.Configs.AdminConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.CurrencyConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("CurrencyConfig") + .HasForeignKey("Hanekawa.Entities.Configs.CurrencyConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("DropConfig") + .HasForeignKey("Hanekawa.Entities.Configs.DropConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.HasOne("Hanekawa.Entities.Configs.GreetConfig", "GreetConfig") + .WithMany("Images") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LogConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LogConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.HasOne("Hanekawa.Entities.Configs.LevelConfig", "LevelConfig") + .WithMany("Rewards") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Navigation("Images"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("AdminConfig"); + + b.Navigation("CurrencyConfig"); + + b.Navigation("DropConfig"); + + b.Navigation("GreetConfig"); + + b.Navigation("LevelConfig"); + + b.Navigation("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Navigation("Rewards"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20241218101659_Currency.cs b/Hanekawa.Infrastructure/Migrations/20241218101659_Currency.cs new file mode 100644 index 00000000..a8c75fa3 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20241218101659_Currency.cs @@ -0,0 +1,53 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + /// + public partial class Currency : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Currency", + table: "Users", + type: "bigint", + nullable: false, + defaultValue: 0L); + + migrationBuilder.CreateTable( + name: "CurrencyConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + CurrencyName = table.Column(type: "text", nullable: false), + CurrencySymbol = table.Column(type: "text", nullable: false), + SymbolAffix = table.Column(type: "integer", nullable: false), + IsEmote = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CurrencyConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_CurrencyConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CurrencyConfig"); + + migrationBuilder.DropColumn( + name: "Currency", + table: "Users"); + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20250605202946_boostconfig.Designer.cs b/Hanekawa.Infrastructure/Migrations/20250605202946_boostconfig.Designer.cs new file mode 100644 index 00000000..63363a76 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20250605202946_boostconfig.Designer.cs @@ -0,0 +1,766 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + [Migration("20250605202946_boostconfig")] + partial class boostconfig + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Club.Club", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("OwnerId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Name"); + + b.HasIndex("GuildId", "Name") + .IsUnique(); + + b.ToTable("Clubs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Club.ClubMember", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ClubName") + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId", "ClubName", "UserId"); + + b.HasIndex("GuildId", "UserId"); + + b.ToTable("ClubMembers"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxWarnings") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("AdminConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.BoostConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Currency") + .HasColumnType("integer"); + + b.Property("CurrencyMultiplier") + .HasColumnType("numeric"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Experience") + .HasColumnType("integer"); + + b.Property("ExperienceMultiplier") + .HasColumnType("numeric"); + + b.Property("ReoccurringRewards") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("BoostConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.CurrencyConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("CurrencyName") + .IsRequired() + .HasColumnType("text"); + + b.Property("CurrencySymbol") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsEmote") + .HasColumnType("boolean"); + + b.Property("SymbolAffix") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("CurrencyConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.PrimitiveCollection("Blacklist") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.Property("Emote") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpReward") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("DropConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarSize") + .HasColumnType("integer"); + + b.Property("AvatarX") + .HasColumnType("integer"); + + b.Property("AvatarY") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uploader") + .HasColumnType("numeric(20,0)"); + + b.Property("UsernameSize") + .HasColumnType("real"); + + b.Property("UsernameX") + .HasColumnType("integer"); + + b.Property("UsernameY") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GreetImage"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("DecayEnabled") + .HasColumnType("boolean"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("Multiplier") + .HasColumnType("integer"); + + b.Property("MultiplierEnd") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinLeaveLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("MessageLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("VoiceLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId"); + + b.ToTable("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.GuildModerationLog", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("MessageId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Id"); + + b.ToTable("ModerationLogs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Internals.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelRequirement", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("Experience") + .HasColumnType("integer"); + + b.HasKey("Level"); + + b.ToTable("LevelRequirements"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Money") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Level"); + + b.HasIndex("GuildId"); + + b.ToTable("LevelReward"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("numeric(20,0)"); + + b.Property("Currency") + .HasColumnType("bigint"); + + b.Property("CurrentLevelExperience") + .HasColumnType("bigint"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("Inactive") + .HasColumnType("boolean"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("NextLevelExperience") + .HasColumnType("bigint"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "Id"); + + b.HasIndex("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Inventory", b => + { + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("ItemId") + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("integer"); + + b.HasKey("UserId", "ItemId"); + + b.HasIndex("ItemId"); + + b.ToTable("Inventory"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Item", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("integer"); + + b.Property("TypeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("TypeId"); + + b.ToTable("Items"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.ItemType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("ItemTypes"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Valid") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Club.ClubMember", b => + { + b.HasOne("Hanekawa.Entities.Club.Club", "Club") + .WithMany("Members") + .HasForeignKey("GuildId", "ClubName") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hanekawa.Entities.Users.GuildUser", "User") + .WithMany() + .HasForeignKey("GuildId", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Club"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("AdminConfig") + .HasForeignKey("Hanekawa.Entities.Configs.AdminConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.BoostConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("BoostConfig") + .HasForeignKey("Hanekawa.Entities.Configs.BoostConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.CurrencyConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("CurrencyConfig") + .HasForeignKey("Hanekawa.Entities.Configs.CurrencyConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("DropConfig") + .HasForeignKey("Hanekawa.Entities.Configs.DropConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.HasOne("Hanekawa.Entities.Configs.GreetConfig", "GreetConfig") + .WithMany("Images") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LogConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LogConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.HasOne("Hanekawa.Entities.Configs.LevelConfig", "LevelConfig") + .WithMany("Rewards") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Inventory", b => + { + b.HasOne("Hanekawa.Entities.Users.Item", "Item") + .WithMany() + .HasForeignKey("ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("Inventory") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Item", b => + { + b.HasOne("Hanekawa.Entities.Users.ItemType", "Type") + .WithMany("Items") + .HasForeignKey("TypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Type"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Club.Club", b => + { + b.Navigation("Members"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Navigation("Images"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("AdminConfig"); + + b.Navigation("BoostConfig"); + + b.Navigation("CurrencyConfig"); + + b.Navigation("DropConfig"); + + b.Navigation("GreetConfig"); + + b.Navigation("LevelConfig"); + + b.Navigation("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Navigation("Rewards"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.ItemType", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + + b.Navigation("Inventory"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/20250605202946_boostconfig.cs b/Hanekawa.Infrastructure/Migrations/20250605202946_boostconfig.cs new file mode 100644 index 00000000..1094db71 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/20250605202946_boostconfig.cs @@ -0,0 +1,193 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + /// + public partial class boostconfig : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Inactive", + table: "Users", + type: "boolean", + nullable: false, + defaultValue: false); + + migrationBuilder.CreateTable( + name: "BoostConfig", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + Experience = table.Column(type: "integer", nullable: false), + Currency = table.Column(type: "integer", nullable: false), + ExperienceMultiplier = table.Column(type: "numeric", nullable: false), + CurrencyMultiplier = table.Column(type: "numeric", nullable: false), + ReoccurringRewards = table.Column(type: "boolean", nullable: false), + Enabled = table.Column(type: "boolean", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Updated = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BoostConfig", x => x.GuildId); + table.ForeignKey( + name: "FK_BoostConfig_GuildConfigs_GuildId", + column: x => x.GuildId, + principalTable: "GuildConfigs", + principalColumn: "GuildId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Clubs", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + Name = table.Column(type: "character varying(100)", maxLength: 100, nullable: false), + Description = table.Column(type: "character varying(1000)", maxLength: 1000, nullable: false), + OwnerId = table.Column(type: "numeric(20,0)", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clubs", x => new { x.GuildId, x.Name }); + }); + + migrationBuilder.CreateTable( + name: "ItemTypes", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "character varying(50)", maxLength: 50, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ItemTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ClubMembers", + columns: table => new + { + GuildId = table.Column(type: "numeric(20,0)", nullable: false), + ClubName = table.Column(type: "character varying(100)", nullable: false), + UserId = table.Column(type: "numeric(20,0)", nullable: false), + JoinedAt = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClubMembers", x => new { x.GuildId, x.ClubName, x.UserId }); + table.ForeignKey( + name: "FK_ClubMembers_Clubs_GuildId_ClubName", + columns: x => new { x.GuildId, x.ClubName }, + principalTable: "Clubs", + principalColumns: new[] { "GuildId", "Name" }, + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ClubMembers_Users_GuildId_UserId", + columns: x => new { x.GuildId, x.UserId }, + principalTable: "Users", + principalColumns: new[] { "GuildId", "Id" }, + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Items", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "text", nullable: false), + Description = table.Column(type: "text", nullable: false), + TypeId = table.Column(type: "uuid", nullable: false), + Price = table.Column(type: "integer", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Items", x => x.Id); + table.ForeignKey( + name: "FK_Items_ItemTypes_TypeId", + column: x => x.TypeId, + principalTable: "ItemTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Inventory", + columns: table => new + { + UserId = table.Column(type: "numeric(20,0)", nullable: false), + ItemId = table.Column(type: "uuid", nullable: false), + Amount = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Inventory", x => new { x.UserId, x.ItemId }); + table.ForeignKey( + name: "FK_Inventory_Items_ItemId", + column: x => x.ItemId, + principalTable: "Items", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Inventory_User_UserId", + column: x => x.UserId, + principalTable: "User", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ClubMembers_GuildId_UserId", + table: "ClubMembers", + columns: new[] { "GuildId", "UserId" }); + + migrationBuilder.CreateIndex( + name: "IX_Clubs_GuildId_Name", + table: "Clubs", + columns: new[] { "GuildId", "Name" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Inventory_ItemId", + table: "Inventory", + column: "ItemId"); + + migrationBuilder.CreateIndex( + name: "IX_Items_TypeId", + table: "Items", + column: "TypeId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BoostConfig"); + + migrationBuilder.DropTable( + name: "ClubMembers"); + + migrationBuilder.DropTable( + name: "Inventory"); + + migrationBuilder.DropTable( + name: "Clubs"); + + migrationBuilder.DropTable( + name: "Items"); + + migrationBuilder.DropTable( + name: "ItemTypes"); + + migrationBuilder.DropColumn( + name: "Inactive", + table: "Users"); + } + } +} diff --git a/Hanekawa.Infrastructure/Migrations/DbServiceModelSnapshot.cs b/Hanekawa.Infrastructure/Migrations/DbServiceModelSnapshot.cs new file mode 100644 index 00000000..e3acdc80 --- /dev/null +++ b/Hanekawa.Infrastructure/Migrations/DbServiceModelSnapshot.cs @@ -0,0 +1,763 @@ +// +using System; +using Hanekawa.Infrastructure; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Hanekawa.Infrastructure.Migrations +{ + [DbContext(typeof(DbService))] + partial class DbServiceModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "9.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Hanekawa.Entities.Club.Club", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Name") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("OwnerId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Name"); + + b.HasIndex("GuildId", "Name") + .IsUnique(); + + b.ToTable("Clubs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Club.ClubMember", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ClubName") + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId", "ClubName", "UserId"); + + b.HasIndex("GuildId", "UserId"); + + b.ToTable("ClubMembers"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxWarnings") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("AdminConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.BoostConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Currency") + .HasColumnType("integer"); + + b.Property("CurrencyMultiplier") + .HasColumnType("numeric"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("Experience") + .HasColumnType("integer"); + + b.Property("ExperienceMultiplier") + .HasColumnType("numeric"); + + b.Property("ReoccurringRewards") + .HasColumnType("boolean"); + + b.Property("Updated") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("BoostConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.CurrencyConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("CurrencyName") + .IsRequired() + .HasColumnType("text"); + + b.Property("CurrencySymbol") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsEmote") + .HasColumnType("boolean"); + + b.Property("SymbolAffix") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("CurrencyConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.PrimitiveCollection("Blacklist") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.Property("Emote") + .IsRequired() + .HasColumnType("text"); + + b.Property("ExpReward") + .HasColumnType("integer"); + + b.HasKey("GuildId"); + + b.ToTable("DropConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Channel") + .HasColumnType("numeric(20,0)"); + + b.Property("DmEnabled") + .HasColumnType("boolean"); + + b.Property("DmMessage") + .IsRequired() + .HasColumnType("text"); + + b.Property("ImageEnabled") + .HasColumnType("boolean"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarSize") + .HasColumnType("integer"); + + b.Property("AvatarX") + .HasColumnType("integer"); + + b.Property("AvatarY") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uploader") + .HasColumnType("numeric(20,0)"); + + b.Property("UsernameSize") + .HasColumnType("real"); + + b.Property("UsernameX") + .HasColumnType("integer"); + + b.Property("UsernameY") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GreetImage"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Property("GuildId") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Language") + .IsRequired() + .HasColumnType("text"); + + b.Property("Prefix") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("GuildId"); + + b.ToTable("GuildConfigs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("DecayEnabled") + .HasColumnType("boolean"); + + b.Property("LevelEnabled") + .HasColumnType("boolean"); + + b.Property("Multiplier") + .HasColumnType("integer"); + + b.Property("MultiplierEnd") + .HasColumnType("timestamp with time zone"); + + b.HasKey("GuildId"); + + b.ToTable("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinLeaveLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("MessageLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.Property("VoiceLogChannelId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId"); + + b.ToTable("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.GuildModerationLog", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("integer"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("MessageId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("GuildId", "Id"); + + b.ToTable("ModerationLogs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Internals.Log", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CallSite") + .IsRequired() + .HasColumnType("text"); + + b.Property("Exception") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .IsRequired() + .HasColumnType("text"); + + b.Property("Logger") + .IsRequired() + .HasColumnType("text"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("TimeStamp") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Logs"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelRequirement", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("Experience") + .HasColumnType("integer"); + + b.HasKey("Level"); + + b.ToTable("LevelRequirements"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.Property("Level") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Level")); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Money") + .HasColumnType("integer"); + + b.Property("RoleId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Level"); + + b.HasIndex("GuildId"); + + b.ToTable("LevelReward"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("Id") + .HasColumnType("numeric(20,0)"); + + b.Property("Currency") + .HasColumnType("bigint"); + + b.Property("CurrentLevelExperience") + .HasColumnType("bigint"); + + b.Property("DailyClaimed") + .HasColumnType("timestamp with time zone"); + + b.Property("DailyStreak") + .HasColumnType("integer"); + + b.Property("Experience") + .HasColumnType("bigint"); + + b.Property("Inactive") + .HasColumnType("boolean"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("NextLevelExperience") + .HasColumnType("bigint"); + + b.Property("TotalVoiceTime") + .HasColumnType("interval"); + + b.HasKey("GuildId", "Id"); + + b.HasIndex("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Inventory", b => + { + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("ItemId") + .HasColumnType("uuid"); + + b.Property("Amount") + .HasColumnType("integer"); + + b.HasKey("UserId", "ItemId"); + + b.HasIndex("ItemId"); + + b.ToTable("Inventory"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Item", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Price") + .HasColumnType("integer"); + + b.Property("TypeId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("TypeId"); + + b.ToTable("Items"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.ItemType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("ItemTypes"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("PremiumExpiration") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Warning", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("ModeratorId") + .HasColumnType("numeric(20,0)"); + + b.Property("Reason") + .IsRequired() + .HasColumnType("text"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.Property("Valid") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("Warnings"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Club.ClubMember", b => + { + b.HasOne("Hanekawa.Entities.Club.Club", "Club") + .WithMany("Members") + .HasForeignKey("GuildId", "ClubName") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hanekawa.Entities.Users.GuildUser", "User") + .WithMany() + .HasForeignKey("GuildId", "UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Club"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.AdminConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("AdminConfig") + .HasForeignKey("Hanekawa.Entities.Configs.AdminConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.BoostConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("BoostConfig") + .HasForeignKey("Hanekawa.Entities.Configs.BoostConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.CurrencyConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("CurrencyConfig") + .HasForeignKey("Hanekawa.Entities.Configs.CurrencyConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.DropConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("DropConfig") + .HasForeignKey("Hanekawa.Entities.Configs.DropConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("GreetConfig") + .HasForeignKey("Hanekawa.Entities.Configs.GreetConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetImage", b => + { + b.HasOne("Hanekawa.Entities.Configs.GreetConfig", "GreetConfig") + .WithMany("Images") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GreetConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LevelConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LevelConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LogConfig", b => + { + b.HasOne("Hanekawa.Entities.Configs.GuildConfig", "GuildConfig") + .WithOne("LogConfig") + .HasForeignKey("Hanekawa.Entities.Configs.LogConfig", "GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("GuildConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Levels.LevelReward", b => + { + b.HasOne("Hanekawa.Entities.Configs.LevelConfig", "LevelConfig") + .WithMany("Rewards") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("LevelConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.GuildUser", b => + { + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("GuildUsers") + .HasForeignKey("Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Inventory", b => + { + b.HasOne("Hanekawa.Entities.Users.Item", "Item") + .WithMany() + .HasForeignKey("ItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Hanekawa.Entities.Users.User", "User") + .WithMany("Inventory") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Item"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.Item", b => + { + b.HasOne("Hanekawa.Entities.Users.ItemType", "Type") + .WithMany("Items") + .HasForeignKey("TypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Type"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Club.Club", b => + { + b.Navigation("Members"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GreetConfig", b => + { + b.Navigation("Images"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.GuildConfig", b => + { + b.Navigation("AdminConfig"); + + b.Navigation("BoostConfig"); + + b.Navigation("CurrencyConfig"); + + b.Navigation("DropConfig"); + + b.Navigation("GreetConfig"); + + b.Navigation("LevelConfig"); + + b.Navigation("LogConfig"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Configs.LevelConfig", b => + { + b.Navigation("Rewards"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.ItemType", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Hanekawa.Entities.Users.User", b => + { + b.Navigation("GuildUsers"); + + b.Navigation("Inventory"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Hanekawa.Infrastructure/Triggers/ModlogBeforeTrigger.cs b/Hanekawa.Infrastructure/Triggers/ModlogBeforeTrigger.cs new file mode 100644 index 00000000..04de5247 --- /dev/null +++ b/Hanekawa.Infrastructure/Triggers/ModlogBeforeTrigger.cs @@ -0,0 +1,34 @@ +using System.Threading; +using System.Threading.Tasks; +using EntityFrameworkCore.Triggered; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Hanekawa.Infrastructure.Triggers; + +internal abstract class ModLogBeforeTrigger(IDbContext dbContext) : IBeforeSaveTrigger +{ + /// + /// Before saving the moderation log, set the ID to the number of moderation logs in the guild + /// + /// + /// + public async Task BeforeSave(ITriggerContext context, CancellationToken cancellationToken) + { + if(context.ChangeType is not ChangeType.Added) return; + + context.Entity.Id = + await dbContext.ModerationLogs.CountAsync(x => x.GuildId == context.Entity.GuildId, + cancellationToken: cancellationToken).ConfigureAwait(false) + 1; + } +} + +internal abstract class ModLogAfterTrigger : IAfterSaveTrigger +{ + public Task AfterSave(ITriggerContext context, CancellationToken cancellationToken) + { + if (context.ChangeType is ChangeType.Added) { } + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/Hanekawa.Shared/ApprovalQueueType.cs b/Hanekawa.Shared/ApprovalQueueType.cs deleted file mode 100644 index 5830487a..00000000 --- a/Hanekawa.Shared/ApprovalQueueType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum ApprovalQueueType - { - Welcome, - Profile - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/ChannelType.cs b/Hanekawa.Shared/ChannelType.cs deleted file mode 100644 index fb3752ad..00000000 --- a/Hanekawa.Shared/ChannelType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum ChannelType - { - Text, - Voice, - Category - } -} diff --git a/Hanekawa.Shared/Command/ColourService.cs b/Hanekawa.Shared/Command/ColourService.cs deleted file mode 100644 index a06ea738..00000000 --- a/Hanekawa.Shared/Command/ColourService.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.Collections.Concurrent; -using Disqord; -using Hanekawa.Shared.Interfaces; - -namespace Hanekawa.Shared.Command -{ - public class ColourService : INService - { - private readonly ConcurrentDictionary _colours = new ConcurrentDictionary(); - - public Color Get(ulong guildId) - => _colours.TryGetValue(guildId, out var color) ? color : Color.Purple; - - public void AddOrUpdate(ulong guildId, Color color) - => _colours.AddOrUpdate(guildId, color, (k, v) => color); - - public bool TryRemove(ulong guildId) => _colours.TryRemove(guildId, out _); - } - - public enum HanaColor - { - Default, - Green, - Red, - Blue, - Purple, - Pink, - Yellow, - Black, - White, - Brown, - Orange, - Aqua, - Maroon, - Olive, - Gray, - Silver, - Fuchsia, - Navy, - Teal, - Lime - } - - public static class HanaBaseColor - { - public static Color Default() => new Color(155, 89, 182); - public static Color Green() => new Color(46, 204, 113); - public static Color Red() => new Color(255, 105, 97); - public static Color Blue() => new Color(9, 132, 227); - public static Color Purple() => new Color(108, 92, 231); - public static Color Pink() => new Color(255, 159, 243); - public static Color Yellow() => new Color(241, 196, 15); - public static Color Black() => new Color(45, 52, 54); - public static Color White() => new Color(255, 255, 255); - public static Color Brown() => new Color(133, 96, 63); - public static Color Orange() => new Color(243, 156, 18); - public static Color Aqua() => new Color(98, 235, 250); - public static Color Maroon() => new Color(125, 105, 108); - public static Color Olive() => new Color(165, 166, 126); - public static Color Gray() => new Color(207, 207, 196); - public static Color Silver() => new Color(189, 195, 199); - public static Color Fuchsia() => new Color(255, 0, 255); - public static Color Navy() => new Color(65, 74, 187); - public static Color Teal() => new Color(99, 183, 183); - public static Color Lime() => new Color(119, 221, 119); - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Command/Extensions/Extensions.cs b/Hanekawa.Shared/Command/Extensions/Extensions.cs deleted file mode 100644 index 8f07b682..00000000 --- a/Hanekawa.Shared/Command/Extensions/Extensions.cs +++ /dev/null @@ -1,258 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Extensions.Interactivity; -using Disqord.Extensions.Interactivity.Menus.Paged; -using Disqord.Rest; - -namespace Hanekawa.Shared.Command.Extensions -{ - public static class Extensions - { - public static bool HasMentionPrefix(this IMessage message, IUser user, out string prefix, out string parsed) - { - var content = message.Content; - parsed = ""; - prefix = ""; - if (content.Length <= 3 || content[0] != '<' || content[1] != '@') - return false; - - var endPos = content.IndexOf('>'); - if (endPos == -1) return false; - - if (content.Length < endPos + 2 || content[endPos + 1] != ' ') - return false; - - if (!TryParseUser(content.Substring(0, endPos + 1), out var userId)) - return false; - - if (userId != user.Id.RawValue) return false; - parsed = content.Substring(endPos + 2); - - prefix = user.Mention; - return true; - } - - public static bool TryParseUser(string text, out ulong userId) - { - if (text.Length >= 3 && text[0] == '<' && text[1] == '@' && text[^1] == '>') - { - text = text.Length >= 4 && text[2] == '!' - ? text[3..^1] - : text[2..^1]; - - if (ulong.TryParse(text, NumberStyles.None, CultureInfo.InvariantCulture, out userId)) - return true; - } - - userId = 0; - return false; - } - - public static async Task ReplyAsync(this HanekawaCommandContext ctx, string content) => - await ctx.Channel.SendMessageAsync(null, false, new LocalEmbedBuilder - { - Color = ctx.Colour.Get(ctx.Guild.Id.RawValue), - Description = content - }.Build()); - - public static async Task ReplyAsync(this HanekawaCommandContext ctx, LocalEmbedBuilder embed) => - await ctx.Channel.SendMessageAsync(null, false, embed.Build()); - - public static async Task ReplyAsync(this HanekawaCommandContext ctx, string content, Color color) => - await ctx.Channel.SendMessageAsync(null, false, new LocalEmbedBuilder - { - Color = color, - Description = content - }.Build()); - - public static async Task PaginatedReply(this HanekawaCommandContext ctx, List content, - IUser userIcon, - string authorTitle, - string title = null, - int pageSize = 5) - => await PaginationBuilder(ctx, content, userIcon.GetAvatarUrl(), authorTitle ?? userIcon.Name, title, pageSize); - - public static async Task PaginatedReply(this HanekawaCommandContext ctx, List content, - IGuild guildIcon, - string authorTitle, - string title = null, - int pageSize = 5) - => await PaginationBuilder(ctx, content, guildIcon.GetIconUrl(), authorTitle ?? guildIcon.Name, title, pageSize); - - private static async Task PaginationBuilder(HanekawaCommandContext ctx, IReadOnlyList content, - string icon, - string authorTitle, - string title, - int pageSize) - { - var pages = new List(); - var sb = new StringBuilder(); - var color = ctx.Colour.Get(ctx.Guild.Id.RawValue); - for (var i = 0; i < content.Count;) - { - for (var j = 0; j < pageSize; j++) - { - if (i >= content.Count) continue; - var x = content[i]; - sb.AppendLine(x); - i++; - } - - var page = pages.Count + 1; - var maxPage = Convert.ToInt32(Math.Ceiling((double) content.Count / pageSize)); - pages.Add(new Page(new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder {Name = authorTitle, IconUrl = icon}, - Title = title, - Description = sb.ToString(), - Color = color, - Footer = new LocalEmbedFooterBuilder {Text = $"Page: {page}/{maxPage}"} - }.Build())); - sb.Clear(); - } - - await ctx.Bot.GetInteractivity() - .StartMenuAsync(ctx.Channel, new PagedMenu(ctx.User.Id.RawValue, new DefaultPageProvider(pages))); - } - - public static async Task ReplyAndDeleteAsync(this HanekawaCommandContext ctx, string content, - bool isTts = false, - LocalEmbedBuilder embed = null, - TimeSpan? timeout = null) - { - timeout ??= TimeSpan.FromSeconds(25); - var message = embed != null - ? await ctx.Channel.SendMessageAsync(content, isTts, embed.Build(), LocalMentions.NoEveryone) - .ConfigureAwait(false) - : await ctx.Channel.SendMessageAsync(content, isTts, null, LocalMentions.NoEveryone) - .ConfigureAwait(false); - try - { - _ = Task.Delay(timeout.Value) - .ContinueWith(_ => message.DeleteAsync().ConfigureAwait(false)) - .ConfigureAwait(false); - } - catch - { - // Ignore - } - return message; - } - - public static bool IsOverriden(this MethodInfo methodInfo) - { - return methodInfo == methodInfo?.GetBaseDefinition(); - } - - public static string Inspect(this object obj) - { - var type = obj.GetType(); - var overridenToString = type.GetMethod("ToString").IsOverriden(); - var props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(x => x.Name).ToArray(); - - var sb = new StringBuilder("```css\n"); - - //doesnt work - sb.AppendLine($"{{{type}: '{(overridenToString ? obj.ToString() : "")}'}}"); - sb.AppendLine(); - - var maxLength = props.Max(x => x.Name.Length); - - foreach (var prop in props) - { - sb.Append($"#{prop.Name.PadRight(maxLength, ' ')} - "); - - object value = null; - - try - { - value = prop.GetValue(obj); - } - catch (TargetInvocationException) { } //c# bad - - static string DateTimeNicefy(DateTimeOffset dateTime) - { - return $"{dateTime.Day}/{dateTime.Month}/{dateTime.Year} {dateTime.TimeOfDay.ToString("g").Split('.').First()}"; - } - - static string NicefyNamespace(Type inType) - { - var str = inType.ToString(); - - return str.Split('.', StringSplitOptions.RemoveEmptyEntries).Last(); - } - - type = value?.GetType(); - if (type is null) - { - continue; - } - - overridenToString = type.GetMethods() - .First(method => method.GetParameters().Length == 0 && method.Name == "ToString") - .IsOverriden(); - - switch (value) - { - case IEnumerable collection when !(value is string): - var count = collection.Cast().Count(); - sb.AppendLine($"[{count} item{(count == 1 ? "" : "s")}]"); - break; - - // case Enum @enum: - // sb.AppendLine($"[{@enum.Humanize()}]"); - // break; - - case string str: - sb.AppendLine($"[\"{str}\"]"); - break; - - case Task task: - var returnT = type.GetGenericArguments(); - sb.AppendLine(returnT.Length > 0 - ? $"[Task<{string.Join(", ", returnT.Select(NicefyNamespace))}>]" - : "[Task]"); - break; - - case DateTime dt: - sb.AppendLine($"[{DateTimeNicefy(dt)}]"); - break; - - case DateTimeOffset dto: - sb.AppendLine($"[{DateTimeNicefy(dto)}]"); - break; - - default: - if (overridenToString) - { - sb.AppendLine($"[{value}]"); - } - else - { - if (type?.IsValueType == false) - { - var niceName = NicefyNamespace(type); - sb.AppendLine($"[{niceName}]"); - } - else - { - sb.AppendLine($"[{value}]"); - } - } - break; - } - } - - sb.AppendLine("```"); - - return sb.ToString(); - } - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Command/HanaCooldown.cs b/Hanekawa.Shared/Command/HanaCooldown.cs deleted file mode 100644 index fa77bcf3..00000000 --- a/Hanekawa.Shared/Command/HanaCooldown.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Shared.Command -{ - public enum HanaCooldown - { - User, - Guild - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Command/HanekawaCommandContext.cs b/Hanekawa.Shared/Command/HanekawaCommandContext.cs deleted file mode 100644 index 90e2e7a7..00000000 --- a/Hanekawa.Shared/Command/HanekawaCommandContext.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Disqord; -using Disqord.Bot; -using Disqord.Bot.Prefixes; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Shared.Command -{ - public class HanekawaCommandContext : DiscordCommandContext - { - public IServiceScope Scope { get; } - public ColourService Colour { get; } - public new DiscordBot Bot { get; } - public new CachedMember Member { get; } - public new CachedTextChannel Channel { get; } - - public HanekawaCommandContext(IServiceScope scope, DiscordBot bot, IPrefix prefix, CachedUserMessage message, ColourService colour) - : base(bot, prefix, message, scope.ServiceProvider) - { - if (!(message.Author is CachedMember member && message.Channel is CachedTextChannel channel)) - { - throw new InvalidOperationException("Bot should not be used in dms"); - } - Scope = scope; - Bot = bot; - Member = member; - Channel = channel; - Colour = colour; - } - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Command/HanekawaCommandModule.cs b/Hanekawa.Shared/Command/HanekawaCommandModule.cs deleted file mode 100644 index c7db448b..00000000 --- a/Hanekawa.Shared/Command/HanekawaCommandModule.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Rest; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Shared.Command -{ - public abstract class HanekawaCommandModule : DiscordModuleBase - { - protected async Task ReplyAsync(string content) => await ReplyAsync(null, false, - new LocalEmbedBuilder - { - Description = content, - Color = Context.ServiceProvider.GetRequiredService().Get(Context.Guild.Id.RawValue) - }.Build(), LocalMentions.None); - - protected async Task ReplyAsync(LocalEmbedBuilder embed) - { - embed.Color ??= Context.ServiceProvider.GetRequiredService() - .Get(Context.Guild.Id.RawValue); - return await ReplyAsync(null, false, embed.Build(), LocalMentions.None); - } - - protected async Task ReplyAsync(string content, Color color) => await ReplyAsync(null, false, - new LocalEmbedBuilder { Description = content, Color = color }.Build(), LocalMentions.None); - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Command/RoslynCommandContext.cs b/Hanekawa.Shared/Command/RoslynCommandContext.cs deleted file mode 100644 index 4cc3c851..00000000 --- a/Hanekawa.Shared/Command/RoslynCommandContext.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Hanekawa.Shared.Command.Extensions; - -namespace Hanekawa.Shared.Command -{ - public class RoslynCommandContext - { - public HanekawaCommandContext Context { get; } - - public RoslynCommandContext(HanekawaCommandContext context) - { - Context = context; - } - - public string Inspect(object obj) - { - return obj.Inspect(); - } - } -} diff --git a/Hanekawa.Shared/Command/TypeParser/HanekawaTypeParser.cs b/Hanekawa.Shared/Command/TypeParser/HanekawaTypeParser.cs deleted file mode 100644 index f5e5335b..00000000 --- a/Hanekawa.Shared/Command/TypeParser/HanekawaTypeParser.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Threading.Tasks; -using Qmmands; - -namespace Hanekawa.Shared.Command -{ - public abstract class HanekawaTypeParser : TypeParser - { - /* - public override ValueTask> ParseAsync(Parameter parameter, string value, - CommandContext context) - => ParseAsync(parameter, value, (HanekawaContext)context, ((HanekawaContext) context)?.ServiceProvider); - - public abstract ValueTask> ParseAsync(Parameter parameter, string value, HanekawaContext context, - IServiceProvider provider); - */ - } -} diff --git a/Hanekawa.Shared/Game/EnemyType.cs b/Hanekawa.Shared/Game/EnemyType.cs deleted file mode 100644 index 6b2a5678..00000000 --- a/Hanekawa.Shared/Game/EnemyType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Shared.Game -{ - public enum EnemyType - { - Player, - Npc - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Game/HungerGame/ActionType.cs b/Hanekawa.Shared/Game/HungerGame/ActionType.cs deleted file mode 100644 index 6c6cb63d..00000000 --- a/Hanekawa.Shared/Game/HungerGame/ActionType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Hanekawa.Shared.Game.HungerGame -{ - public enum ActionType - { - Loot, - Attack, - Idle, - Meet, - Hack, - Die, - Sleep, - Eat, - None - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Game/HungerGame/HungerGameStage.cs b/Hanekawa.Shared/Game/HungerGame/HungerGameStage.cs deleted file mode 100644 index bb3598ea..00000000 --- a/Hanekawa.Shared/Game/HungerGame/HungerGameStage.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Shared.Game.HungerGame -{ - public enum HungerGameStage - { - Signup, - OnGoing, - Closed - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/GiveawayType.cs b/Hanekawa.Shared/GiveawayType.cs deleted file mode 100644 index 3c7fd982..00000000 --- a/Hanekawa.Shared/GiveawayType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum GiveawayType - { - Vote, - Reaction, - Activity - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Hanekawa.Shared.csproj b/Hanekawa.Shared/Hanekawa.Shared.csproj deleted file mode 100644 index 4d342b1c..00000000 --- a/Hanekawa.Shared/Hanekawa.Shared.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net5.0 - 8 - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Hanekawa.Shared/Interfaces/INService.cs b/Hanekawa.Shared/Interfaces/INService.cs deleted file mode 100644 index a31dd67c..00000000 --- a/Hanekawa.Shared/Interfaces/INService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Hanekawa.Shared.Interfaces -{ - public interface INService { } - public interface ISingleton { } - public interface ITransient { } -} \ No newline at end of file diff --git a/Hanekawa.Shared/Interfaces/IRequired.cs b/Hanekawa.Shared/Interfaces/IRequired.cs deleted file mode 100644 index b769d23e..00000000 --- a/Hanekawa.Shared/Interfaces/IRequired.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Hanekawa.Shared.Interfaces -{ - public interface IRequired { } -} \ No newline at end of file diff --git a/Hanekawa.Shared/ItemType.cs b/Hanekawa.Shared/ItemType.cs deleted file mode 100644 index 0f1876bc..00000000 --- a/Hanekawa.Shared/ItemType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum ItemType - { - ServerRole, - HungerGame, - Food, - Potion, - Flask, - Armor, - Weapon, - ProfBackground, - Trash - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/ModAction.cs b/Hanekawa.Shared/ModAction.cs deleted file mode 100644 index e7c6bad0..00000000 --- a/Hanekawa.Shared/ModAction.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum ModAction - { - Mute, - UnMute, - Ban, - Unban - } -} \ No newline at end of file diff --git a/Hanekawa.Shared/WarnLogType.cs b/Hanekawa.Shared/WarnLogType.cs deleted file mode 100644 index f7762aa2..00000000 --- a/Hanekawa.Shared/WarnLogType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum WarnLogType - { - Simple, - Full - } -} diff --git a/Hanekawa.Shared/WarnReason.cs b/Hanekawa.Shared/WarnReason.cs deleted file mode 100644 index a356f20f..00000000 --- a/Hanekawa.Shared/WarnReason.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Hanekawa.Shared -{ - public enum WarnReason - { - Warned, - Muted - } -} \ No newline at end of file diff --git a/Hanekawa.Tests/Common/TestUsers.cs b/Hanekawa.Tests/Common/TestUsers.cs new file mode 100644 index 00000000..6d6a2c94 --- /dev/null +++ b/Hanekawa.Tests/Common/TestUsers.cs @@ -0,0 +1,69 @@ +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Users; + +namespace Hanekawa.Tests.Common; + +public static class TestUsers +{ + public static readonly DiscordMember TestMember = new() + { + Id = 1, + Username = "Test-User", + Nickname = "Test-Nick", + IsBot = false, + RoleIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], + AvatarUrl = string.Empty, + VoiceSessionId = null, + GuildId = 1, + Guild = new Guild + { + GuildId = 1, + Description = string.Empty, + Emotes = [ + new Emote { + Id = 1, + Name = "Test-Emote", + Format = "", + IsAnimated = false, + IsAvailable = false, + IsManaged = false + }, + new Emote + { + Id = 2, + Name = "Test-Emote-2", + Format = "", + IsAnimated = false, + IsAvailable = false, + IsManaged = false + } + ], + Name = "Test-Guild", + MemberCount = 1, + EmoteCount = 1, + IconUrl = string.Empty + } + }; + + public static readonly GuildUser TestUser = new() + { + Id = 1, + GuildId = 1, + Currency = 0, + Experience = 1, + Level = 1, + DailyClaimed = DateTimeOffset.UtcNow, + DailyStreak = 0, + LastSeen = DateTimeOffset.UtcNow, + CurrentLevelExperience = 1, + NextLevelExperience = 10, + TotalVoiceTime = TimeSpan.Zero, + User = new User + { + Id = 1, + PremiumExpiration = DateTimeOffset.UtcNow.AddDays(-1), + Inventory = [], + GuildUsers = [TestUser] + } + }; +} \ No newline at end of file diff --git a/Hanekawa.Tests/Hanekawa.Tests.csproj b/Hanekawa.Tests/Hanekawa.Tests.csproj new file mode 100644 index 00000000..d0dda633 --- /dev/null +++ b/Hanekawa.Tests/Hanekawa.Tests.csproj @@ -0,0 +1,33 @@ + + + + net9.0 + preview + enable + enable + + false + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + \ No newline at end of file diff --git a/Hanekawa.Tests/ImageServiceTests/CommonImageRetrival.cs b/Hanekawa.Tests/ImageServiceTests/CommonImageRetrival.cs new file mode 100644 index 00000000..5c518305 --- /dev/null +++ b/Hanekawa.Tests/ImageServiceTests/CommonImageRetrival.cs @@ -0,0 +1,15 @@ +using SixLabors.Fonts; + +namespace Hanekawa.Tests.ImageServiceTests; + +public static class CommonImageRetrival +{ + public static FontCollection GetTestFontCollection() + { + var fontCollection = new FontCollection(); + fontCollection.Add(@"Data/Fonts/ARIAL.TTF"); + fontCollection.Add(@"Data/Fonts/TIMES.TTF"); + fontCollection.AddSystemFonts(); + return fontCollection; + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/ImageServiceTests/ProfilePictureTests.cs b/Hanekawa.Tests/ImageServiceTests/ProfilePictureTests.cs new file mode 100644 index 00000000..46d2d851 --- /dev/null +++ b/Hanekawa.Tests/ImageServiceTests/ProfilePictureTests.cs @@ -0,0 +1,39 @@ +using Hanekawa.Application.Services; +using Hanekawa.Application.Services.Images; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Users; +using Microsoft.Extensions.Logging; +using Moq; +using SixLabors.Fonts; + +namespace Hanekawa.Tests.ImageServiceTests; + +public class ProfilePictureTests +{ + private readonly Mock _httpClientFactoryMock = new(); + private readonly Mock> _loggerMock = new(); + private readonly ImageService _imageServiceMock; + + public ProfilePictureTests() + { + _httpClientFactoryMock.Setup(x => x.CreateClient(It.IsAny())) + .Returns(new HttpClient()); + } + + [Fact] + public async Task GetProfilePictureAsync_WithValidUser_ReturnsProfilePicture() + { + // Arrange + + // Act + Stream result = await _imageServiceMock.DrawProfileAsync(new DiscordMember(), new GuildUser(), CancellationToken.None); + + // Assert + } + + [Fact] + public async Task GetProfilePictureAsync_WithInvalidUser_ReturnsNull() + { + + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/ImageServiceTests/RankPictureTests.cs b/Hanekawa.Tests/ImageServiceTests/RankPictureTests.cs new file mode 100644 index 00000000..fa8bb8ec --- /dev/null +++ b/Hanekawa.Tests/ImageServiceTests/RankPictureTests.cs @@ -0,0 +1,36 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Services; +using Hanekawa.Application.Services.Images; +using Hanekawa.Entities.Settings.Images; +using Hanekawa.Tests.Common; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Moq; + +namespace Hanekawa.Tests.ImageServiceTests; + +public class RankPictureTests +{ + [Fact] + public async Task DrawRankAsync_ReturnsStream() + { + // Arrange + var httpClientFactory = new Mock(); + var fontCollection = CommonImageRetrival.GetTestFontCollection(); + var imageSettings = new Mock>(); + var logger = new Mock>(); + var dbContext = new Mock(); + var configService = new Mock(); + + var imageService = new ImageService(httpClientFactory.Object, fontCollection, + imageSettings.Object, logger.Object, dbContext.Object, configService.Object); + var discordMember = TestUsers.TestMember; + var guildUser = TestUsers.TestUser; + + // Act + var stream = await imageService.DrawRankAsync(discordMember, guildUser, CancellationToken.None); + + // Assert + Assert.NotNull(stream); + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/Level/LevelService.UnitTest.cs b/Hanekawa.Tests/Level/LevelService.UnitTest.cs new file mode 100644 index 00000000..92043c72 --- /dev/null +++ b/Hanekawa.Tests/Level/LevelService.UnitTest.cs @@ -0,0 +1,118 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Services; +using Hanekawa.Entities.Configs; +using Hanekawa.Entities.Discord; +using Hanekawa.Entities.Levels; +using Hanekawa.Entities.Users; +using MediatR; +using Microsoft.Extensions.Logging; +using MockQueryable.Moq; +using Moq; + +namespace Hanekawa.Tests.Level; + +public class LevelServiceUnitTest +{ + private readonly LevelService _levelService; + private readonly Mock> _mockLogger = new(); + private readonly Mock _mockdb = new(); + private readonly Mock _mockBot = new(); + private readonly Mock _mockMediator = new(); + + private readonly DiscordMember _member = new() + { Id = 1, Guild = new Guild { GuildId = 1 }, Username = "Bob", RoleIds = [ 1, 2, 3 ] }; + private readonly GuildConfig _config = new () + { + GuildId = 1, + LevelConfig = new LevelConfig + { + GuildId = 1, + Multiplier = 1, + DecayEnabled = false, + LevelEnabled = true, + MultiplierEnd = DateTimeOffset.MinValue, + Rewards = + [ + new LevelReward { GuildId = 1, Level = 1, Money = 0, RoleId = 3 }, + new LevelReward { GuildId = 1, Level = 2, Money = 100, RoleId = 4 }, + new LevelReward { GuildId = 1, Level = 3, Money = 200, RoleId = 5 }, + new LevelReward { GuildId = 1, Level = 4, Money = 300, RoleId = 6 }, + new LevelReward { GuildId = 1, Level = 5, Money = 400, RoleId = 7 }, + new LevelReward { GuildId = 1, Level = 6, Money = 500, RoleId = 8 }, + new LevelReward { GuildId = 1, Level = 7, Money = 600, RoleId = 9 }, + new LevelReward { GuildId = 1, Level = 8, Money = 700, RoleId = 10 } + ] + } + }; + + private readonly GuildUser _user = new() + { + GuildId = 1, + Id = 1, + Experience = 0, + Level = 1, + DailyClaimed = DateTimeOffset.Now, + DailyStreak = 0, + LastSeen = DateTimeOffset.Now, + User = new User(), + CurrentLevelExperience = 0, + NextLevelExperience = 200, + TotalVoiceTime = TimeSpan.Zero + }; + + public LevelServiceUnitTest() => _levelService = new LevelService(_mockdb.Object, _mockLogger.Object, _mockBot.Object, _mockMediator.Object); + + [Fact] + public async Task LevelService_AddExperienceAsync_Returns_100() + { + // Arrange + var configDbSet = new List { _config } + .AsQueryable().BuildMockDbSet(); + var levelDbSet = new List { new() { Level = 2, Experience = 400 } } + .AsQueryable().BuildMockDbSet(); + var userDbSet = new List { _user } + .AsQueryable().BuildMockDbSet(); + + _mockdb.Setup(e => e.GuildConfigs).Returns(configDbSet.Object); + _mockdb.Setup(e => e.LevelRequirements).Returns(levelDbSet.Object); + _mockdb.Setup(e => e.Users).Returns(userDbSet.Object); + + const int experience = 100; + const int expected = 100; + + // Act + var actual = await _levelService.AddExperienceAsync(_member, experience); + + // Assert + Assert.Equal(expected, actual); + } + + [Fact] + public async Task LevelService_AddExperienceAsync_Returns_200_And_Level_WithRole() + { + // Arrange + _user.Experience = 300; + + var configDbSet = new List { _config } + .AsQueryable().BuildMockDbSet(); + var levelDbSet = new List { new() { Level = 2, Experience = 400 } } + .AsQueryable().BuildMockDbSet(); + var userDbSet = new List { _user } + .AsQueryable().BuildMockDbSet(); + + _mockdb.Setup(e => e.GuildConfigs).Returns(configDbSet.Object); + _mockdb.Setup(e => e.LevelRequirements).Returns(levelDbSet.Object); + _mockdb.Setup(e => e.Users).Returns(userDbSet.Object); + + const int experience = 200; + const int expected = 200; + + // Act + var actual = await _levelService.AddExperienceAsync(_member, experience); + + // Assert + Assert.Equal(expected, actual); + Assert.Equal(2, _user.Level); + Assert.Equal(_member.RoleIds, new List { 1, 2, 3, 4 }); + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/Mediatr/Warnings/WarningClearHandlerTests.cs b/Hanekawa.Tests/Mediatr/Warnings/WarningClearHandlerTests.cs new file mode 100644 index 00000000..d92b64aa --- /dev/null +++ b/Hanekawa.Tests/Mediatr/Warnings/WarningClearHandlerTests.cs @@ -0,0 +1,6 @@ +namespace Hanekawa.Tests.Mediatr.Warnings; + +public class WarningClearHandlerTests +{ + +} \ No newline at end of file diff --git a/Hanekawa.Tests/Mediatr/Warnings/WarningListHandlerTests.cs b/Hanekawa.Tests/Mediatr/Warnings/WarningListHandlerTests.cs new file mode 100644 index 00000000..3a0fa7d5 --- /dev/null +++ b/Hanekawa.Tests/Mediatr/Warnings/WarningListHandlerTests.cs @@ -0,0 +1,6 @@ +namespace Hanekawa.Tests.Mediatr.Warnings; + +public class WarningListHandlerTests +{ + +} \ No newline at end of file diff --git a/Hanekawa.Tests/Mediatr/Warnings/WarningReceivedTests.cs b/Hanekawa.Tests/Mediatr/Warnings/WarningReceivedTests.cs new file mode 100644 index 00000000..f5d514fa --- /dev/null +++ b/Hanekawa.Tests/Mediatr/Warnings/WarningReceivedTests.cs @@ -0,0 +1,31 @@ +using Hanekawa.Application.Handlers.Services.Warnings; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Discord; +using Moq; + +namespace Hanekawa.Tests.Mediatr.Warnings; + +public class WarningReceivedTests +{ + private WarningReceivedHandler Mediatr { get; set; } = null!; + private readonly Mock _dbContext = new(); + + [Fact] + public async Task WarningReceived_Should_Add_Warning() + { + // Arrange + Mediatr = new WarningReceivedHandler(_dbContext.Object); + var received = + new WarningReceived(new DiscordMember { Guild = new Guild { GuildId = ulong.MinValue }, Username = "", }, + "", 1); + // Act + var result = await Mediatr.Handle(received, CancellationToken.None); + // Assert + } + + [Fact] + public void WarningReceived_Should_Ban_user() + { + + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/Services/ClubCommandServiceTests.cs b/Hanekawa.Tests/Services/ClubCommandServiceTests.cs new file mode 100644 index 00000000..41ca1d0e --- /dev/null +++ b/Hanekawa.Tests/Services/ClubCommandServiceTests.cs @@ -0,0 +1,373 @@ +using Hanekawa.Application.Handlers.Commands.Club; +using Hanekawa.Application.Interfaces; +using Hanekawa.Entities.Club; +using Moq; +using Moq.EntityFrameworkCore; + +namespace Hanekawa.Tests.Services; + +public class ClubCommandServiceTests +{ + private readonly Mock _mockDbContext; + private readonly ClubCommandService _clubCommandService; + private readonly ulong _guildId = 123456789; + private readonly ulong _userId = 987654321; + + public ClubCommandServiceTests() + { + _mockDbContext = new Mock(); + _clubCommandService = new ClubCommandService(_mockDbContext.Object); + } + + [Fact] + public async Task Create_Should_CreateNewClub_When_ValidInput() + { + // Arrange + var clubs = new List(); + var clubMembers = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + _mockDbContext.Setup(db => db.ClubMembers).ReturnsDbSet(clubMembers); + _mockDbContext.Setup(db => db.SaveChangesAsync(It.IsAny())).ReturnsAsync(1); + + // Act + var result = await _clubCommandService.Create(_guildId, "TestClub", "Test Description", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("Club 'TestClub' has been created successfully!", result.Value.Content); + } + + [Fact] + public async Task Create_Should_ReturnError_When_ClubNameAlreadyExists() + { + // Arrange + var existingClub = new Club { GuildId = _guildId, Name = "TestClub", OwnerId = 111111 }; + var clubs = new List { existingClub }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Create(_guildId, "TestClub", "Test Description", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("A club with the name 'TestClub' already exists", result.Value.Content); + Assert.Single(clubs); // No new club added + } + + [Fact] + public async Task Create_Should_ReturnError_When_UserAlreadyOwnsClub() + { + // Arrange + var existingClub = new Club { GuildId = _guildId, Name = "OtherClub", OwnerId = _userId }; + var clubs = new List { existingClub }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Create(_guildId, "TestClub", "Test Description", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("You already own a club. You can only own one club at a time.", result.Value.Content); + Assert.Single(clubs); // No new club added + } + + [Fact] + public async Task Delete_Should_DeleteClub_When_UserIsOwner() + { + // Arrange + var existingClub = new Club { GuildId = _guildId, Name = "TestClub", OwnerId = _userId }; + var clubs = new List { existingClub }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + _mockDbContext.Setup(db => db.SaveChangesAsync(It.IsAny())).ReturnsAsync(1); + + // Act + var result = await _clubCommandService.Delete(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("Club 'TestClub' has been deleted successfully", result.Value.Content); + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + } + + [Fact] + public async Task Delete_Should_ReturnError_When_ClubDoesNotExist() + { + // Arrange + var clubs = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Delete(_guildId, "NonExistentClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("Club 'NonExistentClub' doesn't exist", result.Value.Content); + } + + [Fact] + public async Task Delete_Should_ReturnError_When_UserIsNotOwner() + { + // Arrange + var existingClub = new Club { GuildId = _guildId, Name = "TestClub", OwnerId = 111111 }; // Different owner + var clubs = new List { existingClub }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Delete(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("You don't have permission to delete this club", result.Value.Content); + } + + [Fact] + public async Task List_Should_ListAllClubs() + { + // Arrange + var clubs = new List + { + new Club { GuildId = _guildId, Name = "Club1", Description = "First club", Members = new List { new ClubMember() } }, + new Club { GuildId = _guildId, Name = "Club2", Description = "Second club", Members = new List { new ClubMember(), new ClubMember() } } + }; + + var queryableClubs = clubs.AsQueryable(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(queryableClubs); + + // Act + var result = await _clubCommandService.List(_guildId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Contains("**Clubs in this server:**", result.Value.Content); + Assert.Contains("Club1", result.Value.Content); + Assert.Contains("Club2", result.Value.Content); + Assert.Contains("(1 members)", result.Value.Content); + Assert.Contains("(2 members)", result.Value.Content); + } + + [Fact] + public async Task List_Should_ReturnMessage_When_NoClubsExist() + { + // Arrange + var clubs = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.List(_guildId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("No clubs found in this server", result.Value.Content); + } + + [Fact] + public async Task Join_Should_AddUserToClub() + { + // Arrange + var club = new Club { GuildId = _guildId, Name = "TestClub", Members = new List() }; + var clubs = new List { club }; + var clubMembers = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + _mockDbContext.Setup(db => db.ClubMembers).ReturnsDbSet(clubMembers); + _mockDbContext.Setup(db => db.SaveChangesAsync(It.IsAny())).ReturnsAsync(1); + + // Act + var result = await _clubCommandService.Join(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("You have joined the club 'TestClub'", result.Value.Content); + } + + [Fact] + public async Task Join_Should_ReturnError_When_ClubDoesNotExist() + { + // Arrange + var clubs = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Join(_guildId, "NonExistentClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("Club 'NonExistentClub' doesn't exist", result.Value.Content); + } + + [Fact] + public async Task Join_Should_ReturnError_When_UserAlreadyMember() + { + // Arrange + var member = new ClubMember { GuildId = _guildId, ClubName = "TestClub", UserId = _userId }; + var club = new Club { GuildId = _guildId, Name = "TestClub", Members = new List { member } }; + var clubs = new List { club }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Join(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("You are already a member of this club", result.Value.Content); + } + + [Fact] + public async Task Leave_Should_RemoveUserFromClub() + { + // Arrange + var member = new ClubMember { GuildId = _guildId, ClubName = "TestClub", UserId = _userId }; + var club = new Club + { + GuildId = _guildId, + Name = "TestClub", + OwnerId = 111111, // Different owner + Members = new List { member } + }; + var clubs = new List { club }; + var clubMembers = new List { member }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + _mockDbContext.Setup(db => db.ClubMembers).ReturnsDbSet(clubMembers); + _mockDbContext.Setup(db => db.SaveChangesAsync(It.IsAny())).ReturnsAsync(1); + + // Act + var result = await _clubCommandService.Leave(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("You have left the club 'TestClub'", result.Value.Content); + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + } + + [Fact] + public async Task Leave_Should_ReturnError_When_ClubDoesNotExist() + { + // Arrange + var clubs = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Leave(_guildId, "NonExistentClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("Club 'NonExistentClub' doesn't exist", result.Value.Content); + } + + [Fact] + public async Task Leave_Should_ReturnError_When_UserIsOwner() + { + // Arrange + var club = new Club + { + GuildId = _guildId, + Name = "TestClub", + OwnerId = _userId, + Members = new List { new ClubMember { UserId = _userId } } + }; + var clubs = new List { club }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Leave(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("As the owner, you cannot leave your club. You must delete it or transfer ownership first.", result.Value.Content); + } + + [Fact] + public async Task Leave_Should_ReturnError_When_UserNotMember() + { + // Arrange + var club = new Club + { + GuildId = _guildId, + Name = "TestClub", + OwnerId = 111111, + Members = new List() // Empty members list + }; + var clubs = new List { club }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Leave(_guildId, "TestClub", _userId); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("You are not a member of this club", result.Value.Content); + } + + [Fact] + public async Task Info_Should_ReturnClubDetails() + { + // Arrange + var createdAt = DateTimeOffset.UtcNow.AddDays(-10); + var joinedAt = DateTimeOffset.UtcNow.AddDays(-5); + + var member = new ClubMember + { + GuildId = _guildId, + ClubName = "TestClub", + UserId = _userId, + JoinedAt = joinedAt + }; + + var club = new Club + { + GuildId = _guildId, + Name = "TestClub", + Description = "Test Description", + OwnerId = _userId, + CreatedAt = createdAt, + Members = new List { member } + }; + + var clubs = new List { club }; + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Info(_guildId, "TestClub"); + + // Assert + Assert.True(result.IsSuccess); + Assert.Contains("**Club: TestClub**", result.Value.Content); + Assert.Contains("Description: Test Description", result.Value.Content); + Assert.Contains($"Owner: <@{_userId}>", result.Value.Content); + Assert.Contains($"Created: {createdAt:yyyy-MM-dd}", result.Value.Content); + Assert.Contains("Members: 1", result.Value.Content); + Assert.Contains("**Member List:**", result.Value.Content); + Assert.Contains($"<@{_userId}> (joined: {joinedAt:yyyy-MM-dd}) 👑", result.Value.Content); + } + + [Fact] + public async Task Info_Should_ReturnError_When_ClubDoesNotExist() + { + // Arrange + var clubs = new List(); + + _mockDbContext.Setup(db => db.Clubs).ReturnsDbSet(clubs); + + // Act + var result = await _clubCommandService.Info(_guildId, "NonExistentClub"); + + // Assert + Assert.True(result.IsSuccess); + Assert.Equal("Club 'NonExistentClub' doesn't exist", result.Value.Content); + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/Services/InventoryServiceTests.cs b/Hanekawa.Tests/Services/InventoryServiceTests.cs new file mode 100644 index 00000000..90317a95 --- /dev/null +++ b/Hanekawa.Tests/Services/InventoryServiceTests.cs @@ -0,0 +1,336 @@ +using Hanekawa.Application.Interfaces; +using Hanekawa.Application.Services; +using Hanekawa.Entities.Users; +using Microsoft.EntityFrameworkCore; +using Moq; + +namespace Hanekawa.Tests.Services; + +public class InventoryServiceTests +{ + private readonly Mock _mockDbContext; + private readonly Mock _mockCache; + private readonly IInventoryService _inventoryService; + private readonly Mock> _mockUserDbSet; + + public InventoryServiceTests() + { + _mockDbContext = new Mock(); + _mockCache = new Mock(); + _mockUserDbSet = new Mock>(); + + _mockDbContext.Setup(db => db.Users).Returns(_mockUserDbSet.Object); + + _inventoryService = new InventoryService(_mockDbContext.Object, _mockCache.Object); + } + + [Fact] + public async Task GetInventoryAsync_CallsCache_ReturnsUser() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var user = new GuildUser { GuildId = guildId, Id = userId }; + + _mockCache.Setup(c => c.GetOrCreateAsync($"inventory_{userId}", It.IsAny>>())) + .ReturnsAsync(user); + + // Act + var result = await _inventoryService.GetInventoryAsync(guildId, userId); + + // Assert + Assert.Equal(userId, result.Id); + Assert.Equal(guildId, result.GuildId); + _mockCache.Verify(c => c.GetOrCreateAsync($"inventory_{userId}", It.IsAny>>()), Times.Once); + } + + [Fact] + public async Task UpdateInventoryAsync_WithList_UpdatesUserInventory() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var user = new GuildUser { GuildId = guildId, Id = userId }; + var appUser = new User { Id = userId, Inventory = new List() }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + var inventory = new List + { + new() { ItemId = Guid.NewGuid(), Amount = 5, UserId = userId } + }; + + SetupMockDbContextForUser(existingUser); + + // Act + await _inventoryService.UpdateInventoryAsync(user, inventory); + + // Assert + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + _mockCache.Verify(c => c.Remove($"inventory_{userId}"), Times.Once); + Assert.Same(inventory, existingUser.User.Inventory); + } + + [Fact] + public async Task UpdateInventoryAsync_WithSingleItem_UpdatesUserInventory() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + var appUser = new User { Id = userId, Inventory = new List() }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + var inventoryItem = new Inventory { ItemId = itemId, Amount = 5, UserId = userId }; + + SetupMockDbContextForUser(existingUser); + + // Act + await _inventoryService.UpdateInventoryAsync(user, inventoryItem); + + // Assert + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + _mockCache.Verify(c => c.Remove($"inventory_{userId}"), Times.Once); + Assert.Contains(existingUser.User.Inventory, i => i.ItemId == itemId); + } + + [Fact] + public async Task AddItemAsync_ExistingItem_IncreasesAmount() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var existingInventory = new List + { + new() { ItemId = itemId, Amount = 2, UserId = userId } + }; + var appUser = new User { Id = userId, Inventory = existingInventory }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act + await _inventoryService.AddItemAsync(user, itemId, 3); + + // Assert + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + _mockCache.Verify(c => c.Remove($"inventory_{userId}"), Times.Once); + + var updatedItem = existingUser.User.Inventory.FirstOrDefault(i => i.ItemId == itemId); + Assert.NotNull(updatedItem); + Assert.Equal(5, updatedItem.Amount); // 2 + 3 = 5 + } + + [Fact] + public async Task AddItemAsync_NewItem_AddsToInventory() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var appUser = new User { Id = userId, Inventory = new List() }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act + await _inventoryService.AddItemAsync(user, itemId, 3); + + // Assert + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + _mockCache.Verify(c => c.Remove($"inventory_{userId}"), Times.Once); + + var addedItem = existingUser.User.Inventory.FirstOrDefault(i => i.ItemId == itemId); + Assert.NotNull(addedItem); + Assert.Equal(3, addedItem.Amount); + } + + [Fact] + public async Task RemoveItemAsync_SufficientAmount_DecreasesAmount() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var existingInventory = new List + { + new() { ItemId = itemId, Amount = 5, UserId = userId } + }; + var appUser = new User { Id = userId, Inventory = existingInventory }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act + await _inventoryService.RemoveItemAsync(user, itemId, 3); + + // Assert + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + _mockCache.Verify(c => c.Remove($"inventory_{userId}"), Times.Once); + + var updatedItem = existingUser.User.Inventory.FirstOrDefault(i => i.ItemId == itemId); + Assert.NotNull(updatedItem); + Assert.Equal(2, updatedItem.Amount); // 5 - 3 = 2 + } + + [Fact] + public async Task RemoveItemAsync_RemoveAll_RemovesItemFromInventory() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var existingInventory = new List + { + new() { ItemId = itemId, Amount = 3, UserId = userId } + }; + var appUser = new User { Id = userId, Inventory = existingInventory }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act + await _inventoryService.RemoveItemAsync(user, itemId, 3); + + // Assert + _mockDbContext.Verify(db => db.SaveChangesAsync(It.IsAny()), Times.Once); + _mockCache.Verify(c => c.Remove($"inventory_{userId}"), Times.Once); + + Assert.Empty(existingUser.User.Inventory); + } + + [Fact] + public async Task RemoveItemAsync_InsufficientAmount_ThrowsException() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var existingInventory = new List + { + new() { ItemId = itemId, Amount = 2, UserId = userId } + }; + var appUser = new User { Id = userId, Inventory = existingInventory }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act & Assert + await Assert.ThrowsAsync( + async () => await _inventoryService.RemoveItemAsync(user, itemId, 3)); + } + + [Fact] + public async Task HasItemAsync_ItemExists_ReturnsTrue() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var existingInventory = new List + { + new() { ItemId = itemId, Amount = 2, UserId = userId } + }; + var appUser = new User { Id = userId, Inventory = existingInventory }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act + var result = await _inventoryService.HasItemAsync(user, itemId); + + // Assert + Assert.True(result); + } + + [Fact] + public async Task HasItemAsync_ItemDoesNotExist_ReturnsFalse() + { + // Arrange + const ulong guildId = 123; + const ulong userId = 456; + var itemId = Guid.NewGuid(); + var user = new GuildUser { GuildId = guildId, Id = userId }; + + var appUser = new User { Id = userId, Inventory = new List() }; + var existingUser = new GuildUser { GuildId = guildId, Id = userId, User = appUser }; + + SetupMockDbContextForUser(existingUser); + + // Act + var result = await _inventoryService.HasItemAsync(user, itemId); + + // Assert + Assert.False(result); + } + + [Fact] + public async Task GetItemCountAsync_ItemExists_ReturnsAmount() + { + // Arrange + const ulong userId = 456; + var itemId = Guid.NewGuid(); + const int expectedAmount = 5; + + var queryable = new List + { + new() + { + Id = userId, + User = new User + { + Id = userId, + Inventory = new List + { + new() { ItemId = itemId, Amount = expectedAmount, UserId = userId } + } + } + } + }.AsQueryable(); + + var mockQueryable = queryable.BuildMockDbSet(); + _mockUserDbSet.Setup(m => m.Include(It.IsAny())).Returns(mockQueryable.Object); + + // Act + var result = await _inventoryService.GetItemCountAsync(userId, itemId); + + // Assert + Assert.Equal(expectedAmount, result); + } + + // Helper method to set up the mock DbContext for user-related operations + private void SetupMockDbContextForUser(GuildUser existingUser) + { + var queryable = new List { existingUser }.AsQueryable(); + var mockQueryable = queryable.BuildMockDbSet(); + _mockUserDbSet.Setup(m => m.Include(It.IsAny())).Returns(mockQueryable.Object); + } +} + +// Extension method to help build mock DbSets +public static class MockExtensions +{ + public static Mock> BuildMockDbSet(this IQueryable queryable) where T : class + { + var mockSet = new Mock>(); + mockSet.As>().Setup(m => m.Provider).Returns(queryable.Provider); + mockSet.As>().Setup(m => m.Expression).Returns(queryable.Expression); + mockSet.As>().Setup(m => m.ElementType).Returns(queryable.ElementType); + mockSet.As>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator()); + + return mockSet; + } +} \ No newline at end of file diff --git a/Hanekawa.Tests/Usings.cs b/Hanekawa.Tests/Usings.cs new file mode 100644 index 00000000..8c927eb7 --- /dev/null +++ b/Hanekawa.Tests/Usings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/Hanekawa.sln b/Hanekawa.sln index 1300b052..18125c65 100644 --- a/Hanekawa.sln +++ b/Hanekawa.sln @@ -1,15 +1,16 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.28803.156 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hanekawa.Database", "Hanekawa.Database\Hanekawa.Database.csproj", "{56714493-6317-4237-B7EA-9A9A25E1C999}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hanekawa.Bot", "Hanekawa.Bot\Hanekawa.Bot.csproj", "{FF8EAC21-1450-FAED-FDF8-A14E83399CDF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hanekawa", "Hanekawa\Hanekawa.csproj", "{36916A6C-1437-4D5E-AF90-245145F30BED}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hanekawa.Infrastructure", "Hanekawa.Infrastructure\Hanekawa.Infrastructure.csproj", "{6E4DDA37-C749-2A03-FB73-E0314FDD5C5A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hanekawa.Shared", "Hanekawa.Shared\Hanekawa.Shared.csproj", "{BB7BFBBF-6D9A-4183-B8B7-524DDC0D2B08}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hanekawa", "Hanekawa\Hanekawa.csproj", "{F15A1159-6D34-DE83-C18D-28A6EEF0B0EF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hanekawa.HungerGames", "Hanekawa.HungerGames\Hanekawa.HungerGames.csproj", "{C617CC96-B2EE-4E5B-ADB5-68EA9C06F1E2}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hanekawa.Application", "Hanekawa.Application\Hanekawa.Application.csproj", "{94DDA4CF-403D-EFAF-0BCD-9071BD6E8FF8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hanekawa.Test", "Hanekawa.Test\Hanekawa.Test.csproj", "{A608AE03-147B-194A-82EC-83EF07ABBCA3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,27 +18,31 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {56714493-6317-4237-B7EA-9A9A25E1C999}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {56714493-6317-4237-B7EA-9A9A25E1C999}.Debug|Any CPU.Build.0 = Debug|Any CPU - {56714493-6317-4237-B7EA-9A9A25E1C999}.Release|Any CPU.ActiveCfg = Release|Any CPU - {56714493-6317-4237-B7EA-9A9A25E1C999}.Release|Any CPU.Build.0 = Release|Any CPU - {36916A6C-1437-4D5E-AF90-245145F30BED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {36916A6C-1437-4D5E-AF90-245145F30BED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {36916A6C-1437-4D5E-AF90-245145F30BED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {36916A6C-1437-4D5E-AF90-245145F30BED}.Release|Any CPU.Build.0 = Release|Any CPU - {BB7BFBBF-6D9A-4183-B8B7-524DDC0D2B08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BB7BFBBF-6D9A-4183-B8B7-524DDC0D2B08}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BB7BFBBF-6D9A-4183-B8B7-524DDC0D2B08}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BB7BFBBF-6D9A-4183-B8B7-524DDC0D2B08}.Release|Any CPU.Build.0 = Release|Any CPU - {C617CC96-B2EE-4E5B-ADB5-68EA9C06F1E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C617CC96-B2EE-4E5B-ADB5-68EA9C06F1E2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C617CC96-B2EE-4E5B-ADB5-68EA9C06F1E2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C617CC96-B2EE-4E5B-ADB5-68EA9C06F1E2}.Release|Any CPU.Build.0 = Release|Any CPU + {FF8EAC21-1450-FAED-FDF8-A14E83399CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FF8EAC21-1450-FAED-FDF8-A14E83399CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FF8EAC21-1450-FAED-FDF8-A14E83399CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FF8EAC21-1450-FAED-FDF8-A14E83399CDF}.Release|Any CPU.Build.0 = Release|Any CPU + {6E4DDA37-C749-2A03-FB73-E0314FDD5C5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6E4DDA37-C749-2A03-FB73-E0314FDD5C5A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6E4DDA37-C749-2A03-FB73-E0314FDD5C5A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6E4DDA37-C749-2A03-FB73-E0314FDD5C5A}.Release|Any CPU.Build.0 = Release|Any CPU + {F15A1159-6D34-DE83-C18D-28A6EEF0B0EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F15A1159-6D34-DE83-C18D-28A6EEF0B0EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F15A1159-6D34-DE83-C18D-28A6EEF0B0EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F15A1159-6D34-DE83-C18D-28A6EEF0B0EF}.Release|Any CPU.Build.0 = Release|Any CPU + {94DDA4CF-403D-EFAF-0BCD-9071BD6E8FF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {94DDA4CF-403D-EFAF-0BCD-9071BD6E8FF8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {94DDA4CF-403D-EFAF-0BCD-9071BD6E8FF8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {94DDA4CF-403D-EFAF-0BCD-9071BD6E8FF8}.Release|Any CPU.Build.0 = Release|Any CPU + {A608AE03-147B-194A-82EC-83EF07ABBCA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A608AE03-147B-194A-82EC-83EF07ABBCA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A608AE03-147B-194A-82EC-83EF07ABBCA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A608AE03-147B-194A-82EC-83EF07ABBCA3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {61A5A529-674B-4109-90E2-C18E07D397A9} + SolutionGuid = {F478A445-C5E0-44B3-9128-0C0A88902BAA} EndGlobalSection EndGlobal diff --git a/Hanekawa.slnx b/Hanekawa.slnx new file mode 100644 index 00000000..2cbe9f34 --- /dev/null +++ b/Hanekawa.slnx @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Hanekawa/Bot/Hanekawa.cs b/Hanekawa/Bot/Hanekawa.cs deleted file mode 100644 index c9fe22de..00000000 --- a/Hanekawa/Bot/Hanekawa.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Reflection; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Bot.Parsers; -using Disqord.Bot.Prefixes; -using Hanekawa.Bot.TypeReaders; -using Hanekawa.Shared.Command; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot -{ - public class Hanekawa : DiscordBot - { - public Hanekawa(TokenType tokenType, string token, IPrefixProvider prefixProvider, DiscordBotConfiguration configuration) : base(tokenType, token, prefixProvider, configuration) - { - AddModules(Assembly.GetEntryAssembly()); - RemoveTypeParser(GetSpecificTypeParser()); - RemoveTypeParser(GetSpecificTypeParser()); - RemoveTypeParser(GetSpecificTypeParser>()); - RemoveTypeParser(GetSpecificTypeParser>()); - RemoveTypeParser(GetSpecificTypeParser>()); - RemoveTypeParser(GetSpecificTypeParser>()); - RemoveTypeParser(GetSpecificTypeParser()); - - AddTypeParser(new CachedRoleTypeParser(StringComparison.OrdinalIgnoreCase)); - AddTypeParser(new CachedUserTypeParser(StringComparison.OrdinalIgnoreCase)); - AddTypeParser(new CachedGuildChannelTypeParser(StringComparison.OrdinalIgnoreCase)); - AddTypeParser(new CachedGuildChannelTypeParser(StringComparison.OrdinalIgnoreCase)); - AddTypeParser(new CachedGuildChannelTypeParser(StringComparison.OrdinalIgnoreCase)); - AddTypeParser(new CachedGuildChannelTypeParser(StringComparison.OrdinalIgnoreCase)); - AddTypeParser(new TimeSpanTypeParser()); - AddTypeParser(new ColourTypeParser()); - AddTypeParser(new RangeTypeParser()); - - CommandExecuted += HaneCommandExecuted; - } - - private Task HaneCommandExecuted(CommandExecutedEventArgs e) - { - (e.Context as HanekawaCommandContext)?.Scope.Dispose(); - return Task.CompletedTask; - } - - protected override ValueTask CheckMessageAsync(CachedUserMessage message) => - new(!message.Author.IsBot && !(message.Channel is IPrivateChannel)); - - protected override ValueTask GetCommandContextAsync(CachedUserMessage message, - IPrefix prefix) - { - var scope = this.CreateScope(); - return new ValueTask(new HanekawaCommandContext(scope, this, prefix, message, scope.ServiceProvider.GetRequiredService())); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Account/Profile.cs b/Hanekawa/Bot/Modules/Account/Account/Profile.cs deleted file mode 100644 index 61339f14..00000000 --- a/Hanekawa/Bot/Modules/Account/Account/Profile.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Database; -using Hanekawa.Shared.Command; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Account -{ - public partial class Account - { - [Name("Profile")] - [Command("profile")] - [Description("Showcase yours or another persons profile")] - [RequireBotGuildPermissions(Permission.AttachFiles, Permission.SendMessages)] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - [RequiredChannel] - public async Task ProfileAsync(CachedMember user = null) - { - user ??= Context.Member; - await Context.Channel.TriggerTypingAsync(); - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - await using var image = await _image.ProfileBuilder(user, db); - image.Position = 0; - await Context.Channel.SendMessageAsync(new LocalAttachment(image, "profile.png")); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Account/Rank.cs b/Hanekawa/Bot/Modules/Account/Account/Rank.cs deleted file mode 100644 index 801bf343..00000000 --- a/Hanekawa/Bot/Modules/Account/Account/Rank.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Bot.Services.ImageGen; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Account -{ - [Name("Account")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public partial class Account : HanekawaCommandModule - { - private readonly ExpService _exp; - private readonly ImageGenerator _image; - - public Account(ExpService exp, ImageGenerator image) - { - _exp = exp; - _image = image; - } - - [Name("Rank")] - [Command("rank")] - [Description("Display your rank, level and exp within the server, also global rank")] - [RequiredChannel] - public async Task RankAsync(CachedMember user = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - user ??= Context.Member; - var serverData = await db.GetOrCreateUserData(user); - var globalData = await db.GetOrCreateGlobalUserData(user); - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder {Name = user.DisplayName}, - ThumbnailUrl = user.GetAvatarUrl(), - Color = Context.Colour.Get(Context.Guild.Id.RawValue), - Fields = - { - new LocalEmbedFieldBuilder {Name = "Level", Value = $"{serverData.Level}", IsInline = true}, - new LocalEmbedFieldBuilder - { - Name = "Exp", - Value = $"{serverData.Exp}/{_exp.ExpToNextLevel(serverData)}", - IsInline = true - }, - new LocalEmbedFieldBuilder - { - Name = "Rank", - Value = - $"{await db.Accounts.CountAsync(x => x.GuildId == Context.Guild.Id.RawValue && x.TotalExp >= serverData.TotalExp)}" + - $"/{await db.Accounts.CountAsync(x => x.GuildId == Context.Guild.Id.RawValue)}", - IsInline = false - }, - new LocalEmbedFieldBuilder - { - Name = "Global Rank", - Value = - $"{await db.AccountGlobals.CountAsync(x => x.TotalExp >= globalData.TotalExp)}" + - $"/{await db.AccountGlobals.CountAsync()}", - IsInline = false - } - } - }; - await Context.ReplyAsync(embed); - } - - [Name("Level Leaderboard")] - [Command("top", "leaderboard", "lb")] - [Description("Displays highest ranked users")] - [RequiredChannel] - public async Task LeaderboardAsync(int amount = 100) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var toGet = Context.Guild.MemberCount < amount ? Context.Guild.MemberCount : amount; - var users = await db.Accounts.Where(x => x.GuildId == Context.Guild.Id.RawValue && x.Active).OrderByDescending(x => x.TotalExp - x.Decay).Take(toGet).ToArrayAsync(); - var result = new List(); - var strBuilder = new StringBuilder(); - for (var i = 0; i < users.Length; i++) - { - var user = users[i]; - var username = await Context.Guild.GetOrFetchMemberAsync(user.UserId); - if (username == null) - { - user.Active = false; - continue; - } - strBuilder.AppendLine($"**Rank: {i + 1}** - {username.Mention}"); - strBuilder.Append($"-> Level:{user.Level} - Total Exp: {user.TotalExp}"); - result.Add(strBuilder.ToString()); - strBuilder.Clear(); - } - - await db.SaveChangesAsync(); - await Context.PaginatedReply(result, Context.Guild, $"Leaderboard for {Context.Guild.Name}", pageSize: 10); - } - - [Name("Reputation")] - [Command("rep")] - [Description("Rewards a reputation to a user. Usable once a day")] - [Remarks("rep @bob#0000")] - [RequiredChannel] - public async Task RepAsync(CachedMember user = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cdCheck = await db.GetOrCreateUserData(Context.Member); - if (user == null || user == Context.User) - { - if (cdCheck.RepCooldown.Date.AddDays(1) > DateTime.UtcNow) - { - var timer = cdCheck.RepCooldown.Date.AddDays(1) - DateTime.UtcNow; - await Context.ReplyAsync( - $"{Context.User.Mention} daily rep refresh in {timer.Humanize(2)}\n" + - "Reputation reset at midnight UTC!"); - } - else - { - await Context.ReplyAsync( - $"{Context.User.Mention}, you got a reputation point available!", - Color.Green); - } - - return; - } - - if (cdCheck.RepCooldown.Date.AddDays(1) > DateTime.UtcNow) - { - var timer = cdCheck.RepCooldown.Date.AddDays(1) - DateTime.UtcNow; - await Context.ReplyAsync($"{Context.User.Mention} daily rep refresh in {timer.Humanize(2)}\n" + - "Reputation reset at midnight UTC!", - Color.Red); - return; - } - - var userData = await db.GetOrCreateUserData(user); - cdCheck.RepCooldown = DateTime.UtcNow.Date; - userData.Rep++; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Rewarded {user.Mention} with a reputation point!", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Economy/Balance.cs b/Hanekawa/Bot/Modules/Account/Economy/Balance.cs deleted file mode 100644 index 8e8117da..00000000 --- a/Hanekawa/Bot/Modules/Account/Economy/Balance.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Economy; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Account.Economy -{ - public partial class Economy - { - private readonly CurrencyService _currency; - public Economy(CurrencyService currency) => _currency = currency; - - [Name("Wallet")] - [Command("wallet", "balance", "money")] - [Description("Display how much credit you or someone else got")] - [RequiredChannel] - public async Task WalletAsync(CachedMember user = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - user ??= Context.Member; - var userData = await db.GetOrCreateUserData(user); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - var embed = new LocalEmbedBuilder() - .Create($"{cfg.CurrencyName}: {_currency.ToCurrency(cfg, userData.Credit)}\n" + - $" {cfg.SpecialCurrencyName}: {_currency.ToCurrency(cfg, userData.CreditSpecial, true)}", Context.Colour.Get(Context.Guild.Id.RawValue)) - .WithAuthor(new LocalEmbedAuthorBuilder {IconUrl = user.GetAvatarUrl(), Name = user.DisplayName}); - await ReplyAsync(null, false, embed.Build()); - } - - [Name("Give")] - [Command("give", "transfer")] - [Description("Transfer credit between users")] - [RequiredChannel] - public async Task GiveCreditAsync(int amount, params CachedMember[] users) - { - if (amount <= 0) return; - if (users.Contains(Context.User)) return; - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(Context.Member); - var currencyCfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (userData.Credit < amount * users.Length) - { - await Context.ReplyAsync($"{Context.User.Mention} doesn't have enough {currencyCfg.CurrencyName}", - Color.Red); - return; - } - - var strBuilder = new StringBuilder(); - for (var i = 0; i < users.Length; i++) - { - var user = users[i]; - var receiverData = await db.GetOrCreateUserData(user); - - userData.Credit -= amount; - receiverData.Credit += amount; - strBuilder.AppendLine($"{user.Mention}"); - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"{Context.User.Mention} transferred {_currency.ToCurrency(currencyCfg, amount)} to:\n{strBuilder}", - Color.Green); - } - - [Name("Daily")] - [Command("daily")] - [Description("Daily credit command, usable once every 18hrs")] - [RequiredChannel] - public async Task DailyAsync(CachedMember user = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(Context.Member); - var currencyCfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (userData.DailyCredit.Date.AddDays(1) > DateTime.UtcNow) - { - var timer = userData.DailyCredit.Date.AddDays(1) - DateTime.UtcNow; - await Context.ReplyAsync( - $"{Context.User.Mention} daily {currencyCfg.CurrencyName} refresh in {timer.Humanize(2)}\n" + - "Dailies reset at midnight UTC!", - Color.Red); - return; - } - - int reward; - if (user == null || user == Context.User) - { - user = Context.Member; - reward = 200; - userData.DailyCredit = DateTime.UtcNow.Date; - userData.Credit += reward; - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Rewarded {user.Mention} with {_currency.ToCurrency(currencyCfg, reward)}", - Color.Green); - } - else - { - reward = new Random().Next(200, 300); - var receiverData = await db.GetOrCreateUserData(user); - userData.DailyCredit = DateTime.UtcNow.Date; - receiverData.Credit += reward; - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"{Context.User.Mention} rewarded {user.Mention} with {_currency.ToCurrency(currencyCfg, reward)}", Color.Green); - } - } - - [Name("Richest")] - [Command("richest")] - [Description("Displays top 10 users on the money leaderboard")] - [RequiredChannel] - public async Task LeaderboardAsync(int amount = 50) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - - amount = Context.Guild.MemberCount < amount ? Context.Guild.MemberCount : amount; - var users = await db.Accounts.Where(x => x.Active && x.GuildId == Context.Guild.Id.RawValue) - .OrderByDescending(account => account.Credit).Take(amount).ToListAsync(); - var pages = new List(); - var strBuilder = new StringBuilder(); - for (var i = 0; i < users.Count; i++) - { - var x = users[i]; - var user = await Context.Guild.GetOrFetchMemberAsync(x.UserId); - if (user == null) - { - x.Active = false; - continue; - } - strBuilder.AppendLine($"**Rank: {i + 1}** - {user.Mention}"); - strBuilder.Append($"-> {cfg.CurrencyName}: {_currency.ToCurrency(cfg, x.Credit)}"); - pages.Add(strBuilder.ToString()); - strBuilder.Clear(); - } - - await db.SaveChangesAsync(); - await Context.PaginatedReply(pages, Context.Guild, $"Money leaderboard for {Context.Guild.Name}", pageSize: 10); - } - - [Name("Reward")] - [Command("reward", "award")] - [Description("Rewards special credit to users (does not remove from yourself)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RewardCreditAsync(int amount, params CachedMember[] users) - { - if (amount <= 0) return; - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var strBuilder = new StringBuilder(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - for (var i = 0; i < users.Length; i++) - { - var user = users[i]; - var userData = await db.GetOrCreateUserData(user); - userData.CreditSpecial += amount; - strBuilder.AppendLine($"{user.Mention}"); - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Rewarded {_currency.ToCurrency(cfg, amount, true)} to:\n {strBuilder}", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Economy/Currency.cs b/Hanekawa/Bot/Modules/Account/Economy/Currency.cs deleted file mode 100644 index f1e43fb9..00000000 --- a/Hanekawa/Bot/Modules/Account/Economy/Currency.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Account.Economy -{ - [Name("Economy")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public partial class Economy : HanekawaCommandModule - { - [Name("Regular Currency Name")] - [Command("rcn")] - [Description("Change the name of regular currency (default: credit)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetRegularNameAsync([Remainder] string name = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (name.IsNullOrWhiteSpace()) - { - cfg.CurrencyName = "Credit"; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Set regular back to default `Credit`", Color.Green); - return; - } - - cfg.CurrencyName = name; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set regular currency name to {name}", Color.Green); - } - - [Name("Special Currency Name")] - [Command("scn")] - [Description("Change the name of special currency (default: special credit)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetSpecialNameAsync([Remainder] string name = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (name.IsNullOrWhiteSpace()) - { - cfg.SpecialCurrencyName = "Special Credit"; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Set regular back to default `Special Credit`", - Color.Green); - return; - } - - cfg.SpecialCurrencyName = name; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set regular currency name to {name}", Color.Green); - } - - [Name("Regular Currency Symbol")] - [Command("rcs")] - [Description("Change the symbol of regular currency (default: $)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetRegularSymbolAsync(LocalCustomEmoji emote) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - cfg.EmoteCurrency = true; - cfg.CurrencySign = emote.MessageFormat; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set regular currency sign to {emote}", Color.Green); - } - - [Name("Regular Currency Symbol")] - [Command("rcs")] - [Description("Change the symbol of regular currency (default: $)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetRegularSymbolAsync([Remainder] string symbol) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (symbol.IsNullOrWhiteSpace()) symbol = "$"; - - cfg.EmoteCurrency = false; - cfg.CurrencySign = symbol; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set regular currency sign to {symbol}", Color.Green); - } - - [Name("Special Currency Symbol")] - [Command("scs")] - [Description("Change the symbol of special currency (default: $)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetSpecialSymbolAsync(LocalCustomEmoji emote) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - cfg.SpecialEmoteCurrency = true; - cfg.SpecialCurrencySign = emote.MessageFormat; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set special currency sign to {emote}", Color.Green); - } - - [Name("Special Currency Symbol")] - [Command("scs")] - [Description("Change the symbol of special currency (default: $)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetSpecialSymbolAsync([Remainder] string symbol) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (symbol.IsNullOrWhiteSpace()) symbol = "$"; - - cfg.SpecialEmoteCurrency = false; - cfg.SpecialCurrencySign = symbol; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set special currency sign to {symbol}", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Gamble/Gamble.cs b/Hanekawa/Bot/Modules/Account/Gamble/Gamble.cs deleted file mode 100644 index af40afae..00000000 --- a/Hanekawa/Bot/Modules/Account/Gamble/Gamble.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Account.Gamble -{ - [Name("Gamble")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public class Gamble : HanekawaCommandModule - { - [Name("Bet")] - [Command("bet")] - [Description("Gamble a certain amount and win 5x. Bet with the bot in an attempt to get same number.")] - [RequiredChannel] - public async Task BetAsync(int bet) - { - if (bet <= 0) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(Context.Member); - if (userData.Credit == 0) - { - await Context.ReplyAsync($"{Context.User.Mention} doesn't have any credit to gamble with", - Color.Red); - return; - } - - await Context.ReplyAsync(await GambleBetAsync(db, Context, userData, bet)); - } - - [Name("Roll")] - [Command("roll")] - [Description("Gamble a certain amount and win up to 3x. Roll 1-100, above 50 and win")] - [RequiredChannel] - public async Task RollAsync(int bet) - { - if (bet <= 0) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(Context.Member); - if (userData.Credit == 0) - { - await Context.ReplyAsync($"{Context.User.Mention} doesn't have any credit to gamble with", - Color.Red); - return; - } - - await Context.ReplyAsync(await GambleRollAsync(db, Context, userData, bet)); - } - - private async Task GambleBetAsync(DbService db, DiscordCommandContext context, - Database.Tables.Account.Account userData, int bet) - { - if (userData.Credit < bet) bet = BetAdjust(userData); - if (bet > 5000) bet = BetAdjust(); - var userRoll = new Random().Next(1, 6); - var botRoll = new Random().Next(1, 9); - if (userRoll == botRoll) - { - userData.Credit += bet * 5; - await db.SaveChangesAsync(); - return new LocalEmbedBuilder().Create( - $"Congratulations {context.User.Mention}!, You made a total of **${bet * 5}** off ${bet}!\n" + - $"You rolled: {userRoll} - Bot rolled: {botRoll}", Color.Green); - } - - userData.Credit -= bet; - await db.SaveChangesAsync(); - return new LocalEmbedBuilder().Create( - $"Sorry **{context.User.Mention}**, You rolled **{userRoll}** and lost ${bet}\n " + - $"You rolled:{userRoll} - Bot rolled: {botRoll}", Color.Red); - } - - private async Task GambleRollAsync(DbService db, DiscordCommandContext context, - Database.Tables.Account.Account userData, int bet) - { - if (userData.Credit < bet) bet = BetAdjust(userData); - if (bet > 5000) bet = BetAdjust(); - - var rolled = new Random().Next(1, 100); - - if (rolled >= 90) - { - userData.Credit += bet * 2; - await db.SaveChangesAsync(); - return new LocalEmbedBuilder().Create( - $"{context.User.Mention} rolled **{rolled}** and won ${bet * 2}", - Color.Green); - } - - if (rolled >= 50) - { - userData.Credit += bet; - await db.SaveChangesAsync(); - return new LocalEmbedBuilder().Create($"{context.User.Mention} rolled **{rolled}** and won ${bet}", - Color.Green); - } - - userData.Credit -= bet; - await db.SaveChangesAsync(); - return new LocalEmbedBuilder().Create( - $"Sorry **{context.User.Mention}**, You have lost ${bet} Off a roll of **{rolled}**", - Color.Red); - } - - private static int BetAdjust(Database.Tables.Account.Account userData) => - userData.Credit >= 25000 ? 25000 : userData.Credit; - - private static int BetAdjust() => 5000; - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Store/Store.cs b/Hanekawa/Bot/Modules/Account/Store/Store.cs deleted file mode 100644 index 3b3854a1..00000000 --- a/Hanekawa/Bot/Modules/Account/Store/Store.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Economy; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Account.Store -{ - [Name("Store")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public partial class Store : HanekawaCommandModule - { - private readonly CurrencyService _currency; - public Store(CurrencyService currency) => _currency = currency; - - [Name("Inventory")] - [Command("inventory", "inv")] - [Description("Inventory of user")] - [RequiredChannel] - public async Task InventoryAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var inventory = await db.Inventories - .Where(x => x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue).ToListAsync(); - if (inventory.Count == 0) - { - await Context.ReplyAsync("Your inventory is empty"); - return; - } - - var result = new List(); - for (var i = 0; i < inventory.Count; i++) - { - var x = inventory[i]; - var item = await db.Items.FirstOrDefaultAsync(z => z.Id == x.ItemId); - if (item == null || !item.Role.HasValue) continue; - var role = Context.Guild.GetRole(item.Role.Value); - if (role == null) continue; - result.Add($"{role.Name} - Amount: {x.Amount}"); - } - - if (result.Count == 0) - { - await Context.ReplyAsync("Your inventory is empty"); - return; - } - - await Context.PaginatedReply(result, Context.Member, $"Inventory for {Context.User}"); - } - - [Name("Equip")] - [Command("equip", "use")] - [Description("Equips a role you have in your inventory")] - [RequiredChannel] - public async Task EquipRoleAsync([Remainder] CachedRole role) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var inventory = await db.Inventories - .Where(x => x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue).ToListAsync(); - var item = await db.Items.FirstOrDefaultAsync(z => z.GuildId == Context.Guild.Id.RawValue && z.Role == role.Id.RawValue); - if (inventory.FirstOrDefault(x => x.ItemId == item.Id) == null) - { - await Context.ReplyAsync("You do not own this item"); - return; - } - - if (Context.Member.Roles.Values.Contains(role)) - { - await Context.ReplyAsync("You already have this role added"); - return; - } - - await Context.Member.TryAddRoleAsync(role); - await Context.ReplyAsync($"{Context.User.Mention} equipped {role.Name}"); - } - - [Name("Unequip")] - [Command("unequip", "unuse")] - [Description("Equips a role you have in your inventory")] - [RequiredChannel] - public async Task UnequipRoleAsync([Remainder] CachedRole role) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var inventory = await db.Inventories - .Where(x => x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue).ToListAsync(); - var item = await db.Items.FirstOrDefaultAsync(z => z.GuildId == Context.Guild.Id.RawValue && z.Role == role.Id.RawValue); - if (inventory.FirstOrDefault(x => x.ItemId == item.Id) == null) - { - await Context.ReplyAsync("You can't remove a role you do not own or have."); - return; - } - - if (!Context.Member.Roles.Values.Contains(role)) - { - await Context.ReplyAsync("You don't have this role added"); - return; - } - - await Context.Member.TryRemoveRoleAsync(role); - await Context.ReplyAsync($"{Context.User.Mention} unequipped {role.Name}"); - } - - [Name("Store")] - [Command("store", "shop")] - [Description("Displays the server store")] - [RequiredChannel] - public async Task ServerShopAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - var store = await db.ServerStores.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - if (store.Count == 0) - { - await Context.ReplyAsync("Store is empty"); - return; - } - - var result = new List(); - for (var i = 0; i < store.Count; i++) - { - var x = store[i]; - result.Add( - $"{Context.Guild.GetRole(x.RoleId).Name ?? "No role found"} - {_currency.ToCurrency(cfg, x.Price, x.SpecialCredit)}"); - } - - await Context.PaginatedReply(result, Context.Guild, $"Store for {Context.Guild.Name}"); - } - - [Name("Buy")] - [Command("buy")] - [Description("Purchase an item from the store")] - [Priority(1)] - [RequiredChannel] - public async Task BuyAsync([Remainder] CachedRole role) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var serverData = - await db.ServerStores.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.RoleId == role.Id.RawValue); - if (serverData == null) - { - await Context.ReplyAsync("Couldn't find an item with that ID."); - return; - } - - var userData = await db.GetOrCreateUserData(Context.Member); - var item = await db.Items.FirstOrDefaultAsync(x => x.GuildId == Context.Guild.Id.RawValue && x.Role == role.Id.RawValue); - var creditCfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - if (serverData.SpecialCredit) - { - if (userData.CreditSpecial < serverData.Price) - { - await Context.ReplyAsync( - $"You do not have enough {_currency.ToCurrency(creditCfg, serverData.Price, true)} to purchase {role.Name}", - Color.Red); - return; - } - } - else - { - if (userData.Credit < serverData.Price) - { - await Context.ReplyAsync( - $"You do not have enough {_currency.ToCurrency(creditCfg, serverData.Price)} to purchase {role.Name}", - Color.Red); - return; - } - } - - var invItem = await db.Inventories.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue && x.ItemId == item.Id); - if (invItem != null) - { - await Context.ReplyAsync($"You've already purchased {Context.Guild.GetRole(item.Role.Value).Name}.", - Color.Red); - return; - } - - if (serverData.SpecialCredit) userData.CreditSpecial -= serverData.Price; - else userData.Credit -= serverData.Price; - - await db.Inventories.AddAsync(new Inventory - { - Amount = 1, - GuildId = Context.Guild.Id.RawValue, - UserId = Context.User.Id.RawValue, - ItemId = item.Id - }); - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Purchased {Context.Guild.GetRole(item.Role.Value)} for {_currency.ToCurrency(creditCfg, serverData.Price, serverData.SpecialCredit)}", - Color.Green); - await Context.Member.TryAddRoleAsync(role); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Account/Store/StoreAdmin.cs b/Hanekawa/Bot/Modules/Account/Store/StoreAdmin.cs deleted file mode 100644 index efc46f7d..00000000 --- a/Hanekawa/Bot/Modules/Account/Store/StoreAdmin.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Database.Tables.Stores; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Account.Store -{ - public partial class Store - { - [Name("Store add")] - [Command("sa")] - [Description("Adds an item to the store with regular credit")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddStoreItemAsync(int price, [Remainder] CachedRole role) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var date = DateTime.UtcNow; - var item = new Item - { - GuildId = Context.Guild.Id.RawValue, - Role = role.Id.RawValue, - DateAdded = date - }; - var storeItem = new ServerStore - { - GuildId = Context.Guild.Id.RawValue, - Price = price, - SpecialCredit = false, - RoleId = role.Id.RawValue - }; - var creditCfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - await db.Items.AddAsync(item); - await db.ServerStores.AddAsync(storeItem); - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Added {role.Name} to the shop for {_currency.ToCurrency(creditCfg, price)}", - Color.Green); - } - - [Name("Store add special")] - [Command("sas")] - [Description("Adds an item to the store with special credit")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddSpecialStoreItemAsync(int price, [Remainder] CachedRole role) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var date = DateTime.UtcNow; - var item = new Item - { - GuildId = Context.Guild.Id.RawValue, - Role = role.Id.RawValue, - DateAdded = date - }; - var storeItem = new ServerStore - { - GuildId = Context.Guild.Id.RawValue, - Price = price, - SpecialCredit = true, - RoleId = role.Id.RawValue - }; - var creditCfg = await db.GetOrCreateCurrencyConfigAsync(Context.Guild); - await db.Items.AddAsync(item); - await db.ServerStores.AddAsync(storeItem); - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Added {role.Name} to the shop for {_currency.ToCurrency(creditCfg, price, true)}", - Color.Green); - } - - [Name("Store remove")] - [Command("sr")] - [Description("Removes a role from the store")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveStoreItemAsync([Remainder] CachedRole role) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var itemCheck = - await db.Items.FirstOrDefaultAsync(x => x.GuildId == Context.Guild.Id.RawValue && x.Role == role.Id.RawValue); - if (itemCheck == null) - { - await Context.ReplyAsync($"{role.Name} is not a part of the store"); - return; - } - - var serverItem = await db.ServerStores.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.RoleId == role.Id.RawValue); - - db.ServerStores.Remove(serverItem); - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Removed {role.Name} from the server store"); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Administration/Administration.cs b/Hanekawa/Bot/Modules/Administration/Administration.cs deleted file mode 100644 index 052212ba..00000000 --- a/Hanekawa/Bot/Modules/Administration/Administration.cs +++ /dev/null @@ -1,387 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Rest; -using Hanekawa.Bot.Services.Administration.Mute; -using Hanekawa.Bot.Services.Administration.Warning; -using Hanekawa.Bot.Services.Caching; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Moderation; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Range = Hanekawa.Models.Range; - -namespace Hanekawa.Bot.Modules.Administration -{ - [Name("Administration")] - [Description("Moderation commands")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public class Administration : HanekawaCommandModule - { - private readonly MuteService _mute; - private readonly WarnService _warn; - private readonly CacheService _cache; - - public Administration(MuteService mute, WarnService warn, CacheService cache) - { - _mute = mute; - _warn = warn; - _cache = cache; - } - - [Name("Ban")] - [Command("ban")] - [Description("Bans a user")] - [Priority(1)] - [RequireMemberGuildPermissions(Permission.BanMembers, Permission.ManageMessages)] - public async Task BanAsync(CachedMember user, [Remainder] string reason = "No reason applied") - { - if (user == Context.User) return; - await Context.Message.TryDeleteMessageAsync(); - if (Context.User == user) return; - if (!Context.Guild.CurrentMember.HierarchyCheck(user)) - { - await Context.ReplyAndDeleteAsync( - null, - false, - new LocalEmbedBuilder() - .Create("Cannot ban someone that's higher than me in hierarchy.", - Color.Red), TimeSpan.FromSeconds(20)); - return; - } - - if (!Context.Member.HierarchyCheck(user)) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create( - $"{Context.User.Mention}, can't ban someone that's equal or more power than you.", - Color.Red), TimeSpan.FromSeconds(20)); - return; - } - var bans = _cache.BanCache.GetOrAdd(Context.Guild.Id, new MemoryCache(new MemoryCacheOptions())); - bans.Set(user.Id.RawValue, Context.User.Id, TimeSpan.FromMinutes(1)); - _cache.BanCache.AddOrUpdate(Context.Guild.Id, bans, (_, _) => bans); - await Context.Guild.BanMemberAsync(user.Id.RawValue, $"{Context.User.Id.RawValue} - {reason}", 7); - await Context.ReplyAndDeleteAsync(null, false, new LocalEmbedBuilder().Create( - $"Banned {user.Mention} from {Context.Guild.Name}.", - Color.Green), TimeSpan.FromSeconds(20)); - } - - [Name("Ban")] - [Command("ban")] - [Description("Bans a user by their ID, doesn't require to be in the server")] - [RequireBotGuildPermissions(Permission.BanMembers, Permission.ManageMessages)] - [RequireMemberGuildPermissions(Permission.BanMembers)] - public async Task BanAsync(ulong userId, [Remainder] string reason = "No reason applied") - { - await Context.Message.TryDeleteMessageAsync(); - var user = await Context.Guild.GetOrFetchMemberAsync(userId); - if (user == null) - { - try - { - var bans = _cache.BanCache.GetOrAdd(Context.Guild.Id, new MemoryCache(new MemoryCacheOptions())); - bans.Set(userId, Context.User.Id, TimeSpan.FromMinutes(1)); - _cache.BanCache.AddOrUpdate(Context.Guild.Id, bans, (_, _) => bans); - await Context.Guild.BanMemberAsync(userId, reason, 7); - await Context.ReplyAndDeleteAsync(null, false, new LocalEmbedBuilder().Create( - $"Banned **{userId}** from {Context.Guild.Name}.", - Color.Green), TimeSpan.FromSeconds(20)); - } - catch - { - await Context.ReplyAndDeleteAsync(null, false, new LocalEmbedBuilder().Create( - "Couldn't fetch a user by that ID.", - Color.Green), TimeSpan.FromSeconds(20)); - } - } - else await BanAsync(user as CachedMember, reason); - } - - [Name("Kick")] - [Command("kick")] - [Description("Kicks a user")] - [RequireBotGuildPermissions(Permission.KickMembers, Permission.ManageMessages)] - [RequireMemberGuildPermissions(Permission.KickMembers)] - public async Task KickAsync(CachedMember user, [Remainder] string reason = "No reason applied") - { - if (user == Context.User) return; - await Context.Message.TryDeleteMessageAsync(); - if (!Context.Guild.CurrentMember.HierarchyCheck(user)) - { - await Context.ReplyAndDeleteAsync( - null, - false, - new LocalEmbedBuilder() - .Create("Cannot kick someone that's higher than me in hierarchy.", - Color.Red), TimeSpan.FromSeconds(20)); - return; - } - - if (!Context.Member.HierarchyCheck(user)) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create( - $"{Context.User.Mention}, can't kick someone that's equal or more power than you.", - Color.Red), TimeSpan.FromSeconds(20)); - return; - } - - await user.KickAsync(RestRequestOptions.FromReason($"{Context.User} ({Context.User.Id}) reason: {reason}")); - await Context.ReplyAndDeleteAsync(null, false, new LocalEmbedBuilder().Create( - - $"Kicked {user.Mention} from {Context.Guild.Name}.", - Color.Green), TimeSpan.FromSeconds(20)); - } - - [Name("Prune")] - [Command("prune")] - [Description("Prunes X messages, user specific is optional")] - [RequireBotGuildPermissions(Permission.ManageMessages)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task PruneAsync(int amount = 5, CachedMember user = null) - { - if (amount <= 0) return; - await Context.Message.TryDeleteMessageAsync(); - var messages = await Context.Channel.FilterMessagesAsync(amount, user); - try - { - if (await Context.Channel.TryDeleteMessagesAsync(messages)) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Deleted {amount} messages", Color.Green), - TimeSpan.FromSeconds(20)); - } - else - { - await Context.ReplyAndDeleteAsync(null, false, new LocalEmbedBuilder().Create($"Couldn't delete {amount} messages, missing permission?", - Color.Red), TimeSpan.FromSeconds(20)); - } - } - catch - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder() - .Create("Couldn't delete messages, missing permissions?", Color.Red), - TimeSpan.FromSeconds(20)); - } - } - - [Name("Soft Ban")] - [Command("softban", "sb")] - [Description("In the last 50 messages, deletes the messages user has sent and mutes")] - [RequireBotGuildPermissions(Permission.ManageMessages, Permission.ManageRoles, Permission.MuteMembers)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task SoftBanAsync(CachedMember user) - { - if (Context.Member == user) return; - await Context.Message.TryDeleteMessageAsync(); - - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - if (!await _mute.Mute(user, db)) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create("Couldn't mute user.", Color.Red), - TimeSpan.FromSeconds(20)); - } - - var messages = await Context.Channel.FilterMessagesAsync(50, user); - await Context.Channel.TryDeleteMessagesAsync(messages); - } - - [Name("Mute")] - [Command("mute")] - [Description("Mutes a user for a duration, specified 1h13m4s or 2342 in minutes with a optional reason")] - [RequireBotGuildPermissions(Permission.ManageMessages, Permission.ManageRoles, Permission.MuteMembers)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task MuteAsync(CachedMember user, TimeSpan? duration = null, - [Remainder] string reason = "No reason") - { - if (user == Context.User) return; - await Context.Message.TryDeleteMessageAsync(); - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - duration ??= await _mute.GetMuteTime(user, db); - - var muteRes = await _mute.TimedMute(user, Context.Member, duration.Value, db, reason); - if (muteRes) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Muted {user.Mention} for {duration.Value.Humanize(2)}", - Color.Green), TimeSpan.FromSeconds(20)); - } - else - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder() - .Create($"Couldn't mute {user.Mention}, missing permission or role not accessible ?", - Color.Red), - TimeSpan.FromSeconds(20)); - } - } - - [Name("UnMute")] - [Command("unmute")] - [Description("UnMutes a user")] - [RequireBotGuildPermissions(Permission.ManageRoles, Permission.MuteMembers)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task UnMuteAsync(CachedMember user, [Remainder] string reason = "No reason applied") - { - if (user == Context.User) return; - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - if (await _mute.UnMuteUser(user, db)) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Unmuted {user.Mention}", Color.Green), - TimeSpan.FromSeconds(20)); - } - else - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder() - .Create( - $"Couldn't unmute {user.Mention}, missing permissions or role not accessible ?", - Color.Red), - TimeSpan.FromSeconds(20)); - } - } - - [Name("Warn")] - [Command("warn", "warning")] - [Description("Warns a user, bot dms them the warning. Warning accessible through warnlog")] - [RequireBotGuildPermissions(Permission.BanMembers, Permission.KickMembers, Permission.ManageMessages, Permission.ManageRoles, Permission.MuteMembers)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task WarnAsync(CachedMember user, [Remainder] string reason = "No reason") - { - if (user == Context.User) return; - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - await _warn.AddWarn(db, user, Context.Member, reason, WarnReason.Warned, true); - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Warned {user.Mention}", Color.Green), - TimeSpan.FromSeconds(20)); - } - - [Name("Warn Log")] - [Command("warnlog")] - [Description("Pulls up warnlog and admin profile of a user.")] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task WarnLogAsync(CachedMember user, WarnLogType type = WarnLogType.Simple) - { - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - if (type == WarnLogType.Simple) - { - await Context.ReplyAsync(await _warn.GetSimpleWarnlogAsync(user, db)); - } - else - { - var pages = await WarnService.GetFullWarnlogAsync(user, db); - await Context.PaginatedReply(pages, user, $"Warn log for {user}"); - } - } - - [Name("Reason")] - [Command("reason")] - [Description("Inputs reason for moderation log entry")] - [RequireBotGuildPermissions(Permission.ManageMessages)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task ReasonAsync(int id, [Remainder] string reason = "No reason applied") - { - if (id <= 0) return; - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - await ApplyReason(db, id, reason); - - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Updated mod log for {id}", Color.Green), - TimeSpan.FromSeconds(10)); - } - - [Name("Reason")] - [Command("reason")] - [Priority(1)] - [Description("Adds reason to multiple moderation log entries")] - [RequireBotGuildPermissions(Permission.ManageMessages)] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task ReasonAsync(Range range, [Remainder] string reason = "No reason applied") - { - if (range.MinValue <= 0) return; - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - for (var i = range.MinValue; i < range.MaxValue; i++) - { - await ApplyReason(db, i, reason); - await Task.Delay(TimeSpan.FromMilliseconds(200)); - } - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Updated mod logs for entries between {range}", Color.Green), - TimeSpan.FromSeconds(10)); - } - - private async Task ApplyReason(DbService db, int id, string reason) - { - var modCase = await db.ModLogs.FindAsync(id, Context.Guild.Id.RawValue); - await UpdateMessage(modCase, db, reason); - - modCase.Response = reason != null ? $"{reason}" : "No Reason Provided"; - modCase.ModId = Context.User.Id.RawValue; - await db.SaveChangesAsync(); - } - - private async Task UpdateMessage(ModLog modCase, DbService db, string reason) - { - var updMsg = await Context.Channel.GetMessageAsync(modCase.MessageId) as IUserMessage; - if (updMsg == null) - { - await Context.ReplyAndDeleteAsync("Couldn't find the message, retrying in 5 seconds...", - timeout: TimeSpan.FromSeconds(10)); - var delay = Task.Delay(5000); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild).ConfigureAwait(false); - await Task.WhenAll(delay); - if (cfg.LogBan.HasValue) - { - updMsg = await Context.Guild.GetTextChannel(cfg.LogBan.Value) - .GetMessageAsync(modCase.MessageId) as IUserMessage; - } - } - - if (updMsg == null) - { - await Context.ReplyAndDeleteAsync("Couldn't find the message. aborting...", timeout: TimeSpan.FromSeconds(10)); - return; - } - - var embed = updMsg.Embeds.FirstOrDefault().ToEmbedBuilder(); - if (embed == null) - { - await Context.ReplyAndDeleteAsync("Couldn't find a embed to update...", timeout: TimeSpan.FromSeconds(20)); - return; - } - - var modField = embed.Fields.FirstOrDefault(x => x.Name == "Moderator"); - var reasonField = embed.Fields.FirstOrDefault(x => x.Name == "Reason"); - - if (modField != null) modField.Value = Context.User.Mention; - if (reasonField != null) reasonField.Value = reason != null ? $"{reason}" : "No Reason Provided"; - - await updMsg.ModifyAsync(m => m.Embed = embed.Build()); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Administration/SelfAssignAbleRoles.cs b/Hanekawa/Bot/Modules/Administration/SelfAssignAbleRoles.cs deleted file mode 100644 index d536e92f..00000000 --- a/Hanekawa/Bot/Modules/Administration/SelfAssignAbleRoles.cs +++ /dev/null @@ -1,266 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Utility; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Administration -{ - [Name("Self Assignable Roles")] - [RequiredChannel] - [RequireBotChannelPermissions(Permission.SendMessages, Permission.EmbedLinks, Permission.ManageMessages)] - public class SelfAssignAbleRoles : HanekawaCommandModule - { - private readonly SelfAssignService _assignService; - public SelfAssignAbleRoles(SelfAssignService assignService) => _assignService = assignService; - - [Name("I am")] - [Command("iam", "give")] - [Description("Assigns a role that's setup as self-assignable")] - [RequiredChannel] - public async Task AssignSelfRoleAsync([Remainder] CachedRole role) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - await Context.Message.TryDeleteMessageAsync(); - var dbRole = await db.SelfAssignAbleRoles.FindAsync(role.Guild.Id.RawValue, role.Id.RawValue); - if (dbRole == null) - { - await Context.ReplyAndDeleteAsync("Couldn't find a self-assignable role with that name", - timeout: TimeSpan.FromSeconds(15)); - return; - } - - bool addedRole; - var gUser = Context.Member; - if (dbRole.Exclusive) - { - var roles = await db.SelfAssignAbleRoles.Where(x => x.GuildId == Context.Guild.Id.RawValue && x.Exclusive) - .ToListAsync(); - foreach (var x in roles) - { - var exclusiveRole = Context.Guild.GetRole(x.RoleId); - if(exclusiveRole == null) continue; - if (gUser.Roles.Values.Contains(exclusiveRole)) await gUser.TryRemoveRoleAsync(exclusiveRole); - } - - addedRole = await gUser.TryAddRoleAsync(role); - } - else - { - addedRole = await gUser.TryAddRoleAsync(role); - } - - if (addedRole) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create($"Added {role.Name} to {Context.User.Mention}", - Color.Green),TimeSpan.FromSeconds(10)); - } - else - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create( - $"Couldn't add {role.Name} to {Context.User.Mention}, missing permission or role position?", - Color.Red),TimeSpan.FromSeconds(10)); - } - } - - [Name("I am not")] - [Command("iamnot", "iamn")] - [Description("Removes a role that's setup as self-assignable")] - [RequiredChannel] - public async Task RemoveSelfRoleAsync([Remainder] CachedRole role) - { - if (Context.Member.Roles.Values.FirstOrDefault(x => x.Id.RawValue == role.Id.RawValue) == null) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - await Context.Message.TryDeleteMessageAsync(); - var dbRole = await db.SelfAssignAbleRoles.FindAsync(role.Guild.Id.RawValue, role.Id.RawValue); - if (dbRole == null) - { - await Context.ReplyAndDeleteAsync("Couldn't find a self-assignable role with that name", - timeout: TimeSpan.FromSeconds(15)); - return; - } - - if (await Context.Member.TryRemoveRoleAsync(role)) - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder() - .Create($"Removed {role.Name} from {Context.User.Mention}", Color.Green), TimeSpan.FromSeconds(10)); - } - else - { - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder() - .Create( - $"Couldn't remove {role.Name} from {Context.User.Mention}, missing permission or role position?", - Color.Red), TimeSpan.FromSeconds(10)); - } - } - - [Name("Role list")] - [Command("rolelist", "rl")] - [Description("Displays list of self-assignable roles")] - [RequiredChannel] - public async Task ListSelfAssignAbleRolesAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var list = await db.SelfAssignAbleRoles.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - if (list == null || list.Count == 0) - { - await Context.ReplyAsync("No self-assignable roles added"); - return; - } - - var result = new List(); - foreach (var x in list) - { - var role = Context.Guild.GetRole(x.RoleId) ?? - Context.Guild.Roles.Values.FirstOrDefault(z => z.Id.RawValue == x.RoleId); - if (role != null) result.Add(x.Exclusive ? $"**{role.Name}** (exclusive)" : $"**{role.Name}**"); - } - - await Context.PaginatedReply(result, Context.Guild, - $"Self-assignable roles for {Context.Guild.Name}"); - } - - [Name("Post Reaction Message")] - [Command("postrolemsg", "prm")] - [Description( - "Posts a message with all self-assignable roles and their respectable reaction emote, adds reactions to message")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task PostMessageAsync(CachedTextChannel channel = null) - { - channel ??= Context.Channel; - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var messages = await _assignService.PostAsync(Context, channel, db); - var cfg = await db.GetOrCreateChannelConfigAsync(Context.Guild); - cfg.SelfAssignableChannel = channel.Id.RawValue; - cfg.SelfAssignableMessages = messages.ToArray(); - await db.SaveChangesAsync(); - await ReplyAsync($"Sent Self-Assignable React Roles to {channel.Mention}!", Color.Green); - } - - [Name("Exclusive role add")] - [Command("era")] - [Description("Adds a role to the list of self-assignable roles")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ExclusiveRole([Remainder] CachedRole role) => - await AddSelfAssignAbleRoleAsync(Context, role, true); - - [Name("Exclusive role add")] - [Command("era")] - [Description("Adds a role to the list of self-assignable roles")] - [Priority(1)] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ExclusiveRole(CachedRole role, LocalCustomEmoji emote) => - await AddSelfAssignAbleRoleAsync(Context, role, true, emote); - - [Name("Role add")] - [Command("roleadd", "ra")] - [Description("Adds a role to the list of self-assignable roles")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task NonExclusiveRole([Remainder] CachedRole role) => - await AddSelfAssignAbleRoleAsync(Context, role, false); - - [Name("Role add")] - [Command("roleadd", "ra")] - [Priority(1)] - [Description("Adds a role to the list of self-assignable roles")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task NonExclusiveRole(CachedRole role, LocalCustomEmoji emote) => - await AddSelfAssignAbleRoleAsync(Context, role, false, emote); - - [Name("Role remove")] - [Command("roleremove", "rr")] - [Description("Removes a role from the list of self-assignable roles")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveSelfAssignAbleRoleAsync([Remainder] CachedRole role) - { - if (!Context.Member.HierarchyCheck(role)) - { - await Context.ReplyAsync("Can't remove a role that's higher then your highest role.", - Color.Red); - return; - } - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var roleCheck = - await db.SelfAssignAbleRoles.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.RoleId == role.Id.RawValue); - if (roleCheck == null) - { - await Context.ReplyAsync($"There is no self-assignable role by the name {role.Name}", - Color.Red); - return; - } - - db.SelfAssignAbleRoles.Remove(roleCheck); - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Removed {role.Name} as a self-assignable role!", Color.Green); - } - - private async Task AddSelfAssignAbleRoleAsync(DiscordCommandContext context, CachedRole role, bool exclusive, LocalCustomEmoji emote = null) - { - if (!context.Member.HierarchyCheck(role)) - { - await Context.ReplyAsync("Can't add a role that's higher then your highest role.", Color.Red); - return; - } - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var roleCheck = await db.SelfAssignAbleRoles.FindAsync(context.Guild.Id.RawValue, role.Id.RawValue); - if (roleCheck != null) - { - if (exclusive && !roleCheck.Exclusive) - { - roleCheck.Exclusive = true; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Changed {role.Name} to a exclusive self-assignable role!", - Color.Green); - } - else if (!exclusive && roleCheck.Exclusive) - { - roleCheck.Exclusive = false; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Changed {role.Name} to a non-exclusive self-assignable role!", - Color.Green); - } - else - { - await Context.ReplyAsync($"{role.Name} is already added as self-assignable", - Color.Red); - } - return; - } - - var data = new SelfAssignAbleRole - { - GuildId = context.Guild.Id.RawValue, - RoleId = role.Id.RawValue, - Exclusive = exclusive, - EmoteMessageFormat = emote?.MessageFormat, - EmoteReactFormat = emote?.ReactionFormat - }; - await db.SelfAssignAbleRoles.AddAsync(data); - await db.SaveChangesAsync(); - if(emote != null) await Context.ReplyAsync($"Added {role.Name} as a self-assignable role with emote {emote}!", Color.Green); - else await Context.ReplyAsync($"Added {role.Name} as a self-assignable role!", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Advertise/Advertise.cs b/Hanekawa/Bot/Modules/Advertise/Advertise.cs deleted file mode 100644 index c9d77f1d..00000000 --- a/Hanekawa/Bot/Modules/Advertise/Advertise.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Advertise; -using Hanekawa.Shared.Command; -using Hanekawa.Utility; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Advertise -{ - [Name("Advertise")] - [Description("Commands to setup rewards for voting on the server on sites such as top.gg")] - [RequireUser(111123736660324352)] - public class Advertise : HanekawaCommandModule - { - [Name("Create TopGG Webhook")] - [Description("Creates a config and key in-order to take in topgg requests to reward users for voting")] - [Command("ctopwebhook")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task CreateTopGGWebhook() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var check = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - var channel = Context.Member.DmChannel ?? (IDmChannel)await Context.Member.CreateDmChannelAsync(); - if (check != null) - { - await ReplyAsync("You've already made a config!, sending new key in dms"); - try - { - await channel.SendMessageAsync("Your top.gg Webhook URL is: https://hanekawa.bot/api/advert/dbl \n" + - $"Auth Key: {check.AuthKey}"); - } - catch - { - await ReplyAsync("Could not DM, sending here. Please delete this message afterwards.\n" + - "Webhook URL: https://hanekawa.bot/api/advert/dbl \n" + - $"Auth Key: {check.AuthKey}", Color.Green); - } - return; - } - - await db.DblAuths.AddAsync(new DblAuth - { - GuildId = Context.Guild.Id.RawValue, - ExpGain = 0, - CreditGain = 0, - SpecialCredit = 0, - RoleIdReward = null, - Message = null, - AuthKey = Guid.NewGuid() - }); - await db.SaveChangesAsync(); - var cfg = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - await ReplyAsync("Authentication Created! DMing the credentials."); - try - { - await channel.SendMessageAsync("Your top.gg Webhook URL is: https://hanekawa.bot/api/advert/dbl\n" + - $"Auth Key: {cfg.AuthKey}"); - } - catch - { - await ReplyAsync("Could not DM, sending here. Please delete this message afterwards.\n" + - "Webhook URL: https://hanekawa.bot/api/advert/dbl \n" + - $"Auth Key: {cfg.AuthKey}", Color.Green); - } - } - - [Name("Set Vote Exp Reward")] - [Description("Sets exp reward for voting on the server on top.gg")] - [Command("advertexp")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task AddExpReward(int exp = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - if (cfg == null) - { - await ReplyAsync("Please create a webhook & config first before using these commands!", Color.Red); - return; - } - cfg.ExpGain = exp; - await db.SaveChangesAsync(); - if (exp == 0) - { - await ReplyAsync("Disabled exp reward for Top.gg votes"); - } - else - { - await ReplyAsync($"Set Top.gg exp vote rewards to {exp}"); - } - } - - [Name("Set Vote Credit Reward")] - [Description("Sets credit reward for voting on the server on top.gg")] - [Command("advertcredit")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task AddCreditReward(int credit = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - if (cfg == null) - { - await ReplyAsync("Please create a webhook & config first before using these commands!", Color.Red); - return; - } - cfg.CreditGain = credit; - await db.SaveChangesAsync(); - if (credit == 0) - { - await ReplyAsync("Disabled credit reward for Top.gg votes"); - } - else - { - await ReplyAsync($"Set Top.gg credit vote rewards to {credit}"); - } - } - - [Name("Set Vote Special Credit Reward")] - [Description("Sets special credit reward for voting on the server on top.gg")] - [Command("advertscredit")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task AddSpecialReward(int specialCredit = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - if (cfg == null) - { - await ReplyAsync("Please create a webhook & config first before using these commands!", Color.Red); - return; - } - cfg.SpecialCredit = specialCredit; - await db.SaveChangesAsync(); - if (specialCredit == 0) - { - await ReplyAsync("Disabled special credit reward for Top.gg votes"); - } - else - { - await ReplyAsync($"Set Top.gg special credit vote rewards to {specialCredit}"); - } - } - - [Name("Set Vote Role Reward")] - [Description("Sets role reward for voting on the server on top.gg")] - [Command("advertrole")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task AddRoleReward(CachedRole role = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - if (cfg == null) - { - await ReplyAsync("Please create a webhook & config first before using these commands!", Color.Red); - return; - } - cfg.RoleIdReward = role?.Id.RawValue; - await db.SaveChangesAsync(); - if (role == null) - { - await ReplyAsync("Disabled role reward for Top.gg vote"); - } - else - { - await ReplyAsync($"Set Top.gg role rewards to {role.Name}"); - } - } - - [Name("Set Vote Notification")] - [Description("Sets message to be sent in dms for voting on the server on top.gg")] - [Command("advertmessage", "advertmsg")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task AddMessage(string message = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.DblAuths.FindAsync(Context.Guild.Id.RawValue); - if (cfg == null) - { - await ReplyAsync("Please create a webhook & config first before using these commands!", Color.Red); - return; - } - cfg.Message = message; - await db.SaveChangesAsync(); - if (message == null) - { - await ReplyAsync("Disabled dm notification when user has voted"); - } - else - { - await ReplyAsync("Set DM notification message to:\n" + - $"{MessageUtil.FormatMessage(message, Context.Member, Context.Guild)}"); - } - } - } -} diff --git a/Hanekawa/Bot/Modules/Board/Board.cs b/Hanekawa/Bot/Modules/Board/Board.cs deleted file mode 100644 index e5e45560..00000000 --- a/Hanekawa/Bot/Modules/Board/Board.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services; -using Hanekawa.Bot.Services.Board; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Board -{ - [Name("Board")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public partial class Board : HanekawaCommandModule - { - [Name("Board Stats")] - [Command("boardstats")] - [Description("Overview of board stats of this server")] - [RequiredChannel] - public async Task BoardStatsAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoardConfigAsync(Context.Guild); - LocalCustomEmoji.TryParse(cfg.Emote, out var emote); - var boards = await db.Boards.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - var topStars = boards.OrderByDescending(x => x.StarAmount).Take(3).ToList(); - var topReceive = await db.Accounts.Where(x => x.GuildId == Context.Guild.Id.RawValue) - .OrderByDescending(x => x.StarReceived).Take(3).ToListAsync(); - var totalStars = 0; - for (var i = 0; i < boards.Count; i++) totalStars += boards[i].StarAmount; - - string topReceived = null; - for (var i = 0; i < topReceive.Count; i++) - { - var index = topReceive[i]; - var user = await Context.Guild.GetOrFetchMemberAsync(index.UserId); - topReceived += $"{i}: {user.Mention ?? "User left the server"} ({index.StarReceived} {emote})\n"; - } - - string topStarMessages = null; - for (var i = 0; i < topStars.Count; i++) - { - var index = topStars[i]; - topStarMessages += $"{i}: {index.MessageId} ({index.StarAmount} {emote})\n"; - } - - var embed = new LocalEmbedBuilder() - { - Description = $"{boards.Count} messages boarded with a total of {totalStars} {emote} given", - Fields = - { - new LocalEmbedFieldBuilder { Name = $"Top {emote} Posts", Value = $"{topStarMessages ?? "N/A"}" }, - new LocalEmbedFieldBuilder { Name = $"Top {emote} Receivers", Value = $"{topReceived ?? "N/A"}" } - } - }; - await Context.ReplyAsync(embed); - } - - [Name("Board Stats")] - [Command("boardstats")] - [Description("Shows board stats for a user")] - [RequiredChannel] - public async Task BoardStatsAsync(CachedMember user) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoardConfigAsync(Context.Guild); - LocalCustomEmoji.TryParse(cfg.Emote, out var emote); - var userData = await db.GetOrCreateUserData(user); - var boardData = await db.Boards.Where(x => x.GuildId == Context.Guild.Id.RawValue && x.UserId == user.Id.RawValue) - .OrderByDescending(x => x.StarAmount).ToListAsync(); - string topStar = null; - if (boardData.Count != 0) - { - if (boardData.Count > 3) boardData = boardData.Take(3).ToList(); - for (var i = 0; i < boardData.Count; i++) - { - var index = boardData[i]; - topStar += $"{i} > {index.MessageId} ({emote} received {index.StarAmount})\n"; - } - } - else - { - topStar += $"No {emote} messages"; - } - - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder {IconUrl = user.GetAvatarUrl(), Name = user.DisplayName}, - Fields = - { - new LocalEmbedFieldBuilder{ Name = "Boarded Messages", Value = $"{boardData.Count}", IsInline = true }, - new LocalEmbedFieldBuilder{ Name = $"{emote} Received", Value = $"{userData.StarReceived}", IsInline = true }, - new LocalEmbedFieldBuilder{ Name = $"{emote} Given", Value = $"{userData.StarGiven}", IsInline = true }, - new LocalEmbedFieldBuilder{ Name = $"Top {emote} Posts", Value = $"{topStar ?? "N/A"}" } - } - }; - await Context.ReplyAsync(embed); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Board/BoardAdmin.cs b/Hanekawa/Bot/Modules/Board/BoardAdmin.cs deleted file mode 100644 index 154169fb..00000000 --- a/Hanekawa/Bot/Modules/Board/BoardAdmin.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Board -{ - public partial class Board - { - [Name("Board Emote")] - [Command("boardemote")] - [Description("Sets a emote to be used for the board")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task BoardEmoteAsync(LocalCustomEmoji emote) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoardConfigAsync(Context.Guild); - cfg.Emote = emote.MessageFormat; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Changed board emote to {emote}", Color.Green); - } - - [Name("Board Channel")] - [Command("boardchannel")] - [Description("Sets which channel starred messages go")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task BoardChannelAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoardConfigAsync(Context.Guild); - if (channel == null) - { - cfg.Channel = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled starboard", Color.Green); - } - else - { - cfg.Channel = channel.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set board channel to {channel.Mention}", Color.Green); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Club/Club.cs b/Hanekawa/Bot/Modules/Club/Club.cs deleted file mode 100644 index 9b8f4623..00000000 --- a/Hanekawa/Bot/Modules/Club/Club.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Club; -using Hanekawa.Database; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Club -{ - [Name("Club")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public partial class Club : HanekawaCommandModule - { - private readonly ClubService _club; - - public Club(ClubService club) => _club = club; - - [Name("Club List")] - [Command("clublist", "clubs")] - [Description("Paginates all clubs")] - [RequiredChannel] - public async Task ClubListAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var clubs = await db.ClubInfos.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - if (clubs.Count == 0) - { - await Context.ReplyAsync("No clubs on this server"); - return; - } - - var pages = new List(); - for (var i = 0; i < clubs.Count; i++) - { - var x = clubs[i]; - if (x.LeaderId == 1) continue; - var memberCount = - await db.ClubPlayers.CountAsync(y => y.GuildId == Context.Guild.Id.RawValue && y.ClubId == x.Id); - if (memberCount == 0) continue; - var leader = (await Context.Guild.GetOrFetchMemberAsync(x.LeaderId)).Mention ?? - "Couldn't find user or left server."; - pages.Add($"**{x.Name} (id: {x.Id})**\n" + - $"Members: {memberCount}\n" + - $"Leader {leader}"); - } - - if (pages.Count == 0) - { - await Context.ReplyAsync( - "There seems to be a problem with all clubs on this server. Either disbanded or internal problem."); - } - else - { - await Context.PaginatedReply(pages, Context.Guild, $"Clubs in {Context.Guild.Name}"); - } - } - - [Name("Club Check")] - [Command("club", "clubcheck", "cc")] - [Description("Checks specific club information")] - [RequiredChannel] - public async Task ClubCheckAsync(int id) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => x.Id == id && x.GuildId == Context.Guild.Id.RawValue); - if (club == null) - { - await Context.ReplyAsync("Couldn't find a club with that ID.", Color.Red); - return; - } - - var clubUsers = - await db.ClubPlayers.Where(x => x.GuildId == Context.Guild.Id.RawValue && x.ClubId == club.Id).ToListAsync(); - var officers = new StringBuilder(); - foreach (var x in clubUsers.Where(x => x.Rank == 2)) - officers.AppendLine($"{(await Context.Guild.GetOrFetchMemberAsync(x.UserId)).Mention}\n"); - - if (officers.Length == 0) officers.AppendLine("No officers"); - - var embed = new LocalEmbedBuilder - { - ThumbnailUrl = club.ImageUrl, - Timestamp = club.CreationDate, - Author = new LocalEmbedAuthorBuilder {IconUrl = club.IconUrl, Name = $"{club.Name} (ID:{club.Id})"}, - Footer = new LocalEmbedFooterBuilder {Text = "Created:"}, - Fields = - { - new LocalEmbedFieldBuilder - { - IsInline = false, Name = "Leader", - Value = - $"{(await Context.Guild.GetOrFetchMemberAsync(club.LeaderId)).Mention ?? "Couldn't find user or left server."}" - }, - new LocalEmbedFieldBuilder - {IsInline = false, Name = "Officers", Value = officers.ToString().Truncate(999)} - } - }.Create(club.Description, Context.Colour.Get(Context.Guild.Id.RawValue)); - await Context.ReplyAsync(embed); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Club/ClubAdmin.cs b/Hanekawa/Bot/Modules/Club/ClubAdmin.cs deleted file mode 100644 index 2ac305fe..00000000 --- a/Hanekawa/Bot/Modules/Club/ClubAdmin.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Services.Club; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Club -{ - public partial class Club - { - [Name("Rename Club")] - [Command("csn")] - [Description("Force changes a name of a club")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubForceRename(int clubId, [Remainder] string name) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => x.Id == clubId && x.GuildId == Context.Guild.Id.RawValue); - if (club == null) - { - await Context.ReplyAsync("There's no club with that ID in this guild"); - return; - } - - if (name.IsNullOrWhiteSpace()) - { - await Context.ReplyAsync("Please provide a proper name"); - return; - } - - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - club.Name = name; - await db.SaveChangesAsync(); - if (club.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await Context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(club.AdMessage.Value) as IUserMessage; - await ClubService.UpdatePostNameAsync(msg, name); - } - - if (club.Role.HasValue) - { - var role = Context.Guild.GetRole(club.Role.Value); - await role.ModifyAsync(x => x.Name = name); - } - - if (club.Channel.HasValue) - { - var channel = Context.Guild.GetTextChannel(club.Channel.Value); - await channel.ModifyAsync(x => x.Name = name); - } - } - - [Name("Change Club Icon")] - [Command("csicon")] - [Description("Force changes icon of a club")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubForceReIcon(int clubId, [Remainder] string icon) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => x.Id == clubId && x.GuildId == Context.Guild.Id.RawValue); - if (club == null) - { - await Context.ReplyAsync("There's no club with that ID in this guild"); - return; - } - - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - club.IconUrl = icon; - await db.SaveChangesAsync(); - if (club.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await Context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(club.AdMessage.Value) as IUserMessage; - await ClubService.UpdatePostIconAsync(msg, icon); - } - } - - [Name("Change Club Image")] - [Command("csi", "csimage")] - [Description("Force changes image of a club")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubForceReImage(int clubId, [Remainder] string image) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => x.Id == clubId && x.GuildId == Context.Guild.Id.RawValue); - if (club == null) - { - await Context.ReplyAsync("There's no club with that ID in this guild"); - return; - } - - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - club.ImageUrl = image; - await db.SaveChangesAsync(); - if (club.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await Context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(club.AdMessage.Value) as IUserMessage; - await ClubService.UpdatePostImageAsync(msg, image); - } - } - - [Name("Change Club Description")] - [Command("csd")] - [Description("Force changes a name of a club")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubForceReDescription(int clubId, [Remainder] string desc) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => x.Id == clubId && x.GuildId == Context.Guild.Id.RawValue); - if (club == null) - { - await Context.ReplyAsync("There's no club with that ID in this guild"); - return; - } - - if (desc.IsNullOrWhiteSpace()) desc = "N/A"; - - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - club.Description = desc; - await db.SaveChangesAsync(); - if (club.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await Context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(club.AdMessage.Value) as IUserMessage; - await ClubService.UpdatePostDescriptionAsync(msg, desc); - } - } - - [Name("Club Role Toggle")] - [Command("crt")] - [Description( - "Toggles the use of creating roles for club or channel permission. Auto to channel when above 50 roles")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ToggleClubRole() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - if (cfg.RoleEnabled) - { - cfg.RoleEnabled = false; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled creation of roles for clubs.\n" + - "Now using channel permissions to add users to their designated channel"); - } - else - { - cfg.RoleEnabled = true; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Enabled creation of roles for clubs.\n" + - "Now using their designated role to add users to their channel"); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Club/ClubAdvertise.cs b/Hanekawa/Bot/Modules/Club/ClubAdvertise.cs deleted file mode 100644 index a07e657f..00000000 --- a/Hanekawa/Bot/Modules/Club/ClubAdvertise.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Threading.Tasks; -using Hanekawa.Bot.Preconditions; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Club -{ - public partial class Club - { - [Name("Club Name")] - [Command("clubname", "cn")] - [Description("Changes club name")] - [RequiredChannel] - public async Task ClubNameChangeAsync([Remainder] string content) => - await _club.AdNameAsync(Context, content); - - [Name("Club Description")] - [Command("clubdesc", "cd")] - [Description("Sets description of a club")] - [RequiredChannel] - public async Task ClubDescriptionAsync([Remainder] string content) => - await _club.AdDescAsync(Context, content); - - [Name("Club Image")] - [Command("clubimage", "clubpic", "cimage", "ci")] - [Description("Sets a picture to a club")] - [RequiredChannel] - public async Task ClubImageAsync(string image) => await _club.AdImageAsync(Context, image); - - [Name("Club Icon")] - [Command("clubicon", "cicon")] - [Description("Sets a icon to a club")] - [RequiredChannel] - public async Task ClubIconAsync(string image) => await _club.AdIconAsync(Context, image); - - [Name("Club Public")] - [Command("clubpublic", "cpublic")] - [Description("Toggles a club to be public or not")] - [RequiredChannel] - public async Task ClubPublicAsync() => await _club.AdPublicAsync(Context); - - [Name("Club Advertise")] - [Command("clubadvertise", "clubpost", "cpost")] - [Description("Posts a advertisement of club to designated advertisement channel")] - [RequiredChannel] - public async Task ClubAdvertiseAsync() => await _club.AdAdvertiseAsync(Context); - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Club/ClubManagement.cs b/Hanekawa/Bot/Modules/Club/ClubManagement.cs deleted file mode 100644 index f5c5682d..00000000 --- a/Hanekawa/Bot/Modules/Club/ClubManagement.cs +++ /dev/null @@ -1,363 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Club; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Club; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Club -{ - public partial class Club - { - [Name("Create")] - [Command("clubcreate", "ccreate")] - [Description("Creates a club")] - [RequiredChannel] - public async Task CreateClub([Remainder] string name) - { - if (name.IsNullOrWhiteSpace()) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(Context.Member); - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - if (userData.Level < cfg.ChannelRequiredLevel) - { - await Context.ReplyAsync( - $"You do not meet the requirement to make a club (Level {cfg.ChannelRequiredLevel}).", - Color.Red); - return; - } - - var leaderCheck = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.LeaderId == Context.User.Id.RawValue); - if (leaderCheck != null) - { - await Context.ReplyAsync("You're already a leader of a club, you can't create multiple clubs.", - Color.Red); - return; - } - - var club = await db.CreateClub(Context.User, Context.Guild, name, DateTimeOffset.UtcNow); - var data = new ClubUser - { - ClubId = club.Id, - GuildId = Context.Guild.Id.RawValue, - JoinDate = DateTimeOffset.UtcNow, - Rank = 1, - UserId = Context.User.Id.RawValue - }; - await db.ClubPlayers.AddAsync(data); - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Successfully created club {name} !", Color.Green); - } - - [Name("Club Add")] - [Command("clubadd", "cadd")] - [Description("Adds a member to your club")] - [RequiredChannel] - public async Task AddClubMemberAsync(CachedMember user) - { - if (user == Context.User) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var clubUser = - await db.ClubPlayers.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue && x.Rank <= 2); - if (clubUser == null) return; - if (clubUser.Rank > 2) - { - await Context.ReplyAsync("You're not high enough rank to use that command!", Color.Red); - return; - } - - var check = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.UserId == user.Id.RawValue && x.GuildId == user.Guild.Id.RawValue && x.ClubId == clubUser.Id); - if (check != null) - { - await Context.ReplyAsync($"{user.Mention} is already a member of your club."); - return; - } - - var clubData = await db.GetClubAsync(Context.Member, clubUser.ClubId); - await Context.ReplyAsync( - $"{user.Mention}, {Context.User.Mention} has invited you to {clubData.Name}, do you accept? (y/n)"); - var status = true; - while (status) - try - { - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Author.Id.RawValue == user.Id.RawValue && x.Message.Guild.Id.RawValue == user.Guild.Id.RawValue, TimeSpan.FromMinutes(1)); - - if (response.Message.Content.ToLower() == "y") status = false; - if (response.Message.Content.ToLower() == "n") return; - } - catch - { - await Context.ReplyAsync("Invite expired.", Color.Red); - return; - } - - await Context.Channel.TriggerTypingAsync(); - await _club.AddUserAsync(user, clubData.Id, db); - await Context.ReplyAsync($"Added {user.Mention} to {clubData.Name}", Color.Green); - } - - [Name("Club Remove")] - [Command("clubremove", "clubkick", "ckick")] - [Description("Removes a user from your club")] - [RequiredChannel] - public async Task RemoveClubMemberAsync(CachedMember user) - { - if (user == Context.Member) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.LeaderId == Context.User.Id.RawValue); - if (club == null) return; - await Context.Channel.TriggerTypingAsync(); - if (!await _club.RemoveUserAsync(user, user.Guild, club.Id, db)) - { - await Context.ReplyAsync($"Couldn't remove {user.Mention}", Color.Red); - return; - } - - await Context.ReplyAsync($"Removed {user.Mention} from {club.Name}", Color.Green); - } - - [Name("Club Leave")] - [Command("clubleave")] - [Description("Leaves a club you're part of")] - [RequiredChannel] - public async Task LeaveClubAsync(int id) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var clubUser = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue && x.ClubId == id); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.Id == clubUser.ClubId); - await _club.RemoveUserAsync(Context.Member, Context.Guild, club.Id, db); - await Context.ReplyAsync($"Successfully left {club.Name}", Color.Green); - } - - [Name("Club Leave")] - [Command("clubleave")] - [Description("Leaves a club you're part of")] - [RequiredChannel] - public async Task LeaveClubAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var clubs = await db.ClubPlayers.Where( - x => x.GuildId == Context.Guild.Id.RawValue && x.UserId == Context.User.Id.RawValue).ToListAsync(); - if (clubs.Count == 0) - { - await Context.ReplyAsync("You're currently not in any clubs within this guild"); - return; - } - - var clubInfos = new List(); - var str = new StringBuilder(); - for (var i = 0; i < clubs.Count; i++) - { - var clubInfo = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.Id == clubs[i].ClubId); - clubInfos.Add(clubInfo); - str.AppendLine($"ID: {clubInfo.Id}: {clubInfo.Name}"); - } - - await Context.ReplyAsync($"Which club would you like to leave? Provide ID\n{str}"); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Author.Id.RawValue == Context.Member.Id.RawValue && x.Message.Guild.Id.RawValue == Context.Member.Guild.Id.RawValue, TimeSpan.FromMinutes(1)); - if (response == null || response.Message.Content.IsNullOrWhiteSpace()) - { - await Context.ReplyAsync("Timed out", Color.Red); - return; - } - - var check = int.TryParse(response.Message.Content, out var result); - if (!check) return; - var club = clubInfos.FirstOrDefault(x => x.Id == result); - if (club == null) - { - await Context.ReplyAsync("Couldn't find a club with that ID", Color.Red); - return; - } - - var leave = await _club.RemoveUserAsync(Context.User, Context.Guild, club.Id, db); - if (leave) await Context.ReplyAsync($"Successfully left {club.Name}", Color.Green); - else await Context.ReplyAsync($"Something went wrong, couldn't leave {club.Name}", Color.Red); - } - - [Name("Club Promote")] - [Command("clubpromote", "cprom")] - [Description("Promotes someone to a higher rank")] - [RequiredChannel] - public async Task ClubPromoteAsync(CachedMember user) - { - if (Context.User == user) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.LeaderId == Context.Guild.Id.RawValue); - if (club == null) - { - await Context.ReplyAsync("You can't use this command as you're not a leader of any clubs", - Color.Red); - return; - } - - var clubUser = - await db.ClubPlayers.FirstOrDefaultAsync(x => - x.GuildId == user.Guild.Id.RawValue && x.UserId == user.Id.RawValue && x.Rank <= 2); - if (clubUser != null && clubUser.ClubId != club.Id) - { - await Context.ReplyAsync($"{user.Mention} is already an officer in a club"); - return; - } - - var toPromote = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.ClubId == club.Id && x.GuildId == user.Guild.Id.RawValue && x.UserId == user.Id.RawValue); - if (toPromote == null) - { - await Context.ReplyAsync($"{user.Mention} is not part of {club.Name}", - Color.Red); - return; - } - - if (toPromote.Rank == 2) - { - await Context.ReplyAsync( - $"Are you sure you want to transfer ownership of {club.Name} to {user.Mention}? (y/n)"); - var response = await Context.Bot.GetInteractivity() - .WaitForMessageAsync(x => x.Message.Guild.Id.RawValue == user.Guild.Id.RawValue, TimeSpan.FromMinutes(1)); - if (response == null || response.Message.Content.ToLower() != "y") - { - await Context.ReplyAsync("Cancelling..."); - return; - } - - await ClubService.PromoteUserAsync(user, toPromote, club, db); - await Context.ReplyAsync($"Transferred ownership of {club.Name} to {user.Mention}"); - } - else - { - await ClubService.PromoteUserAsync(user, toPromote, club, db); - await Context.ReplyAsync($"Promoted {user.Mention} to rank 2."); - } - } - - [Name("Club Demote")] - [Command("clubdemote", "cdem")] - [Description("Demotes someone to a lower rank")] - [RequiredChannel] - public async Task ClubDemoteAsync(CachedMember user) - { - if (Context.User == user) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.LeaderId == Context.User.Id.RawValue); - if (club == null) return; - var toDemote = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.ClubId == club.Id && x.GuildId == user.Guild.Id.RawValue && x.UserId == user.Id.RawValue); - if (toDemote == null) - { - await Context.ReplyAsync($"Can't demote {user.Mention} because he/she is not part of {club.Name}", - Color.Red); - return; - } - - if (toDemote.Rank == 3) - { - await Context.ReplyAsync($"Cannot demote {user.Mention} any further. (Already lowest rank)"); - return; - } - - if (toDemote.Rank == 1) return; - await ClubService.DemoteAsync(toDemote, db); - await Context.ReplyAsync($"Demoted {user.Mention} down to rank 3 in {club.Name}", - Color.Green); - } - - [Name("Club Blacklist")] - [Command("clubblacklist", "cblacklist", "cb")] - [Description("Blacklist a user from their club")] - [RequiredChannel] - public async Task BlackListUser(CachedMember user, [Remainder] string reason = null) - { - if (Context.User == user) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.LeaderId == Context.User.Id.RawValue); - if (club == null) return; - var toBlacklist = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.ClubId == club.Id && x.UserId == user.Id.RawValue && x.GuildId == Context.Guild.Id.RawValue); - if (toBlacklist == null) return; - var blacklist = await _club.AddBlacklist(user, Context.Member, Context.Guild, club, db, reason); - if (!blacklist) - { - await Context.ReplyAsync( - "User is already blacklisted. Do you wish to remove it? (y/n)"); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Author.Id.RawValue == Context.Member.Id.RawValue && x.Message.Guild.Id.RawValue == user.Guild.Id.RawValue, TimeSpan.FromMinutes(1)); - if (response == null || response.Message.Content.IsNullOrWhiteSpace()) return; - if (response.Message.Content.ToLower() != "y") - { - await Context.ReplyAsync("User stays blacklisted"); - return; - } - await _club.RemoveBlacklist(user, Context.Guild, club, db); - await Context.ReplyAsync($"Removed blacklist for {user.Mention} in {club.Name}", - Color.Green); - } - - await Context.ReplyAsync($"Blacklisted {user.Mention} from {club.Name}", Color.Green); - } - - [Name("Club Blacklist")] - [Command("clubblacklist", "cblacklist", "cb")] - [Description("Gets current blacklist for their club")] - [RequiredChannel] - public async Task GetBlackList() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.LeaderId == Context.User.Id.RawValue); - if (club == null) return; - var blacklist = await db.ClubBlacklists.Where(x => x.ClubId == club.Id).ToListAsync(); - if (blacklist == null || blacklist.Count == 0) - { - await Context.ReplyAsync("No users currently blacklisted"); - return; - } - - var result = new List(); - for (var i = 0; i < blacklist.Count; i++) - { - var x = blacklist[i]; - var stringBuilder = new StringBuilder(); - stringBuilder.AppendLine( - $"{x.BlackListUser} blacklisted by {x.IssuedUser} on {x.Time.Humanize()} ({x.Time})"); - stringBuilder.AppendLine($"Reason: {x.Reason}"); - result.Add(stringBuilder.ToString()); - } - - await Context.PaginatedReply(result, Context.Guild, $"Blacklisted users for {club.Name}"); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Club/ClubSettings.cs b/Hanekawa/Bot/Modules/Club/ClubSettings.cs deleted file mode 100644 index 70ad3753..00000000 --- a/Hanekawa/Bot/Modules/Club/ClubSettings.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Club -{ - public partial class Club - { - [Name("Club Setting Advertisement")] - [Command("ca")] - [Description("Sets channel where club advertisements will be posted. \nLeave empty to disable")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubSetAdvertisementChannel(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - if (channel == null) - { - cfg.AdvertisementChannel = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled Advertisement creation of clubs.", - Color.Green); - return; - } - - if (cfg.AdvertisementChannel.HasValue && cfg.AdvertisementChannel.Value == channel.Id.RawValue) - { - await Context.ReplyAsync($"Advertisement channel has already been set to {channel.Mention}", - Color.Red); - } - else - { - cfg.AdvertisementChannel = channel.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Advertisement channel set has been been set to {channel.Mention}", - Color.Green); - } - } - - [Name("Club Setting Category")] - [Command("Clubcategory", "ccat")] - [Description("Sets location in where club channels will be created. \nLeave empty to disable")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubSetCategory(CachedCategoryChannel category = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - if (cfg.ChannelCategory.HasValue && cfg.ChannelCategory.Value == category.Id.RawValue) - { - await Context.ReplyAsync($"Club category channel has already been set to {category.Name}", - Color.Red); - return; - } - - if (category == null) - { - cfg.ChannelCategory = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled club channel creation", - Color.Green); - } - else - { - cfg.ChannelCategory = category.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Club category channel set has been been set to {category.Name}", - Color.Green); - } - } - - [Name("Club Setting Level")] - [Command("Clublevel", "cl")] - [Description("Sets level requirement for people to create a club")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubSetLevelRequirement(int level) - { - if (level <= 0) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - cfg.ChannelRequiredLevel = level; - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Set required level limit to create a club to {level}", - Color.Green); - } - - [Name("Club Setting Channel Amount")] - [Command("cca")] - [Description("Sets amount required that's above the level requirement to create a channel")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ClubSetAmountRequirement(int amount) - { - if (amount <= 0) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateClubConfigAsync(Context.Guild); - cfg.ChannelRequiredAmount = amount; - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Set required amount of club members above the level limit to create a channel to {amount}", - Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Game/Game.cs b/Hanekawa/Bot/Modules/Game/Game.cs deleted file mode 100644 index 50224afe..00000000 --- a/Hanekawa/Bot/Modules/Game/Game.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Game.Ship; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Game -{ - [Name("Ship Game")] - [Description( - "Ship game is a game mode where you search for opponements based on your level and fight them. Change between classes to get a feel of different fight styles.")] - [RequiredChannel] - public class Game : HanekawaCommandModule - { - private readonly ShipGameService _shipGame; - public Game(ShipGameService shipGame) => _shipGame = shipGame; - - [Name("Search")] - [Command("search")] - [Description("Searches for a monster to fight")] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task SearchAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var embed = await _shipGame.SearchAsync(Context); - if (embed == null) return; - await Context.ReplyAsync(embed); - } - - [Name("Attack")] - [Command("attack")] - [Description("Starts a fight with a monster you've found")] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task AttackAsync() => await _shipGame.AttackAsync(Context); - - [Name("Duel")] - [Command("duel")] - [Description("Duels a user. Add an amount to duel for credit")] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task DuelAsync(CachedMember user, int? bet = null) => - await _shipGame.AttackAsync(Context, user, bet); - - [Name("Class Info")] - [Command("classinfo")] - [Description("Display all classes in a paginated message")] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task ClassInfoAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var result = new List(); - var classes = await db.GameClasses.OrderBy(x => x.LevelRequirement).ToListAsync(); - for (var i = 0; i < classes.Count(); i++) - { - var x = classes[i]; - result.Add($"{x.Id} - {x.Name} (level: {x.LevelRequirement})"); - } - - if (result.Count == 0) await Context.ReplyAsync("Something went wrong...\nCouldn't get a list of classes."); - else await Context.PaginatedReply(result, Context.Guild, "Game Classes"); - } - - [Name("Class Info")] - [Command("classinfo")] - [Description("Display information on a specific class providing ID")] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task ClassInfoAsync(int classId) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var classInfo = await db.GameClasses.FindAsync(classId); - if (classInfo == null) - { - await Context.ReplyAsync("Couldn't find a class with that ID", Color.Red); - return; - } - - await Context.ReplyAsync($"Information for **{classInfo.Name}**\n" + - $"Health: {100 * classInfo.ModifierHealth}\n" + - $"Damage: {100 * classInfo.ModifierDamage}\n" + - $"Critical Chance: {classInfo.ChanceCrit}\n" + - $"Avoidance: {classInfo.ChanceAvoid}"); - } - - [Name("Choose Class")] - [Command("class")] - [Description("Choose or change into a class with its ID")] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task ChooseClassAsync(int id) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var classInfo = await db.GameClasses.FindAsync(id); - var userData = await db.GetOrCreateUserData(Context.Member); - if (userData.Level < (int) classInfo.LevelRequirement) - { - await Context.ReplyAsync("Not high enough level for this class yet"); - return; - } - - userData.Class = classInfo.Id; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Switched class to **{classInfo.Name}**", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Game/HungerGame.cs b/Hanekawa/Bot/Modules/Game/HungerGame.cs deleted file mode 100644 index 4c511049..00000000 --- a/Hanekawa/Bot/Modules/Game/HungerGame.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Game.HungerGames; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Game.HungerGame; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Game -{ - [Name("Hunger Games")] - [RequirePremium] - public class HungerGame : HanekawaCommandModule - { - private readonly HungerGameService _service; - public HungerGame(HungerGameService service) => _service = service; - - [Name("Start")] - [Command("hgstart")] - [Description("Forcefully starts a hunger game")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task StartAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.HungerGameStatus.FindAsync(Context.Guild.Id.RawValue); - if (cfg == null) - { - await ReplyAsync("Please setup a sign-up channel.", Color.Red); - return; - } - if (!cfg.EventChannel.HasValue) - { - await ReplyAsync("Please setup a event channel with h.hgec ", Color.Red); - return; - } - if (!cfg.SignUpChannel.HasValue) - { - await ReplyAsync("Please setup a sign-up channel with h.hgsc ", Color.Red); - return; - } - - switch (cfg.Stage) - { - case HungerGameStage.Signup: - await ReplyAsync("Closing sign-ups and starting"); - if (!await _service.StartGameAsync(cfg, db, true)) - { - await ReplyAsync("Please setup event and sign-up channels with h.hgec & h.hgsc", Color.Red); - } - break; - case HungerGameStage.OnGoing: - await ReplyAsync("Playing next round"); - await _service.NextRoundAsync(cfg, db); - break; - case HungerGameStage.Closed: - await ReplyAsync("Starting sign-ups"); - await _service.StartSignUpAsync(cfg, db); - break; - default: - return; - } - } - - [Name("Set Sign-up emote")] - [Command("hgemote")] - [Description("Sets the emote used to sign-up for hunger game")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetSignUpEmoteAsync(LocalCustomEmoji emote) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (emote != null) - { - cfg.EmoteMessageFormat = emote.MessageFormat; - await ReplyAsync($"Set Hunger Game sign-up emote to {emote}!", Color.Green); - } - else - { - cfg.SignUpChannel = null; - await ReplyAsync("Now using the default emote for sign-ups!", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Set sign-up channel")] - [Command("hgschannel", "hgsc")] - [Description("Sets the sign-up channel for hunger game")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetSignUpChannel(CachedTextChannel channel = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (channel != null) - { - cfg.SignUpChannel = channel.Id.RawValue; - cfg.EventChannel ??= channel.Id.RawValue; - await ReplyAsync($"Set Hunger Game sign-up channel to {channel.Mention}! This starts the game on schedule (every 6hrs)", Color.Green); - } - else - { - cfg.SignUpChannel = null; - await ReplyAsync("Disabled sign-up channel, and also Hunger Game as a whole", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Set event channel")] - [Command("hgechannel", "hgec")] - [Description("Sets the event channel, where all the rounds will be outputted to")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetEventChannel(CachedTextChannel channel = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (channel != null) - { - cfg.EventChannel = channel.Id.RawValue; - await ReplyAsync($"Set Hunger Game event channel to {channel.Mention}!", Color.Green); - } - else - { - cfg.EventChannel = null; - if (cfg.SignUpChannel.HasValue) cfg.EventChannel = cfg.SignUpChannel.Value; - await ReplyAsync("Disabled event channel, or set it to sign-up channel if there's one currently setup.", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Set sign-up message")] - [Command("hgsm")] - [Description("Sets message being sent during sign-up along with sign-up reaction")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetSignUpMessage([Remainder] string message = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (!message.IsNullOrWhiteSpace()) - { - cfg.SignUpMessage = message; - await ReplyAsync("Set Hunger Game sign-up message!", Color.Green); - } - else - { - cfg.SignUpMessage = null; - await ReplyAsync("Now using the default message for sign-ups!", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Exp Reward")] - [Command("hgexp")] - [Description("Sets exp reward for winning the hunger games!")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetExpReward(int exp = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (exp > 0) - { - cfg.ExpReward = exp; - await ReplyAsync($"Set Hunger Game winning exp reward to {exp}!", Color.Green); - } - else - { - cfg.ExpReward = 0; - await ReplyAsync("Disabled exp reward for winning Hunger Games!", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Credit Reward")] - [Command("hgcredit")] - [Description("Sets credit reward for winning the hunger games!")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetCreditReward(int credit = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (credit > 0) - { - cfg.CreditReward = credit; - await ReplyAsync($"Set Hunger Game winning credit reward to {credit}!", Color.Green); - } - else - { - cfg.CreditReward = 0; - await ReplyAsync("Disabled credit reward for winning Hunger Games!", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Special Credit Reward")] - [Command("hgscredit")] - [Description("Sets special credit reward for winning the hunger games!")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetSpecialCreditAsync(int specialCredit = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (specialCredit > 0) - { - cfg.SpecialCreditReward = specialCredit; - await ReplyAsync($"Set Hunger Game winning special credit reward to {specialCredit}!", Color.Green); - } - else - { - cfg.SpecialCreditReward = 0; - await ReplyAsync("Disabled special credit reward for winning Hunger Games!", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Role Reward")] - [Command("hgrole")] - [Description("Sets role reward for winning the hunger games!")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetRoleReward(CachedRole role = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateHungerGameStatus(Context.Guild); - if (role != null) - { - cfg.RoleReward = role.Id.RawValue; - await ReplyAsync($"Set Hunger Game winning role reward to {role.Mention}!", Color.Green); - } - else - { - cfg.RoleReward = null; - await ReplyAsync("Disabled role reward for winning Hunger Games!", Color.Green); - } - - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Giveaway/Giveaway.cs b/Hanekawa/Bot/Modules/Giveaway/Giveaway.cs deleted file mode 100644 index eca44022..00000000 --- a/Hanekawa/Bot/Modules/Giveaway/Giveaway.cs +++ /dev/null @@ -1,260 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.TypeReaders; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Giveaway; -using Hanekawa.Extensions; -using Hanekawa.Shared; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Giveaway -{ - public class Giveaway : HanekawaCommandModule - { - [Name("Draw")] - [Command("draw")] - [Description("Draw(s) winner(s) from a reaction on a message")] - [Remarks("draw 5 5435346235434 #general")] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task DrawWinnerAsync(int winners, LocalCustomEmoji emote, ulong messageId, CachedTextChannel channel = null) - { - await Context.Message.TryDeleteMessageAsync(); - var stream = new MemoryStream(); - channel ??= Context.Channel; - if (channel == null) return; - if (!(await channel.GetMessageAsync(messageId) is IUserMessage message)) - { - await Context.ReplyAsync($"Couldn't find a message with that ID in {channel.Mention}", - Color.Red); - return; - } - - var reactionAmount = GetReactionAmount(message, emote); - var users = await message.GetReactionsAsync(emote, reactionAmount); - if (users == null) - { - await Context.ReplyAsync( - "Couldn't find any users reacting with that emote. You sure this is a emote on this server?", - Color.Red); - return; - } - - var rnd = new Random(); - var result = users.OrderBy(item => rnd.Next()); - var winnerString = new StringBuilder(); - - await using var file = new StreamWriter(stream); - var nr = 1; - foreach (var x in result) - { - if (nr <= winners) winnerString.AppendLine($"{x}"); - await file.WriteLineAsync($"{nr}: {x.Id.RawValue} - {x.Name}#{x.Discriminator}"); - nr++; - } - - await file.FlushAsync(); - stream.Seek(0, SeekOrigin.Begin); - await channel.SendMessageAsync(new LocalAttachment(stream, "participants.txt"), - $"Drawing winners for giveaway with reaction {emote}:\n{winners}"); - } - - [Name("Draw")] - [Command("draw")] - [Description("Draw winner from an active giveaway with provided ID")] - [Remarks("draw 2")] - [Priority(1)] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task DrawWinnerAsync(int id) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var giveaway = - await db.Giveaways.Include(x => x.Participants).FirstOrDefaultAsync(x => x.GuildId == Context.Guild.Id.RawValue && x.IdNum == id); - if (giveaway == null) - { - await ReplyAsync( - "Couldn't find a giveaway with that ID, please check the ID in the list to make sure you got the correct one", - Color.Red); - return; - } - - var rand = Context.ServiceProvider.GetRequiredService(); - var winners = new ulong[giveaway.WinnerAmount]; - var stringBuilder = new StringBuilder(); - for (var i = 0; i < giveaway.WinnerAmount; i++) - { - var x = giveaway.Participants[rand.Next(giveaway.Participants.Count)]; - var user = await Context.Guild.GetOrFetchMemberAsync(x.UserId); - if (user == null || winners.Contains(user.Id.RawValue)) - { - i--; - continue; - } - winners.SetValue(user.Id.RawValue, i); - stringBuilder.AppendLine($"{i + 1}: {user} ({user.Id.RawValue})"); - } - - await ReplyAsync($"**Drawing winners for giveaway {giveaway.Name} with ID: {giveaway.IdNum}**\n" + - $"{stringBuilder}"); - await db.GiveawayHistories.AddAsync(new GiveawayHistory - { - Id = giveaway.Id, - IdNum = giveaway.IdNum, - GuildId = giveaway.GuildId, - Creator = giveaway.Creator, - Winner = winners, - ClosedAtOffset = giveaway.CloseAtOffset ?? DateTimeOffset.UtcNow, - CreatedAtOffset = giveaway.CreatedAtOffset, - Description = giveaway.Description, - Name = giveaway.Name, - Type = giveaway.Type - }); - await db.SaveChangesAsync(); - db.Giveaways.Remove(giveaway); - await db.SaveChangesAsync(); - } - - [Name("Create Giveaway")] - [Command("gwcreate")] - [Description("Creates a more advanced giveaway (Top.gg vote or activity based)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task CreateAsync(GiveawayType type) - { - var giveaway = new Database.Tables.Giveaway.Giveaway - { - GuildId = Context.Guild.Id.RawValue, - Creator = Context.User.Id.RawValue, - CreatedAtOffset = DateTimeOffset.UtcNow, - Active = true, - Stack = true - }; - var interactive = Context.Bot.GetInteractivity(); - - await ReplyAsync("What's the name of the giveaway u wanna do?"); - var name = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - giveaway.Name = name.Message.Content; - - await ReplyAsync("Description of giveaway?"); - var description = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - giveaway.Description = description.Message.Content; - - await ReplyAsync("How many winners are gonna be drawn?"); - var winnerString = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - var isIntW = int.TryParse(winnerString.Message.Content, out var winnerAmount); - if (isIntW) giveaway.WinnerAmount = winnerAmount; - - await ReplyAsync("Does entries stack? (y/n) (vote multiple times for multiple entries) "); - var stackResponse = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - if (stackResponse.Message.Content.ToLower() == "y" || stackResponse.Message.Content.ToLower() == "yes") - giveaway.Stack = true; - else giveaway.Stack = false; - - await ReplyAsync("Level requirement?"); - var levelStr = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - var isInt = int.TryParse(levelStr.Message.Content, out var level); - if (isInt) giveaway.LevelRequirement = level; - var timeParse = new TimeSpanTypeParser(); - - await ReplyAsync("When does the giveaway end? \n(1d = 1 day, 2h = 2 hours, 4m = 4minutes, 1d2d4m = 1 day, 2hours and 4min. Cancel with 'no'"); - var timespanStr = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - var timespan = await timeParse.ParseAsync(null, timespanStr.Message.Content, Context); - if (timespan.IsSuccessful && timespan.HasValue) - giveaway.CloseAtOffset = DateTimeOffset.UtcNow.Add(timespan.Value); - - await ReplyAsync("Restrict participant to server age? Respond like above to define account age \n1d = 1 day, 2h = 2 hours, 4m = 4minutes, 1d2d4m = 1 day, 2hours and 4min. Cancel with 'no'"); - var serverAge = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - var serverSpan = await timeParse.ParseAsync(null, serverAge.Message.Content, Context); - if (serverSpan.IsSuccessful && serverSpan.HasValue) giveaway.ServerAgeRequirement = serverSpan.Value; - - var embed = new LocalEmbedBuilder - { - Title = giveaway.Name, - Description = giveaway.Description, - Timestamp = giveaway.CloseAtOffset, - Color = Context.Colour.Get(Context.Guild.Id.RawValue), - Footer = new LocalEmbedFooterBuilder {Text = "Giveaway ends in:"} - }; - embed.AddField("Amount of winners", $"{giveaway.WinnerAmount}"); - embed.AddField("Stack Entries", $"{giveaway.Stack}"); - if (giveaway.LevelRequirement.HasValue) - embed.AddField("Level Requirement", $"{giveaway.LevelRequirement.Value}"); - if (giveaway.ServerAgeRequirement.HasValue) - embed.AddField("Server Age Restriction", $"{giveaway.ServerAgeRequirement.Value.Humanize()}"); - await ReplyAsync("Does this look good? (y/n)", false, embed.Build()); - var confirm = await interactive.WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Guild.Id == Context.Guild.Id); - if (confirm == null || confirm.Message.Content.ToLower() != "y") - { - await ReplyAsync("Aborting..."); - return; - } - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var idHistory = await db.GiveawayHistories.CountAsync(x => x.GuildId == Context.Guild.Id.RawValue); - var idActive = await db.Giveaways.CountAsync(x => x.GuildId == Context.Guild.Id.RawValue); - giveaway.IdNum = idActive + idHistory + 1; - await db.Giveaways.AddAsync(giveaway); - await db.SaveChangesAsync(); - await ReplyAsync($"Giveaway added with id {giveaway.IdNum}!"); - } - - [Name("Giveaway List")] - [Command("gwlist")] - [Description("List of giveaways created")] - [RequiredChannel] - public async Task ListAsync() - { - var giveaways = new List(); - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var current = await db.Giveaways.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - var old = await db.GiveawayHistories.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - for (var i = 0; i < current.Count; i++) - { - var x = current[i]; - var str = new StringBuilder(); - str.AppendLine($"Id: {x.IdNum}"); - str.AppendLine($"Name: {x.Name}"); - str.AppendLine($"Created At: {x.CreatedAtOffset.Humanize()}"); - giveaways.Add(str.ToString()); - } - - for (var i = 0; i < old.Count; i++) - { - var x = old[i]; - var str = new StringBuilder(); - str.AppendLine($"Id: {x.IdNum} (closed)"); - str.AppendLine($"Name: {x.Name}"); - str.AppendLine($"Created At: {x.CreatedAtOffset.Humanize()}"); - giveaways.Add(str.ToString()); - } - - if (giveaways.Count == 0) await ReplyAsync("No giveaway history available"); - else await Context.PaginatedReply(giveaways, Context.Guild, $"Giveaways in {Context.Guild.Name}"); - } - - private static int GetReactionAmount(IUserMessage message, LocalCustomEmoji emote) - { - message.Reactions.TryGetValue(emote, out var reactionData); - return reactionData?.Count ?? 0; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Help/Help.cs b/Hanekawa/Bot/Modules/Help/Help.cs deleted file mode 100644 index 794328dc..00000000 --- a/Hanekawa/Bot/Modules/Help/Help.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Help -{ - [Name("Help")] - [Description("Displays all commands and how to execute them")] - public class Help : HanekawaCommandModule - { - [Name("Help")] - [Command("help")] - [Description("List all modules")] - [Priority(1)] - [RequiredChannel] - [Cooldown(1, 2, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task HelpAsync() - { - var result = new StringBuilder(); - var modules = Context.Bot.GetAllModules(); - for (var i = 0; i < modules.Count;) - { - var strBuilder = new StringBuilder(); - for (var j = 0; j < 5; j++) - { - if (i >= modules.Count) continue; - var x = modules[i]; - if (x.Name == "Owner") - { - i++; - continue; - } - strBuilder.Append(j < 4 ? $"`{x.Name}` - " : $"`{x.Name}`"); - i++; - } - - result.AppendLine($"{strBuilder}"); - } - - var embed = new LocalEmbedBuilder().Create(result.ToString(), Context.Colour.Get(Context.Guild.Id.RawValue)); - embed.Author = new LocalEmbedAuthorBuilder {Name = "Module list"}; - embed.Footer = new LocalEmbedFooterBuilder - { - Text = - $"Use `{Context.Prefix}help ` to get help with a module" - }; - await Context.ReplyAsync(embed); - } - - [Name("Help")] - [Command("help")] - [Description("List all commands for provided module, if valid one provided")] - [RequiredChannel] - [Cooldown(1, 2, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task HelpAsync([Remainder] string module) - { - var moduleInfo = Context.Bot.GetAllModules().FirstOrDefault(x => - string.Equals(x.Name, module, StringComparison.CurrentCultureIgnoreCase)); - if (moduleInfo == null) - { - var response = new StringBuilder(); - var moduleList = new List>(); - var modules = Context.Bot.GetAllModules(); - for (var i = 0; i < modules.Count; i++) - { - if (i >= modules.Count) continue; - var x = modules[i]; - if (x.Name.FuzzyMatch(module, out var score)) moduleList.Add(new Tuple(x, score)); - } - - var orderedList = moduleList.OrderByDescending(x => x.Item2).ToList(); - if (orderedList.Count == 0) response.AppendLine("No module matches that search"); - if (orderedList.Count == 1) moduleInfo = orderedList.First().Item1; - - else - { - response.AppendLine("Found multiple matches, did you mean:"); - var amount = moduleList.Count > 5 ? 5 : moduleList.Count; - for (var i = 0; i < amount; i++) - { - var x = orderedList[i]; - response.AppendLine($"{i + 1}: **{x.Item1.Name}**"); - } - } - - if (moduleInfo == null) - { - var embed = new LocalEmbedBuilder().Create(response.ToString(), Context.Colour.Get(Context.Guild.Id.RawValue)); - embed.Author = new LocalEmbedAuthorBuilder { Name = "Module list" }; - embed.Title = "Couldn't find a module with that name"; - embed.Footer = new LocalEmbedFooterBuilder - { - Text = - $"Use `{Context.Prefix}help ` to get help with a module" - }; - await Context.ReplyAsync(embed); - return; - } - } - if (moduleInfo.Name == "Owner") return; - var result = new List(); - for (var i = 0; i < moduleInfo.Commands.Count; i++) - { - var cmd = moduleInfo.Commands[i]; - var command = cmd.Aliases.FirstOrDefault(); - var content = new StringBuilder(); - var perms = PermBuilder(cmd); - content.AppendLine(!cmd.Name.IsNullOrWhiteSpace() - ? $"**{cmd.Name}**" - : $"**{cmd.Aliases.FirstOrDefault()}**"); - if (!perms.IsNullOrWhiteSpace()) content.Append($"**Require {perms}** "); - if (PremiumCheck(cmd, out var prem)) content.AppendLine(prem); - content.AppendLine( - $"Alias: **{cmd.Aliases.Aggregate("", (current, cmdName) => current + $"{cmdName}, ")}**"); - if (!cmd.Description.IsNullOrWhiteSpace()) content.AppendLine(cmd.Description); - if (!cmd.Remarks.IsNullOrWhiteSpace()) content.AppendLine(cmd.Remarks); - content.AppendLine($"Usage: **{Context.Prefix}{command} {ParamBuilder(cmd)}**"); - content.AppendLine($"Example: {Context.Prefix}{command} {ExampleParamBuilder(cmd)}"); - result.Add(content.ToString()); - } - - if (result.Count > 0) - await Context.PaginatedReply(result, Context.Guild, "Command List"); - else await Context.ReplyAsync("Couldn't find any commands in that module", Color.Red); - } - - // Showcases the params - private string ParamBuilder(Command command) - { - var output = new StringBuilder(); - if (!command.Parameters.Any()) return output.ToString(); - for (var i = 0; i < command.Parameters.Count; i++) - { - var x = command.Parameters[i]; - var name = x.Name; - if (x.IsOptional) - output.Append($"[{name} = {x.DefaultValue}] "); - else if (x.IsRemainder) - output.Append($"...{name} "); - else if (x.IsMultiple) - output.Append($"|{name} etc...|"); - else - output.Append($"<{name}> "); - } - - return output.ToString(); - } - - // Adds examples, ie. for user it adds bob#0000 - private string ExampleParamBuilder(Command command) - { - var output = new StringBuilder(); - if (!command.Parameters.Any()) return output.ToString(); - for (var i = 0; i < command.Parameters.Count; i++) - { - var x = command.Parameters[i]; - var name = PermTypeBuilder(x); - if (x.IsOptional) - output.Append($"{name} "); - else if (x.IsRemainder) - output.Append($"{name} "); - else if (x.IsMultiple) - output.Append($"{name} "); - else - output.Append($"{name} "); - } - - return output.ToString(); - } - - private static string PermTypeBuilder(Parameter parameter) => - parameter.Type == typeof(CachedMember) ? "@bob#0000" : - parameter.Type == typeof(CachedRole) ? "role" : - parameter.Type == typeof(CachedTextChannel) ? "#General" : - parameter.Type == typeof(CachedVoiceChannel) ? "VoiceChannel" : - parameter.Type == typeof(CachedCategoryChannel) ? "Category" : - parameter.Type == typeof(TimeSpan) ? "1h2m" : - parameter.Type == typeof(int) ? "5" : - parameter.Type == typeof(string) ? "Example text" : - parameter.Type == typeof(ulong) ? "431610594290827267" : parameter.Name; - - // Appends permission requirements - private string PermBuilder(Command cmd) - { - var str = new StringBuilder(); - foreach (var x in cmd.Module.Checks) - { - if (x is RequireMemberGuildPermissionsAttribute perm) - { - if (perm.Permissions.Count() == 1) str.AppendLine(perm.Permissions.FirstOrDefault().ToString()); - else foreach (var e in perm.Permissions) str.Append($"{e}, "); - } - } - foreach (var x in cmd.Checks) - { - if (x is RequireMemberGuildPermissionsAttribute perm) - { - if (perm.Permissions.Count() == 1) str.AppendLine(perm.Permissions.FirstOrDefault().ToString()); - else foreach (var e in perm.Permissions) str.Append($"{e}, "); - } - } - - return str.ToString(); - } - - private bool PremiumCheck(Command cmd, out string perm) - { - var premium = cmd.Checks.FirstOrDefault(x => x is RequirePremium); - if (premium == null) premium = cmd.Module.Checks.FirstOrDefault(x => x is RequirePremium); - if (premium != null) - { - perm = "**Require Premium**"; - return true; - } - - perm = null; - return false; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Info/Info.cs b/Hanekawa/Bot/Modules/Info/Info.cs deleted file mode 100644 index f35383e7..00000000 --- a/Hanekawa/Bot/Modules/Info/Info.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Diagnostics; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Info -{ - [Name("Info")] - [Description("Commands for delivering information about the bot")] - public class Info : HanekawaCommandModule - { - [Name("About")] - [Command("about", "info", "bot", "botinfo")] - [Description("General information about the bot and links")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - [RequiredChannel] - public async Task AboutAsync() - { - // var appData = await Context.Bot.GetCurrentApplicationAsync(); - - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder { Name = Context.Bot.CurrentUser.Name, IconUrl = Context.Bot.CurrentUser.GetAvatarUrl() }, - Fields = - { - new LocalEmbedFieldBuilder { Name = "Up Time", Value = (DateTime.Now - Process.GetCurrentProcess().StartTime).Humanize(3), IsInline = true }, - new LocalEmbedFieldBuilder { Name = "Support", Value = "[Invite Link](https://discord.gg/gGu5TT6)", IsInline = true }, - new LocalEmbedFieldBuilder { Name = "Bot Invite", Value = "[Invite Link](https://discordapp.com/api/oauth2/authorize?client_id=431610594290827267&scope=bot&permissions=8)", IsInline = true } - } - }.Create("Hanekawa is a bot focused on rewarding user activity while giving server owners and moderators the tools they need for moderation, short and long-term.", Context.Colour.Get(Context.Guild.Id.RawValue)); - await Context.ReplyAsync(embed); - } - - [Name("Up Time")] - [Command("uptime")] - [Description("Show bots up time")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - [RequiredChannel] - public async Task UptimeAsync() - => await Context.ReplyAsync($"Current up time: {(DateTime.Now - Process.GetCurrentProcess().StartTime).Humanize()}"); - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Level/ExpEvent.cs b/Hanekawa/Bot/Modules/Level/ExpEvent.cs deleted file mode 100644 index 9afb8bf4..00000000 --- a/Hanekawa/Bot/Modules/Level/ExpEvent.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Level -{ - public partial class Level - { - [Name("Exp Multiplier")] - [Command("expmulti")] - [Description("Checks what the current exp multiplier is")] - [RequiredChannel] - public async Task ExpMultiplierAsync() - => await Context.ReplyAsync($"Current multiplier is: {_exp.GetMultiplier(Context.Guild.Id.RawValue)}"); - - [Name("Text Exp Multiplier")] - [Command("txtexpmulti", "tem")] - [Description("Sets a new exp multiplier permanently")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task TextExpMultiplierAsync(double multiplier) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var old = _exp.GetMultiplier(Context.Guild.Id.RawValue); - var cfg = await db.GetOrCreateLevelConfigAsync(Context.Guild); - cfg.TextExpMultiplier = multiplier; - await db.SaveChangesAsync(); - _exp.AdjustTextMultiplier(Context.Guild.Id.RawValue, multiplier); - await Context.ReplyAsync($"Changed text exp multiplier from {old} to {multiplier}", - Color.Green); - } - - [Name("Voice Exp Multiplier")] - [Command("voiceexpmulti", "vem")] - [Description("Sets a new exp multiplier permanently")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task VoiceExpMultiplierAsync(double multiplier) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var old = _exp.GetMultiplier(Context.Guild.Id.RawValue); - var cfg = await db.GetOrCreateLevelConfigAsync(Context.Guild); - cfg.VoiceExpMultiplier = multiplier; - await db.SaveChangesAsync(); - _exp.AdjustVoiceMultiplier(Context.Guild.Id.RawValue, multiplier); - await Context.ReplyAsync($"Changed voice exp multiplier from {old} to {multiplier}", - Color.Green); - } - - [Name("Enable/Disable Voice Exp")] - [Command("voicexp", "ve")] - [Description("Enable/Disables experience gained from being in voice channels")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ToggleVoiceExp() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLevelConfigAsync(Context.Guild); - if (cfg.VoiceExpEnabled) - { - cfg.VoiceExpEnabled = false; - await Context.ReplyAsync("Disabled experience gained from being in voice channels!", - Color.Green); - } - else - { - cfg.VoiceExpEnabled = true; - await Context.ReplyAsync("Enabled experience gained from being in voice channels!", - Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Exp Event")] - [Command("expevent")] - [Description("Starts a exp event with a specified multiplier for a period of time")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ExpEventAsync(double multiplier, TimeSpan? duration = null) - { - if (multiplier <= 0) return; - duration ??= TimeSpan.FromDays(1); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - await _exp.StartEventAsync(db, Context, multiplier, duration.Value); - await Context.ReplyAsync($"Started a {multiplier}x exp event for {duration.Value.Humanize(2)}!", - Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Level/Experience.cs b/Hanekawa/Bot/Modules/Level/Experience.cs deleted file mode 100644 index 310c328c..00000000 --- a/Hanekawa/Bot/Modules/Level/Experience.cs +++ /dev/null @@ -1,294 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Extensions.Interactivity; -using Disqord.Extensions.Interactivity.Menus.Paged; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using ChannelType = Hanekawa.Shared.ChannelType; - -namespace Hanekawa.Bot.Modules.Level -{ - public partial class Level - { - [Name("Add Experience")] - [Command("addexp")] - [Description("Give a certain amount of experience to a one or more users")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddExp(int exp, params CachedMember[] users) - { - if (exp == 0) return; - if (exp < 0) - { - await RemoveExp(exp, users); - return; - } - - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - string userString = null; - for (var i = 0; i < users.Length; i++) - { - var user = users[i]; - var userData = await db.GetOrCreateUserData(users[i]); - await _exp.AddExpAsync(user, userData, exp, 0, db); - userString += $"{user.Mention ?? "Couldn't find user"}\n"; - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Added {exp} to:\n" + - $"{userString}"); - } - - [Name("Remove Experience")] - [Command("remexp")] - [Description("Removes a certain amount of experience to a one or more users")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveExp(int exp, params CachedMember[] users) - { - if (exp <= 0) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - string userString = null; - for (var i = 0; i < users.Length; i++) - { - var user = users[i]; - var userData = await db.GetOrCreateUserData(users[i]); - await _exp.AddExpAsync(user, userData, exp * -1, 0, db); - userString += $"{user.Mention}\n"; - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Removed {exp} from:\n" + - $"{userString}"); - } - - [Name("Add Exp Ignore Channel")] - [Command("eia")] - [Description("Adds one or more channels to ignore exp")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddExpIgnoreChannel(params CachedTextChannel[] channels) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var channeList = _exp.ServerTextChanReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var content = new StringBuilder(); - content.AppendLine("Channels added to exp ignore list:"); - for (var i = 0; i < channels.Length; i++) - { - var x = channels[i]; - if (!channeList.TryGetValue(x.Id.RawValue, out _)) - { - channeList.Add(x.Id.RawValue); - var data = new LevelExpReduction - { - GuildId = Context.Guild.Id.RawValue, - ChannelId = x.Id.RawValue, - ChannelType = ChannelType.Text - }; - await db.LevelExpReductions.AddAsync(data); - content.AppendLine($"Added {x.Mention}"); - } - else - { - content.AppendLine($"{x.Mention} is already added"); - } - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync(content.ToString()); - } - - [Name("Add Exp Ignore Channel")] - [Command("eia")] - [Description("Adds one or more channels to ignore exp")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddExpIgnoreChannel(params CachedVoiceChannel[] channels) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var channeList = _exp.ServerVoiceChanReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var content = new StringBuilder(); - content.AppendLine("Channels added to exp ignore list:"); - for (var i = 0; i < channels.Length; i++) - { - var x = channels[i]; - if (!channeList.TryGetValue(x.Id.RawValue, out _)) - { - channeList.Add(x.Id.RawValue); - var data = new LevelExpReduction - { - GuildId = Context.Guild.Id.RawValue, - ChannelId = x.Id.RawValue, - ChannelType = ChannelType.Voice - }; - await db.LevelExpReductions.AddAsync(data); - content.AppendLine($"Added {x.Name}"); - } - else - { - content.AppendLine($"{x.Name} is already added"); - } - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync(content.ToString()); - } - - [Name("Add Exp Ignore Category")] - [Command("eia")] - [Description("Adds one or more categories to ignore giving exp")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddExpIgnoreChannel(params CachedCategoryChannel[] category) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var channeList = _exp.ServerCategoryReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var content = new StringBuilder(); - content.AppendLine("Categories added to exp ignore list:"); - for (var i = 0; i < category.Length; i++) - { - var x = category[i]; - if (!channeList.TryGetValue(x.Id.RawValue, out _)) - { - channeList.Add(x.Id.RawValue); - var data = new LevelExpReduction - { - GuildId = Context.Guild.Id.RawValue, - ChannelId = x.Id.RawValue, - ChannelType = ChannelType.Category - }; - await db.LevelExpReductions.AddAsync(data); - content.AppendLine($"Added {x.Name}"); - } - else - { - content.AppendLine($"{x.Name} is already added"); - } - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync(content.ToString()); - } - - [Name("Remove Exp Ignore Channel")] - [Command("eir")] - [Description("Removes one or more channels from ignore exp table")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveExpIgnoreChannel(params CachedTextChannel[] channels) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var channeList = _exp.ServerTextChanReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var content = new StringBuilder(); - content.AppendLine("Channels removed from exp ignore list:"); - for (var i = 0; i < channels.Length; i++) - { - var x = channels[i]; - if (channeList.TryGetValue(x.Id.RawValue, out _)) - { - channeList.Remove(x.Id.RawValue); - var data = await db.LevelExpReductions.FirstOrDefaultAsync(z => - z.GuildId == Context.Guild.Id.RawValue && z.ChannelId == x.Id.RawValue); - db.LevelExpReductions.Remove(data); - content.AppendLine($"Removed {x.Mention}"); - } - else - { - content.AppendLine($"Can't remove {x.Mention} as it's not added"); - } - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync(content.ToString()); - } - - [Name("Remove Exp Ignore Category")] - [Command("eir")] - [Description("Removes one or more category from ignore exp table")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveExpIgnoreChannel(params CachedCategoryChannel[] category) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var channeList = _exp.ServerCategoryReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var content = new StringBuilder(); - content.AppendLine("Categories removed from exp ignore list:"); - for (var i = 0; i < category.Length; i++) - { - var x = category[i]; - if (channeList.TryGetValue(x.Id.RawValue, out _)) - { - channeList.Remove(x.Id.RawValue); - var data = await db.LevelExpReductions.FirstOrDefaultAsync(z => - z.GuildId == Context.Guild.Id.RawValue && z.ChannelId == x.Id.RawValue); - db.LevelExpReductions.Remove(data); - content.AppendLine($"Removed {x.Name}"); - } - else - { - content.AppendLine($"Can't remove {x.Name} as it's not added"); - } - } - - await db.SaveChangesAsync(); - await Context.ReplyAsync(content.ToString()); - } - - [Name("Remove Exp Ignore Category")] - [Command("eir")] - [Description("Removes one or more category from ignore exp table")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - [RequiredChannel] - public async Task ExpIgnoreList() - { - var channels = _exp.ServerTextChanReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var categories = _exp.ServerCategoryReduction.GetOrAdd(Context.Guild.Id.RawValue, new HashSet()); - var result = new StringBuilder(); - var pages = new List(); - if (channels.Count == 0 && categories.Count == 0) result.AppendLine("No channels"); - var count = 0; - if (channels.Count > 0) - foreach (var x in channels) - { - var channel = Context.Guild.GetTextChannel(x); - if (channel == null) continue; - if (count > 5) - { - pages.Add(new Page(result.ToString())); - result.Clear(); - count = 0; - } - result.AppendLine($"Channel: {channel.Mention}"); - count++; - } - - if (categories.Count > 0) - foreach (var x in categories) - { - var category = Context.Guild.GetCategoryChannel(x); - if (category == null) continue; - if (count > 5) - { - pages.Add(new Page(result.ToString())); - result.Clear(); - count = 0; - } - result.AppendLine($"Category: {category.Name}"); - count++; - } - - await Context.Bot.GetInteractivity().StartMenuAsync(Context.Channel, - new PagedMenu(Context.Member.Id.RawValue, new DefaultPageProvider(pages))); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Level/Level.cs b/Hanekawa/Bot/Modules/Level/Level.cs deleted file mode 100644 index e547aacd..00000000 --- a/Hanekawa/Bot/Modules/Level/Level.cs +++ /dev/null @@ -1,275 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Level -{ - [Name("Level")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public partial class Level : HanekawaCommandModule - { - private readonly ExpService _exp; - public Level(ExpService exp) => _exp = exp; - - [Name("Level Reset")] - [Command("lr", "lvlreset")] - [Description("Reset the server level/exp back to 0")] - [RequireMemberGuildPermissions(Permission.Administrator)] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task ResetAsync() - { - await Context.ReplyAsync( - "You sure you want to completely reset server levels/exp on this server?(y/n) \nthis change can't be reversed."); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync( - x => x.Message.Author.Id.RawValue == Context.Member.Id.RawValue && x.Message.Guild.Id.RawValue == Context.Guild.Id.RawValue, - TimeSpan.FromMinutes(1)); - if (response == null || response.Message.Content.ToLower() != "y") - { - await Context.ReplyAsync("Aborting..."); - return; - } - - var msg = await Context.ReplyAsync("Server level reset in progress..."); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var users = db.Accounts.Where(x => x.GuildId == Context.Guild.Id.RawValue); - foreach (var x in users) - { - x.Level = 1; - x.Exp = 0; - x.TotalExp = 0; - } - - await db.SaveChangesAsync(); - try - { - var updEmbed = msg.Embeds.First().ToEmbedBuilder(); - updEmbed.Color = Color.Green; - updEmbed.Description = "Server level reset complete."; - await msg.ModifyAsync(x => x.Embed = updEmbed.Build()); - } - catch - { - await Context.ReplyAsync("Server level reset complete!", Color.Green); - } - } - - [Name("Set Level")] - [Command("sl", "setlvl")] - [Description("Sets a user to a desired level")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task SetLevelAsync(CachedMember user, int level) - { - if (level <= 0) return; - var totalExp = 0; - for (var i = 1; i < level + 1; i++) totalExp += _exp.ExpToNextLevel(i); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userdata = await db.GetOrCreateUserData(user); - userdata.Level = level; - userdata.Exp = 0; - userdata.TotalExp = totalExp; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set {user.Mention} level to {level}", Color.Green); - } - - [Name("Decay")] - [Command("decay")] - [Description("Toggles artificial level decay (decay starts after 14 days) No exp is lost")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task DecayAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLevelConfigAsync(Context.Guild); - if (cfg.Decay) - { - cfg.Decay = false; - await db.SaveChangesAsync(); - await Context.ReplyAsync( - "Level decay has been disabled.", - Color.Green); - } - else - { - cfg.Decay = true; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Level decay has been activated. Decay starts after 14 days of user being inactive (hasn't sent a message).\n" + - "No exp lost and exp returned to normal after sending a message again.", - Color.Green); - } - } - - [Name("Level Role Stack")] - [Command("lrs", "lvlstack")] - [Description("Toggles between level roles stacking or keep the highest earned one")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task StackToggleAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLevelConfigAsync(Context.Guild); - if (cfg.StackLvlRoles) - { - cfg.StackLvlRoles = false; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Users will now only keep the highest earned role.", - Color.Green); - } - else - { - cfg.StackLvlRoles = true; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Level roles does now stack.", - Color.Green); - } - } - - [Name("Level Stack Role Add")] - [Command("lsa", "lvlsadd")] - [Description("Adds a role reward which will stack regardless of setting (useful for permission role)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task StackAddAsync(int level, [Remainder] CachedRole role) => - await AddLevelRole(Context, level, role, true); - - [Name("Level Role Add")] - [Command("la", "lvladd")] - [Description("Adds a role reward")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddAsync(int level, [Remainder] CachedRole role) => - await AddLevelRole(Context, level, role, false); - - [Name("Level Role Remove")] - [Command("lr", "lvlremove")] - [Description("Removes a role reward")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveAsync(int level) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var role = await db.LevelRewards.FirstOrDefaultAsync(x => - x.GuildId == Context.Guild.Id.RawValue && x.Level == level); - if (role == null) - { - await Context.ReplyAsync("Couldn't find a role with that level", Color.Red); - return; - } - - db.LevelRewards.Remove(role); - await db.SaveChangesAsync(); - await Context.ReplyAsync( - $"Removed {Context.Guild.Roles.First(x => x.Key == role.Role).Value.Name} from level rewards!", - Color.Green); - } - - [Name("Level List")] - [Command("lvlist")] - [Description("Lists all role rewards")] - [RequiredChannel] - public async Task LevelListAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var levels = await db.LevelRewards.Where(x => x.GuildId == Context.Guild.Id.RawValue).OrderBy(x => x.Level) - .ToListAsync(); - if (levels == null || levels.Count == 0) - { - await Context.ReplyAsync("No level roles added."); - return; - } - - var pages = new List(); - for (var i = 0; i < levels.Count; i++) - { - var x = levels[i]; - try - { - var role = Context.Guild.GetRole(x.Role); - if (role == null) pages.Add("Role not found"); - else - pages.Add($"Name: {role.Name ?? "Role not found"}\n" + - $"Level: {x.Level}\n" + - $"Stack: {x.Stackable}"); - } - catch - { - pages.Add("Role not found"); - //todo: Handle this better in the future - } - } - - await Context.PaginatedReply(pages, Context.Guild, $"Level Roles for {Context.Guild.Name}"); - } - - private async Task AddLevelRole(DiscordCommandContext context, int level, CachedRole role, bool stack) - { - if (level <= 0) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var check = await db.LevelRewards.FindAsync(context.Guild.Id.RawValue, level); - if (check != null) - { - var gRole = context.Guild.GetRole(check.Role); - if (gRole != null) - { - await Context.ReplyAsync($"Do you wish to replace {gRole.Name} for level {check.Level}? (y/n)"); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync( - x => x.Message.Author.Id.RawValue == Context.Member.Id.RawValue && x.Message.Guild.Id.RawValue == Context.Guild.Id.RawValue, - TimeSpan.FromMinutes(1)); - if (response == null || response.Message.Content.ToLower() != "y") - { - await Context.ReplyAsync("Cancelling."); - return; - } - - if (response.Message.Content.ToLower() != "yes") - { - await Context.ReplyAsync("Cancelling."); - return; - } - } - } - - var data = new LevelReward - { - GuildId = context.Guild.Id.RawValue, - Level = level, - Role = role.Id.RawValue, - Stackable = stack - }; - await db.LevelRewards.AddAsync(data); - await db.SaveChangesAsync(); - var users = await db.Accounts.Where(x => x.GuildId == role.Guild.Id.RawValue && x.Level >= level && x.Active) - .ToListAsync(); - if (users.Count <= 10) - { - for (var i = 0; i < users.Count; i++) - { - var x = users[i]; - var user = await role.Guild.GetOrFetchMemberAsync(x.UserId); - if(user == null) continue; - await _exp.NewLevelManagerAsync(users[i], user as CachedMember, db); - } - } - - if (users.Count > 10) await Context.ReplyAsync($"Added {role.Name} as a lvl{level} reward!", Color.Green); - else - await Context.ReplyAsync( - $"Added {role.Name} as a lvl{level} reward, and applied to {users.Count} users", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Music/Music.cs b/Hanekawa/Bot/Modules/Music/Music.cs deleted file mode 100644 index 6c0fdf90..00000000 --- a/Hanekawa/Bot/Modules/Music/Music.cs +++ /dev/null @@ -1,358 +0,0 @@ -namespace Hanekawa.Bot.Modules.Music -{ - /* - [Name("Music")] - [Description("Music module")] - [RequireBotPermission(GuildPermission.EmbedLinks)] - [RequiredMusicChannel] - [RequiredChannel] - public class Music : HanekawaCommandModule - { - private readonly RequiredMusicChannel _channel; - private readonly LavaRestClient _lavaRestClient; - private readonly LavaSocketClient _lavaSocketClient; - - public Music(LavaSocketClient lavaSocketClient, LavaRestClient lavaRestClient, RequiredMusicChannel channel) - { - _lavaSocketClient = lavaSocketClient; - _lavaRestClient = lavaRestClient; - _channel = channel; - } - - [Name("Join")] - [Command("join")] - [Description("Joins the voice channel")] - public async Task JoinAsync() - { - if (Context.User.VoiceChannel == null) - { - await Context.ReplyAsync("You need to be in a voice channel to use this command", Color.Red); - return; - } - - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) - { - player = await _lavaSocketClient.ConnectAsync(Context.User.VoiceChannel, Context.Channel); - await Context.ReplyAsync($"Connected to {player.VoiceChannel.Name}", Color.Red); - } - else - { - await Context.ReplyAsync($"Already connected to {player.VoiceChannel.Name}", Color.Red); - } - } - - [Name("Move")] - [Command("move")] - [Description("Moves the bot to a different voice channel")] - public async Task MoveAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) - { - await _lavaSocketClient.ConnectAsync(Context.User.VoiceChannel, Context.Channel); - await Context.ReplyAsync($"Connected to {Context.User.VoiceChannel.Name}"); - return; - } - - if (player.IsPlaying || Context.User.VoiceChannel == player.VoiceChannel) return; - - var old = player.VoiceChannel; - await _lavaSocketClient.MoveChannelsAsync(Context.User.VoiceChannel); - await Context.ReplyAsync($"Moved from {old.Name} to {Context.User.VoiceChannel}"); - } - - [Name("Stop")] - [Command("stop")] - [Description("stops the current song from playing")] - public async Task StopAsync() - { - if (Context.User.VoiceChannel == null) return; - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) return; - if (Context.User.VoiceChannel != player.VoiceChannel) return; - var song = player.CurrentTrack; - await player.StopAsync(); - if (song.Title.IsNullOrWhiteSpace()) - { - await Context.ReplyAsync("Stopped current player", Color.Green); - return; - } - - await Context.ReplyAsync($"Stopped {song.Title} from playing.", Color.Green); - } - - [Name("Disconnect")] - [Command("disconnect", "disc", "leave")] - [Description("Disconnects the bot from voice channel.")] - public async Task DisconnectAsync() - { - if (Context.User.VoiceChannel == null) return; - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) return; - if (Context.User.VoiceChannel != player.VoiceChannel) return; - var song = player.CurrentTrack; - await _lavaSocketClient.DisconnectAsync(player.VoiceChannel); - await Context.ReplyAsync("Disconnected", Color.Green); - } - - [Name("Currently Playing")] - [Command("CurrentlyPlaying", "NowPlaying", "np")] - [Description("Display which song is currently playing")] - public async Task NowPlayingAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null || !player.IsPlaying) - { - await Context.ReplyAsync("Currently not playing"); - return; - } - - await Context.ReplyAsync($"Currently playing: {player.CurrentTrack.Title}"); - } - - [Name("Play")] - [Command("play", "p")] - [Description("Queues up a song, joins channel if not currently connected")] - public async Task PlayAsync([Remainder] string query) - { - if (Context.User.VoiceChannel == null) - { - await Context.ReplyAsync("You need to be in a voice channel to use this command", Color.Red); - return; - } - - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue) ?? - await _lavaSocketClient.ConnectAsync(Context.User.VoiceChannel, Context.Channel); - if (player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in the same channel as me to queue up songs", - Color.Red); - return; - } - - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) return; - var songResult = await _lavaRestClient.SearchYouTubeAsync(query); - if (songResult.LoadType == LoadType.NoMatches || songResult.LoadType == LoadType.LoadFailed) - { - await Context.ReplyAsync("Couldn't find a song with that name", Color.Red); - } - else - { - var song = songResult.Tracks.FirstOrDefault(); - var msg = player.Queue.Count == 0 ? $"Started playing {song?.Title}" : $"Queued {song?.Title}"; - await player.PlayAsync(song); - _lavaSocketClient.UpdateTextChannel(Context.Guild.Id.RawValue, Context.Channel); - await Context.ReplyAsync(msg); - } - } - - [Name("Queue")] - [Command("queue", "que", "q")] - [Description("Displays the current queue")] - public async Task QueueAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) return; - if (player.Queue.Count == 0) - { - await Context.ReplyAsync("Queue is currently empty"); - return; - } - - var queue = new List(); - for (var i = 0; i < player.Queue.Count; i++) - { - var x = player.Queue.Items.ElementAt(i); - queue.Add(i == 0 ? $"{i + 1}> {x.Id.RawValue}" : $"{i + 1}: {x.Id.RawValue}"); - } - - await Context.ReplyPaginated(queue, Context.Guild, $"Current queue in {Context.Guild.Name}"); - } - - [Name("Pause")] - [Command("pause")] - [Description("Pauses the player if its currently playing")] - public async Task PauseAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null || player.IsPaused) return; - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in a voice channel or same channel as bot to use this command", - Color.Red); - return; - } - - await player.PauseAsync(); - await Context.ReplyAsync("Paused the song!"); - } - - [Name("Resume")] - [Command("resume")] - [Description("Resumes the player if its paused")] - public async Task ResumeAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null || !player.IsPaused) return; - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in a voice channel or same channel as bot to use this command", - Color.Red); - return; - } - - await player.ResumeAsync(); - await Context.ReplyAsync("Resumed the song!"); - } - - [Name("Volume")] - [Command("volume")] - [Description("Sets volume")] - public async Task VolumeAsync(int volume) - { - if (volume < 0) return; - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) - { - await Context.ReplyAsync("Currently not connected to any channel", Color.Red); - return; - } - - if (!player.IsPlaying) - { - await Context.ReplyAsync("Currently not playing", Color.Red); - return; - } - - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in a voice channel or same channel as bot to use this command", - Color.Red); - return; - } - - await player.SetVolumeAsync(volume); - await Context.ReplyAsync($"Set volume to {volume}%"); - } - - [Name("Skip")] - [Command("skip")] - [Description("Skips current song")] - public async Task SkipAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) - { - await Context.ReplyAsync("Currently not connected to any channel", Color.Red); - return; - } - - if (!player.IsPlaying) - { - await Context.ReplyAsync("Currently not playing", Color.Red); - return; - } - - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in a voice channel or same channel as bot to use this command", - Color.Red); - return; - } - - var track = await player.SkipAsync(); - await Context.ReplyAsync($"Skipped {track.Title}"); - } - - [Name("Clear")] - [Command("clear")] - [Description("Clears current playlist")] - public async Task ClearAsync() - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) - { - await Context.ReplyAsync("Currently not connected to any channel", Color.Red); - return; - } - - if (!player.IsPlaying) - { - await Context.ReplyAsync("Currently not playing", Color.Red); - return; - } - - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in a voice channel or same channel as bot to use this command", - Color.Red); - return; - } - - player.Queue.Clear(); - await player.StopAsync(); - await Context.ReplyAsync("Cleared queue"); - } - - [Name("Rewind")] - [Command("rewind")] - [Description( - "Goes back, or rewinds back to a part of the song, if past the limit of the song, starts from teh beginning")] - public async Task RewindsAsync(TimeSpan rewind) - { - var player = _lavaSocketClient.GetPlayer(Context.Guild.Id.RawValue); - if (player == null) - { - await Context.ReplyAsync("Currently not connected to any channel", Color.Red); - return; - } - - if (!player.IsPlaying) - { - await Context.ReplyAsync("Currently not playing", Color.Red); - return; - } - - if (Context.User.VoiceChannel == null || player.VoiceChannel != Context.User.VoiceChannel) - { - await Context.ReplyAsync("You need to be in a voice channel or same channel as bot to use this command", - Color.Red); - return; - } - - var pos = player.CurrentTrack.Position - rewind; - if (pos < new TimeSpan(0, 0, 0, 0)) pos = new TimeSpan(0, 0, 0, 0); - await player.SeekAsync(pos); - await Context.ReplyAsync($"Rewinded {rewind.Humanize(2)} on **{player.CurrentTrack.Title}**"); - } - - [Name("Music Channel")] - [Command("mc", "musicchannel")] - [Description( - "Sets a channel to be used to queue and play music, if none set, defaults to regular ignore channel")] - [RequireUserPermission(GuildPermission.ManageGuild)] - public async Task MusicChannelAsync(SocketTextChannel channel = null) - { - using (var db = scope.ServiceProvider.GetRequiredService()) - { - var cfg = await db.GetOrCreateMusicConfig(Context.Guild); - if (channel == null) - { - cfg.TextChId = null; - await db.SaveChangesAsync(); - _channel.AddOrRemoveChannel(Context.Guild); - await Context.ReplyAsync("Disabled music channel. Following regular ignore channels"); - } - else - { - cfg.TextChId = channel.Id.RawValue; - _channel.AddOrRemoveChannel(Context.Guild, channel); - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set music channel to {channel.Mention}"); - } - } - } - } - */ -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Owner/Owner.cs b/Hanekawa/Bot/Modules/Owner/Owner.cs deleted file mode 100644 index 17bb9419..00000000 --- a/Hanekawa/Bot/Modules/Owner/Owner.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Administration; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Scripting; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Owner -{ - [Name("Owner")] - [Description("Owner commands for bot overview")] - [RequireUser(111123736660324352)] - public class Owner : HanekawaCommandModule - { - [Command("mmlol")] - [RequireGuild(431617676859932704)] - public async Task ReturnRole() - { - try - { - await Context.Message.DeleteAsync(); - var role = Context.Guild.GetRole(431621144517279755); - await Context.Member.GrantRoleAsync(role.Id); - } - catch - { - await Context.Message.DeleteAsync(); - var roles = await Context.Guild.GetRolesAsync(); - var role = roles.FirstOrDefault(x => x.Id.RawValue == 431621144517279755); - await Context.Member.GrantRoleAsync(role.Id); - } - } - - [Name("Servers")] - [Command("servers")] - [Description("List all servers bot is part of")] - public async Task ServersAsync() - { - var servers = new List(); - var totalMembers = 0; - foreach (var (_, value) in Context.Bot.Guilds.ToList()) - { - try - { - totalMembers += value.MemberCount; - var sb = new StringBuilder(); - sb.AppendLine($"Server: {value.Name} ({value.Id.RawValue})"); - sb.AppendLine($"Members: {value.MemberCount}"); - sb.AppendLine($"Owner: {value.Owner.Mention}"); - servers.Add(sb.ToString()); - } - catch { /* IGNORE */} - } - await Context.PaginatedReply(servers, Context.Bot.CurrentUser ,null, $"Total Servers: {Context.Bot.Guilds.Count}\n " + - $"Total Members: {totalMembers}"); - } - - [Name("Blacklist")] - [Command("blacklist")] - [Description("Blacklists a server for the bot to join")] - public async Task BlacklistAsync(ulong guildId, string reason = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var blacklist = await db.Blacklists.FindAsync(guildId); - if (blacklist == null) - { - await db.Blacklists.AddAsync(new Blacklist - { - GuildId = guildId, - ResponsibleUser = Context.User.Id.RawValue, - Reason = reason - }); - await db.SaveChangesAsync(); - await Context.ReplyAsync(new LocalEmbedBuilder().Create($"Added blacklist on {guildId}!", Color.Green)); - return; - } - - blacklist.Unban = DateTimeOffset.UtcNow; - await db.SaveChangesAsync(); - await Context.ReplyAsync(new LocalEmbedBuilder().Create($"Removed blacklist on {guildId}!", Color.Green)); - } - - [Name("Evaluate")] - [Command("eval")] - [Description("Evaluates code")] - public async Task EvaluateAsync([Remainder] string rawCode) - { - var code = rawCode.GetCode(); - var sw = Stopwatch.StartNew(); - var script = CSharpScript.Create(code, RoslynExtensions.RoslynScriptOptions, typeof(RoslynCommandContext)); - var diagnostics = script.Compile(); - var compilationTime = sw.ElapsedMilliseconds; - - if (diagnostics.Any(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error)) - { - var builder = new LocalEmbedBuilder - { - Title = "Compilation Failure", - Color = Color.Red, - Description = $"Compilation took {compilationTime}ms but failed due to..." - }; - foreach (var diagnostic in diagnostics) - { - var message = diagnostic.GetMessage(); - builder.AddField(diagnostic.Id, - message.Substring(0, Math.Min(500, message.Length))); - } - - await ReplyAsync(embed: builder.Build()); - return; - } - - var context = new RoslynCommandContext(Context); - var result = await script.RunAsync(context); - sw.Stop(); - await ReplyAsync(result.ReturnValue.ToString()); - } - } -} diff --git a/Hanekawa/Bot/Modules/Premium/Mvp.cs b/Hanekawa/Bot/Modules/Premium/Mvp.cs deleted file mode 100644 index 313628e3..00000000 --- a/Hanekawa/Bot/Modules/Premium/Mvp.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Mvp; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Premium -{ - [Name("MVP")] - [Description("Premium Module. Assign most active users of the week a role.")] - [RequirePremium] - public class Mvp : HanekawaCommandModule - { - [Name("Set Channel")] - [Command("mvpchannel", "mvpc")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetAnnouncementChannelAsync(CachedTextChannel channel = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateGuildConfigAsync(Context.Guild); - if (channel == null) - { - cfg.MvpChannel = null; - await Context.ReplyAsync("Disabled MVP Announcement!"); - } - else - { - cfg.MvpChannel = channel.Id.RawValue; - await Context.ReplyAsync($"Set MVP Announcement channel to {channel.Mention} !"); - } - - await db.SaveChangesAsync(); - } - - [Name("Set Role")] - [Command("mvprole", "mvpr")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetMvpRoleAsync(CachedRole role = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateMvpConfigAsync(Context.Guild); - if (role == null) - { - cfg.RoleId = null; - await Context.ReplyAsync("Disabled MVP!"); - } - else - { - cfg.RoleId = role.Id.RawValue; - await Context.ReplyAsync($"Set MVP role to {role.Name} !"); - } - - await db.SaveChangesAsync(); - } - - [Name("MVP Reward Day")] - [Command("mvpday")] - [Description("Sets which day the MVP rewards is gonna be handed out")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetMvpDayAsync(DayOfWeek? day = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateMvpConfigAsync(Context.Guild); - if (!day.HasValue) - { - cfg.Disabled = true; - await db.SaveChangesAsync(); - await ReplyAsync("Disabled MVP service!", Color.Red); - return; - } - - if (day != cfg.Day) - { - cfg.Disabled = false; - cfg.Day = day.Value; - await db.SaveChangesAsync(); - await ReplyAsync($"Set MVP reward day to {day.Value}!", Color.Green); - return; - } - - await ReplyAsync($"Mvp reward is already set to {day.Value}!"); - } - - [Name("Force Mvp Reward")] - [Command("mvpforce")] - [Description("Force MVP rewards incase it doesn't go out")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task ForceMvpAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var guildConfig = await db.GetOrCreateGuildConfigAsync(Context.Guild); - await ReplyAsync("Executing MVP rewards..."); - await Context.ServiceProvider.GetRequiredService().Reward(guildConfig, db, true); - await ReplyAsync("Rewarded MVP users and reset MVP counter"); - } - - [Name("Opt Out")] - [Command("Optout")] - [RequiredChannel] - public async Task OptOutAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(Context.Member); - if (userData.MvpOptOut) - { - userData.MvpOptOut = false; - await Context.ReplyAsync("Re-enabled MVP counting!"); - } - else - { - userData.MvpOptOut = true; - await Context.ReplyAsync("Opted out of MVP counting!"); - } - - await db.SaveChangesAsync(); - } - } -} diff --git a/Hanekawa/Bot/Modules/Quote/Quote.cs b/Hanekawa/Bot/Modules/Quote/Quote.cs deleted file mode 100644 index 12dc86c0..00000000 --- a/Hanekawa/Bot/Modules/Quote/Quote.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.Caching; -using Hanekawa.Database; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Quote -{ - public class Quote : HanekawaCommandModule - { - private readonly CacheService _cache; - public Quote(CacheService cache) => _cache = cache; - - [Name("Quote")] - [Command("quote", "q")] - [Description("Sends a pre-defined quote")] - [RequiredChannel] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task QuoteAsync([Remainder] string key) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var quote = await db.Quotes.FindAsync(Context.Guild.Id.RawValue, key); - if (quote == null) return; - - var cache = _cache.QuoteCache.GetOrAdd(Context.Guild.Id, new MemoryCache(new MemoryCacheOptions())); - if (cache.TryGetValue(quote.Key, out var value) && (int)value == 0) - { - cache.Set(quote.Key, 1); - _cache.QuoteCache.AddOrUpdate(Context.Guild.Id, cache, (_, _) => cache); - await ReplyAsync("This quote is still on cooldown..."); - return; - } - - cache.Set(quote.Key, 0, TimeSpan.FromMinutes(1)); - _cache.QuoteCache.AddOrUpdate(Context.Guild.Id, cache, (_, _) => cache); - await ReplyAsync(quote.Message); - } - - [Name("Quote Add")] - [Command("quoteadd", "qa")] - [Description("Adds a quote with a identifier")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task QuoteAddAsync(string key, [Remainder] string message) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var entry = await db.Quotes.FindAsync(Context.Guild.Id.RawValue, key); - if (entry != null) - { - await ReplyAsync("There's already a quote with that key!\n" + - "Please use a different key", Color.Red); - return; - } - - await db.Quotes.AddAsync(new Database.Tables.Quote.Quote - { - GuildId = Context.Guild.Id.RawValue, - Key = key, - Message = message, - Added = DateTimeOffset.UtcNow, - Creator = Context.User.Id.RawValue, - LevelCap = 0, - Triggers = new List() - }); - await db.SaveChangesAsync(); - await ReplyAsync($"Added quote with key {key} !", HanaBaseColor.Lime()); - } - - [Name("Quote Remove")] - [Command("quoteremove", "qr")] - [Description("Remove a quote with a identifier")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task QuoteRemoveAsync(string key) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var entry = await db.Quotes.FindAsync(Context.Guild.Id.RawValue, key); - if (entry == null) - { - await ReplyAsync("Couldn't find a quote with that name !", Color.Red); - return; - } - - db.Quotes.Remove(entry); - await db.SaveChangesAsync(); - await ReplyAsync($"Successfully removed a quote with key {key} !", HanaBaseColor.Lime()); - } - - [Name("Quote List")] - [Command("quotelist", "ql")] - [Description("Lists all quotes")] - [RequiredChannel] - [Cooldown(1, 5, CooldownMeasure.Seconds, HanaCooldown.User)] - public async Task QuoteListAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var entries = await db.Quotes.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - var pages = new List(); - foreach (var x in entries) - { - var sb = new StringBuilder(); - var creator = Context.Guild.GetMember(x.Creator); - sb.AppendLine($"Key: {x.Key}"); - sb.AppendLine($"Msg: {x.Message.Truncate(100)}"); - sb.AppendLine(creator != null ? $"Author: {creator}" : $"Author: {x.Creator}"); - } - await Context.PaginatedReply(pages, Context.Guild, $"Quotes for {Context.Guild.Name}"); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Report/Report.cs b/Hanekawa/Bot/Modules/Report/Report.cs deleted file mode 100644 index 39b99fcf..00000000 --- a/Hanekawa/Bot/Modules/Report/Report.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Report -{ - [Name("Report")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public class Report : HanekawaCommandModule - { - private readonly ColourService _colour; - - public Report(ColourService colour) => _colour = colour; - - [Name("Report")] - [Command("report")] - [Description("Send a report to the moderator team")] - public async Task ReportGuildAsync([Remainder] string text) - { - await Context.Message.TryDeleteMessageAsync(); - if (text.IsNullOrWhiteSpace()) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - - var report = await db.CreateReport(Context.User, Context.Guild, DateTime.UtcNow); - var cfg = await db.GetOrCreateChannelConfigAsync(Context.Guild); - if (!cfg.ReportChannel.HasValue) return; - var embed = new LocalEmbedBuilder().Create(text, Context.Colour.Get(Context.Guild.Id.RawValue)) - .WithAuthor(new LocalEmbedAuthorBuilder() - { - IconUrl = Context.User.GetAvatarUrl(), - Name = Context.Member.DisplayName - }) - .WithFooter(new LocalEmbedFooterBuilder {Text = $"Report ID: {report.Id} - UserId: {Context.User.Id.RawValue}"}) - .WithTimestamp(new DateTimeOffset(DateTime.UtcNow)); - - if (Context.Message.Attachments.FirstOrDefault() != null) - embed.ImageUrl = Context.Message.Attachments.First().Url; - var msg = await Context.Guild.GetTextChannel(cfg.ReportChannel.Value).ReplyAsync(embed); - report.MessageId = msg.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create("Report sent!", Color.Green)); - } - - [Name("Respond")] - [Command("respond")] - [Description("Respond to a report that's been sent")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RespondAsync(int id, [Remainder] string text) - { - if (text.IsNullOrWhiteSpace()) return; - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - - var report = await db.Reports.FindAsync(id, Context.Guild.Id.RawValue); - var cfg = await db.GetOrCreateChannelConfigAsync(Context.Guild); - - if (report?.MessageId == null || !cfg.ReportChannel.HasValue) return; - - var msg = Context.Guild.GetTextChannel(cfg.ReportChannel.Value) - .GetMessage(report.MessageId.Value); - var embed = msg.Embeds.First().ToEmbedBuilder(); - embed.Color = Color.Orange; - embed.AddField(Context.Member.DisplayName, text); - try - { - var suggestUser = await Context.Guild.GetOrFetchMemberAsync(report.UserId) as CachedMember; - if(suggestUser != null && suggestUser.DmChannel != null) await suggestUser.DmChannel.ReplyAsync( - "Your report got a response!\n" + - "report:\n" + - $"{embed.Description.Truncate(400)}\n" + - $"Answer from {Context.User.Mention}:\n" + - $"{text}", _colour.Get(Context.Guild.Id.RawValue)); - if(suggestUser != null) - { - var dm = await suggestUser.CreateDmChannelAsync(); - await dm.ReplyAsync("Your report got a response!\n" + - "report:\n" + - $"{embed.Description.Truncate(400)}\n" + - $"Answer from {Context.User.Mention}:\n" + - $"{text}", _colour.Get(Context.Guild.Id.RawValue)); - } - } - catch - { - /*IGNORE*/ - } - - await ((IUserMessage) msg).ModifyAsync(x => x.Embed = embed.Build()); - } - - [Name("Channel")] - [Command("rc")] - [Description("Sets a channel as channel to receive reports. don't mention a channel to disable reports.")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetReportChannelAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateChannelConfigAsync(Context.Guild); - if (cfg.ReportChannel.HasValue && channel == null) - { - cfg.ReportChannel = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled report channel", Color.Green); - return; - } - - channel ??= Context.Channel as CachedTextChannel; - if (channel == null) return; - cfg.ReportChannel = channel.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"All reports will now be sent to {channel.Mention} !", - Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Settings/Boost.cs b/Hanekawa/Bot/Modules/Settings/Boost.cs deleted file mode 100644 index 447154b9..00000000 --- a/Hanekawa/Bot/Modules/Settings/Boost.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Settings -{ - public class Boost : HanekawaCommandModule - { - [Name("Set Exp Reward")] - [Command("boostexp")] - [Description("Rewards the user a certain amount of exp for boosting the server")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetBoostExpAsync(int exp = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoostConfigAsync(Context.Guild); - cfg.ExpGain = exp; - await db.SaveChangesAsync(); - await ReplyAsync($"Set experience boost reward to {exp}!", Color.Green); - } - - [Name("Set Credit Reward")] - [Command("boostcredit")] - [Description("Rewards the user a certain amount of credit for boosting the server")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetBoostCreditAsync(int credit = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoostConfigAsync(Context.Guild); - cfg.CreditGain = credit; - await db.SaveChangesAsync(); - await ReplyAsync($"Set credit boost reward to {credit}!", Color.Green); - } - - [Name("Set Special Credit Reward")] - [Command("boostscredit")] - [Description("Rewards the user a certain amount of special credit for boosting the server")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetBoostSpecialCreditAsync(int specialCredit = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoostConfigAsync(Context.Guild); - cfg.SpecialCreditGain = specialCredit; - await db.SaveChangesAsync(); - await ReplyAsync($"Set special credit boost reward to {specialCredit}!", Color.Green); - } - - [Name("Set Exp Multiplier")] - [Command("boostexpmulti")] - [Description("Sets a experience multiplier for everyone boosting to get rewarded a little extra experience every time they earn exp")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetBoostExpMultiplier(double multiplier = 1) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLevelConfigAsync(Context.Guild); - cfg.BoostExpMultiplier = multiplier; - await db.SaveChangesAsync(); - await ReplyAsync($"Set experience multiplier for boosting people to {multiplier}!", Color.Green); - } - - [Name("Announcement Channel")] - [Command("boostchannel")] - [Description("Sets a channel to announce people that boosted the server")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetAnnouncementChannelAsync(CachedTextChannel channel = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoostConfigAsync(Context.Guild); - if (channel == null) - { - cfg.ChannelId = null; - await db.SaveChangesAsync(); - await ReplyAsync($"Disabled boost announcements!", Color.Green); - return; - } - - cfg.ChannelId = channel.Id.RawValue; - await db.SaveChangesAsync(); - await ReplyAsync($"Set boost announcement channel to {channel.Mention}!", Color.Green); - } - - [Name("Force Reward")] - [Command("boostfreward")] - [Description("Force reward any existing users boosting the server")] - [RequireMemberGuildPermissions(Permission.Administrator)] - public async Task ForceBoostReward(CachedMember user = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateBoostConfigAsync(Context.Guild); - var expService = Context.ServiceProvider.GetRequiredService(); - Database.Tables.Account.Account userData; - if (user != null) - { - userData = await db.GetOrCreateUserData(user); - await expService.AddExpAsync(user, userData, cfg.ExpGain, cfg.CreditGain, db); - userData.CreditSpecial += cfg.SpecialCreditGain; - await db.SaveChangesAsync(); - await ReplyAsync($"Added boost rewards to {user.Mention}!\n" + - $"+ {cfg.ExpGain} exp\n" + - $"+ {cfg.CreditGain} credit\n" + - $"+ {cfg.SpecialCreditGain} special credit", Color.Green); - return; - } - - await Context.Channel.TriggerTypingAsync(); - var users = Context.Guild.Members.Where(x => x.Value.IsBoosting).ToList(); - for (var i = 0; i < users.Count; i++) - { - var (_, cachedMember) = users[i]; - userData = await db.GetOrCreateUserData(cachedMember); - await expService.AddExpAsync(cachedMember, userData, cfg.ExpGain, cfg.CreditGain, db); - userData.CreditSpecial += cfg.SpecialCreditGain; - await db.SaveChangesAsync(); - } - await ReplyAsync($"Added boost rewards to {users.Count} users!\n" + - $"+ {cfg.ExpGain} exp\n" + - $"+ {cfg.CreditGain} credit\n" + - $"+ {cfg.SpecialCreditGain} special credit", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Settings/Drop.cs b/Hanekawa/Bot/Modules/Settings/Drop.cs deleted file mode 100644 index 5433dc45..00000000 --- a/Hanekawa/Bot/Modules/Settings/Drop.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Services.Drop; -using Hanekawa.Database; -using Hanekawa.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Settings -{ - [Name("Drop")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - public class Drop : HanekawaCommandModule - { - private readonly DropService _drop; - public Drop(DropService drop) => _drop = drop; - - [Name("Drop")] - [Command("drop")] - [Description("Spawns a crate for people to claim. Higher reward then regular crates")] - public async Task SpawnDrop() - { - await Context.Message.TryDeleteMessageAsync(); - await _drop.SpawnAsync(Context); - } - - [Name("Emote")] - [Command("de", "dropemote")] - [Description("Changes claim emote")] - public async Task DropEmote(LocalCustomEmoji emote) - { - await _drop.ChangeEmote(Context.Guild, emote); - await Context.ReplyAsync($"Changed claim emote to {emote}"); - } - - [Name("Add")] - [Command("da", "dropadd")] - [Description("Adds a channel to be eligible for drops")] - public async Task AddDropChannel(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - channel ??= Context.Channel as CachedTextChannel; - if (channel == null) return; - try - { - await Context.Message.TryDeleteMessageAsync(); - await _drop.AddLootChannel(channel, db); - await Context.ReplyAsync($"Added {channel.Mention} to loot eligible channels.", - Color.Green); - } - catch - { - await Context.ReplyAsync($"Couldn't add {channel.Mention} to loot eligible channels.", - Color.Red); - } - } - - [Name("Remove")] - [Command("dr", "dropremove")] - [Description("Removes a channel from being eligible for drops")] - public async Task RemoveDropChannel(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - channel ??= Context.Channel as CachedTextChannel; - if (channel == null) return; - try - { - await Context.Message.TryDeleteMessageAsync(); - await _drop.RemoveLootChannel(channel, db); - await Context.ReplyAsync($"Removed {channel.Mention} from loot eligible channels.", - Color.Green); - } - catch - { - await Context.ReplyAsync($"Couldn't remove {channel.Mention} from loot eligible channels.", - Color.Red); - } - } - - [Name("List")] - [Command("dl", "droplist")] - [Description("Lists channels that are available for drops")] - public async Task ListDropChannelsAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var embed = new LocalEmbedBuilder().WithAuthor(new LocalEmbedAuthorBuilder - {Name = $"{Context.Guild.Name} Loot channels:", IconUrl = Context.Guild.GetIconUrl()}); - var list = await db.LootChannels.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - if (list.Count == 0) - { - embed.Description = "No loot channels has been added to this server"; - } - else - { - var result = new List(); - foreach (var x in list) - { - var channel = Context.Guild.GetTextChannel(x.ChannelId); - if (channel == null) continue; - result.Add(channel.Mention); - } - embed.Description = string.Join("\n", result); - } - - await Context.ReplyAsync(embed); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Settings/Ignore.cs b/Hanekawa/Bot/Modules/Settings/Ignore.cs deleted file mode 100644 index 75f9a467..00000000 --- a/Hanekawa/Bot/Modules/Settings/Ignore.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Settings -{ - [Name("Ignore")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public class Ignore : HanekawaCommandModule - { - private readonly RequiredChannel _requiredChannel; - - public Ignore(RequiredChannel requiredChannel) => _requiredChannel = requiredChannel; - - [Name("Ignore")] - [Command("ignore")] - [Description("Adds or removes a channel from ignore list")] - public async Task IgnoreChannelAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateAdminConfigAsync(Context.Guild); - channel ??= Context.Channel as CachedTextChannel; - if (channel == null) return; - var result = await _requiredChannel.AddOrRemoveChannel(channel, db); - if (result) - { - if (cfg.IgnoreAllChannels) - await Context.ReplyAsync($"Added {channel?.Mention} to the ignore list.\n" + - $"Commands are now enabled in {channel?.Mention}", - Color.Green); - else - await Context.ReplyAsync($"Added {channel?.Mention} to the ignore list.\n" + - $"Commands are now disabled in {channel?.Mention}", - Color.Green); - } - - if (!result) - { - if (cfg.IgnoreAllChannels) - await Context.ReplyAsync($"Removed {channel?.Mention} from the ignore list.\n" + - $"Commands are now disabled in {channel?.Mention}", - Color.Green); - else - await Context.ReplyAsync($"Removed {channel?.Mention} from the ignore list.\n" + - $"Commands are now enabled in {channel?.Mention}", - Color.Green); - } - } - - [Name("Toggle")] - [Command("it", "ignoretoggle")] - [Description("Toggles whether common commands is only usable in ignored channels or not")] - public async Task ToggleIgnoreChannelAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateAdminConfigAsync(Context.Guild); - if (cfg.IgnoreAllChannels) - { - cfg.IgnoreAllChannels = false; - await Context.ReplyAsync( - "Commands are now usable in all channels beside those in the ignore list."); - } - else - { - cfg.IgnoreAllChannels = true; - await Context.ReplyAsync("Commands are now only usable in channels on the list."); - } - - await db.SaveChangesAsync(); - } - - [Name("List")] - [Command("il", "ignorelist")] - [Description("Toggles whether common commands is only usable in ignored channels or not")] - public async Task ListIgnoreChannelsAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateAdminConfigAsync(Context.Guild); - var list = await db.IgnoreChannels.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - string content; - if (list.Count != 0) - { - var channels = new List(); - var toRemove = new List(); - foreach (var x in list) - try - { - var channel = Context.Guild.GetTextChannel(x.ChannelId); - if (channel == null) - { - toRemove.Add(x); - continue; - } - - channels.Add(channel.Mention); - } - catch - { - /* ignored todo: maybe handle this better? channel ignore list */ - } - - content = string.Join("\n", channels); - db.IgnoreChannels.RemoveRange(toRemove); - await db.SaveChangesAsync(); - } - else - { - content = "Commands are usable in every channel"; - } - - var title = cfg.IgnoreAllChannels - ? "Channel commands are enabled in:" - : "Channel commands are ignored in:"; - var embed = new LocalEmbedBuilder().Create(content, Context.Colour.Get(Context.Guild.Id.RawValue)) - .WithAuthor(new LocalEmbedAuthorBuilder {IconUrl = Context.Guild.GetIconUrl(), Name = title}); - await Context.ReplyAsync(embed); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Settings/Log.cs b/Hanekawa/Bot/Modules/Settings/Log.cs deleted file mode 100644 index c870bd2a..00000000 --- a/Hanekawa/Bot/Modules/Settings/Log.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Rest; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Settings -{ - [Name("Log")] - [Description("Log various actions users do to a channel of your choice so you have a better overview of the server.")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public class Log : HanekawaCommandModule - { - [Name("Join/Leave")] - [Command("logjoin")] - [Description("Logs users joining and leaving server, leave empty to disable")] - public async Task JoinLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogJoin = null; - await Context.ReplyAsync("Disabled logging of join/leave!", Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogJoin = channel.Id.RawValue; - await Context.ReplyAsync($"Set join/leave logging channel to {channel.Mention}!", Color.Green); - await db.SaveChangesAsync(); - } - - [Name("Warnings")] - [Command("logwarn")] - [Description("Logs warnings given out from the bot, leave empty to disable")] - public async Task WarnLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogWarn = null; - await Context.ReplyAsync("Disabled logging of warnings!", Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogWarn = channel.Id.RawValue; - await Context.ReplyAsync($"Set warn logging channel to {channel.Mention}!", Color.Green); - await db.SaveChangesAsync(); - } - - [Name("Messages")] - [Command("logmsgs")] - [Description("Logs deleted and updated messages, leave empty to disable")] - public async Task MessageLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogMsg = null; - await Context.ReplyAsync("Disabled logging of messages!", Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogMsg = channel.Id.RawValue; - await Context.ReplyAsync($"Set message logging channel to {channel.Mention}!", Color.Green); - await db.SaveChangesAsync(); - } - - [Name("Ban")] - [Command("logban")] - [Description("Logs users getting banned and muted, leave empty to disable")] - public async Task BanLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogBan = null; - await Context.ReplyAsync("Disabled logging of bans!", Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogBan = channel.Id.RawValue; - await Context.ReplyAsync($"Set ban logging channel to {channel.Mention}!", Color.Green); - await db.SaveChangesAsync(); - } - - [Name("User")] - [Command("loguser")] - [Description("Logs user updates, roles/username/nickname, leave empty to disable")] - public async Task UserLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogAvi = null; - await Context.ReplyAsync("Disabled logging of users!", Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogAvi = channel.Id.RawValue; - await Context.ReplyAsync($"Set user logging channel to {channel.Mention}!", Color.Green); - await db.SaveChangesAsync(); - } - - [Name("Auto-Moderator")] - [Command("logautomod")] - [Description( - "Logs activities auto moderator does. Defaults to ban log if this is disabled. Meant if automod entries should be in a different channel.\nLeave empty to disable")] - public async Task AutoModeratorLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogAutoMod = null; - await Context.ReplyAsync("Disabled separate logging of auto-moderator actions!", - Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogAutoMod = channel.Id.RawValue; - await Context.ReplyAsync($"Set auto mod log channel to {channel.Mention}!", Color.Green); - await db.SaveChangesAsync(); - } - - [Name("Voice")] - [Command("logvoice")] - [Description("Logs voice activities, join/leave/mute/deafen, leave empty to disable")] - public async Task VoiceLogAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (channel == null) - { - cfg.LogVoice = null; - await Context.ReplyAsync("Disabled logging of voice activity!", Color.Green); - await db.SaveChangesAsync(); - return; - } - - cfg.LogVoice = channel.Id.RawValue; - await Context.ReplyAsync($"Set voice activity logging channel to {channel.Mention}!", - Color.Green); - await db.SaveChangesAsync(); - } - - [Name("Reaction")] - [Command("logreaction", "logreac")] - [Description( - "Logs reaction activity, when people add or remove a message it'll be logged to specified channel. Provide no channel to disable.")] - public async Task LogReactionAsync(CachedTextChannel channel = null) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(Context.Guild); - if (!cfg.LogReaction.HasValue && channel != null) - { - var webhook = await channel.GetWebhooksAsync(); - var check = webhook.FirstOrDefault(x => x.Owner.Id != Context.Guild.CurrentMember.Id); - RestWebhook client; - if (check == null) client = await channel.CreateWebhookAsync("Hanekawa Log"); - else client = check; - // CFG Null yada yada - return; - } - if (channel == null) - { - - return; - } - - if (channel.Id.RawValue != cfg.LogReaction.Value) - { - - return; - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Settings/Settings.cs b/Hanekawa/Bot/Modules/Settings/Settings.cs deleted file mode 100644 index ba82b36a..00000000 --- a/Hanekawa/Bot/Modules/Settings/Settings.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Extensions.Interactivity; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Settings -{ - [Name("Settings")] - [Description("Server settings")] - [RequireBotGuildPermissions(Permission.EmbedLinks)] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public class Settings : HanekawaCommandModule - { - private readonly ColourService _colourService; - private readonly Services.Caching.CacheService _cacheService; - - public Settings(ColourService colourService, Services.Caching.CacheService cacheService) - { - _colourService = colourService; - _cacheService = cacheService; - } - - [Name("Add Prefix")] - [Command("addprefix", "aprefix")] - [Description("Adds a cacheService to the bot, if it doesn't already exist")] - public async Task AddPrefixAsync([Remainder] string prefix) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var config = await db.GetOrCreateGuildConfigAsync(Context.Guild); - if (config.Prefix != prefix) - { - _cacheService.AddOrUpdatePrefix(Context.Guild, prefix); - config.Prefix = prefix; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Added {prefix} as a cacheService.", Color.Green); - return; - } - await Context.ReplyAsync($"{prefix} is already a cacheService on this server.", Color.Red); - } - - [Name("Set embed color")] - [Command("embed")] - [Description("Changes the embed colour of the bot")] - public async Task SetEmbedColorAsync(Color color) - { - await Context.ReplyAsync("Would you like to change embed color to this ? (y/n)", new Color(color)); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Guild == Context.Guild && x.Message.Author == Context.User); - if (response == null) - { - await Context.ReplyAsync("Timed out...", Color.Red); - return; - } - if (response.Message.Content.ToLower() == "y" || response.Message.Content.ToLower() == "yes") - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateGuildConfigAsync(Context.Guild); - _colourService.AddOrUpdate(Context.Guild.Id.RawValue, new Color(color)); - cfg.EmbedColor = (uint)color.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Changed default embed color"); - } - else - await Context.ReplyAsync("Cancelled"); - } - - [Name("Set embed color")] - [Command("embed")] - [Description("Changes the embed colour of the bot")] - public async Task SetEmbedColorAsync(int r, int g, int b) - { - var color = new Color(r, g, b); - await Context.ReplyAsync("Would you like to change embed color to this ? (y/n)", color); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Guild == Context.Guild && x.Message.Author == Context.User); - if (response == null) - { - await Context.ReplyAsync("Timed out...", Color.Red); - return; - } - if (response.Message.Content.ToLower() == "y" || response.Message.Content.ToLower() == "yes") - await using (var db = Context.Scope.ServiceProvider.GetRequiredService()) - { - var cfg = await db.GetOrCreateGuildConfigAsync(Context.Guild); - _colourService.AddOrUpdate(Context.Guild.Id.RawValue, color); - cfg.EmbedColor = (uint)color.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Changed default embed color"); - } - else - await Context.ReplyAsync("Canceled"); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Settings/Welcome.cs b/Hanekawa/Bot/Modules/Settings/Welcome.cs deleted file mode 100644 index 734dd34b..00000000 --- a/Hanekawa/Bot/Modules/Settings/Welcome.cs +++ /dev/null @@ -1,292 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Bot.Services.ImageGen; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; -using Quartz.Util; - -namespace Hanekawa.Bot.Modules.Settings -{ - [Name("Welcome")] - [RequireBotGuildPermissions(Permission.EmbedLinks, Permission.AttachFiles)] - public class Welcome : HanekawaCommandModule - { - private readonly ImageGenerator _image; - public Welcome(ImageGenerator image) => _image = image; - - [Name("Banner Add")] - [Command("wa", "welcadd")] - [Description("Adds a welcome banner to the bot")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task AddWelcomeBannerAsync(string url, int aviSize = 60, int aviX = 10, int aviY = 10, int textSize = 33, int textX = 245, int textY = 40) - { - if (!url.IsPictureUrl()) - { - await Context.ReplyAsync("Please use direct image urls when adding pictures!\n" + - "Example: ", Color.Red); - return; - } - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var guildCfg = await db.GetOrCreateGuildConfigAsync(Context.Guild); - await Context.Channel.TriggerTypingAsync(); - var example = await _image.WelcomeBuilder(Context.Member, url, aviSize, aviX, aviY, textSize, textX, textY, guildCfg.Premium); - example.Position = 0; - var fileName = "welcomeExample.png"; - if (url.EndsWith(".gif")) fileName = "welcomeExample.gif"; - var msg = await Context.Channel.SendMessageAsync(new LocalAttachment(example, fileName), - "Do you want to add this banner? (y/N)\n" + - "You can adjust placement of avatar and text by adjust these values in the command (this is the full command with default values)\n" + - $"**Example:** wa {url.Truncate(5)} {aviSize} {aviX} {aviY} {textSize} {textX} {textY}\n" + - $"**Explained:** wa {url.Truncate(5)} PfpSize = {aviSize} PfpX = {aviX} PfpY = {aviY} TextSize = {textSize} TextX = {textX} TextY = {textY}"); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Author == Context.Member && x.Message.Guild == Context.Guild && x.Message.Channel == Context.Channel, TimeSpan.FromMinutes(2)); - if (response == null || response.Message.Content.ToLower() != "y") - { - await msg.DeleteAsync(); - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create("Aborting...", Color.Red),TimeSpan.FromSeconds(20)); - return; - } - - var data = new WelcomeBanner - { - GuildId = Context.Guild.Id.RawValue, - UploadTimeOffset = new DateTimeOffset(DateTime.UtcNow), - Uploader = Context.User.Id.RawValue, - Url = url, - IsNsfw = false - }; - await db.WelcomeBanners.AddAsync(data); - await db.SaveChangesAsync(); - await Context.ReplyAsync("Added banner to the collection!", Color.Green); - } - - [Name("Banner Remove")] - [Command("wr", "welcremove")] - [Description("Removes a welcome banner by given ID")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task RemoveWelcomeBannerAsync(int id) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var banner = - await db.WelcomeBanners.FirstOrDefaultAsync(x => x.Id == id && x.GuildId == Context.Guild.Id.RawValue); - if (banner == null) - { - await Context.ReplyAsync("Couldn\'t remove a banner with that ID.", Color.Red); - return; - } - - db.WelcomeBanners.Remove(banner); - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Removed {banner.Url} with ID {banner.Id} from the bot", - Color.Green); - } - - [Name("Banner List")] - [Command("wl", "welclist")] - [Description("Shows a paginated message of all saved banners")] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task WelcomeBannerListAsync() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var list = await db.WelcomeBanners.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - if (list.Count == 0) - { - await Context.ReplyAsync("No banners added, using default one if enabled", Color.Red); - return; - } - - var pages = new List(); - for (var i = 0; i < list.Count; i++) - { - var index = list[i]; - var strBuilder = new StringBuilder(); - strBuilder.AppendLine($"ID: {index.Id}"); - strBuilder.AppendLine($"URL: {index.Url}"); - strBuilder.AppendLine( - $"Uploader: {(await Context.Guild.GetOrFetchMemberAsync(index.Uploader)).Mention ?? $"User left server ({index.Uploader})"}"); - strBuilder.AppendLine($"Added: {index.UploadTimeOffset.DateTime}"); - pages.Add(strBuilder.ToString()); - } - - await Context.PaginatedReply(pages, Context.Guild, $"Welcome banners for {Context.Guild.Name}"); - } - - [Name("Message")] - [Command("wm", "welcmsg")] - [Description("Sets welcome message")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task WelcomeMessageAsync([Remainder] string message = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(Context.Guild); - cfg.Message = message.IsNullOrWhiteSpace() ? null : message; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Updated welcome message!", Color.Green); - } - - [Name("Channel")] - [Command("wc", "welchannel")] - [Description("Sets welcome channel, leave empty to disable")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task WelcomeChannelAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(Context.Guild); - switch (channel) - { - case null when cfg.Channel.HasValue: - cfg.Channel = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled welcome messages!", Color.Green); - break; - case null: - { - channel = Context.Channel as CachedTextChannel; - if (channel == null) return; - cfg.Channel = channel.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set welcome channel to {channel.Mention}", Color.Green); - break; - } - default: - cfg.Channel = channel.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Enabled or changed welcome channel to {channel.Mention}", Color.Green); - break; - } - } - - [Name("Auto Delete")] - [Command("wad", "welcautodel")] - [Description("A timeout for when welcome messages are automatically deleted. Leave empty to disable")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task WelcomeTimeout(TimeSpan? timeout = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(Context.Guild); - if (!cfg.TimeToDelete.HasValue && timeout == null) return; - if (timeout == null) - { - cfg.TimeToDelete = null; - await Context.ReplyAsync("Disabled auto-deletion of welcome messages!", Color.Green); - } - else - { - cfg.TimeToDelete = timeout.Value; - await Context.ReplyAsync("Enabled auto-deletion of welcome messages!\n" + - $"I will now delete the message after {timeout.Value.Humanize(2)}!", - Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Template")] - [Command("wt", "welctemplate")] - [Description("Posts the welcome template to create welcome banners from. PSD and regular png file.")] - [RequireMemberGuildPermissions(Permission.ManageMessages)] - public async Task WelcomeTemplate() - { - var embed = new LocalEmbedBuilder() - .Create( - "The PSD file contains everything that's needed to get started creating your own banners.\n" + - "Below you see a preview of how the template looks like in plain PNG format, which you can use in case you're unable to open PSD files.\n" + - "The dimension or resolution for a banner is 600px wide and 78px height (600x78)", Context.Colour.Get(Context.Guild.Id.RawValue)) - .WithTitle("Welcome template") - .WithImageUrl("https://i.imgur.com/rk5BBmf.png"); - await Context.Channel.SendMessageAsync(new LocalAttachment("Data/Welcome/WelcomeTemplate.psd", "WelcomeTemplate.psd"), null, false, embed.Build()); - } - - [Name("Banner Toggle")] - [Command("wbt", "welcbantog")] - [Description("Toggles whether welcome banners should be posted or just message")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task Welcomebanner() - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(Context.Guild); - if (cfg.Banner) - { - cfg.Banner = false; - await Context.ReplyAsync("Disabled welcome banners!", Color.Green); - } - else - { - cfg.Banner = true; - await Context.ReplyAsync("Enabled welcome banners!", Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Ignore New Account")] - [Command("wia")] - [Description("Sets if welcomes should ignore new accounts by a defined time. Disabled by default")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task WelcomeIgnoreUsers(DateTimeOffset? time = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(Context.Guild); - if (time == null) - { - cfg.IgnoreNew = null; - await Context.ReplyAsync("No longer ignoring new accounts on welcome", Color.Green); - } - else - { - cfg.IgnoreNew = time.Value; - await Context.ReplyAsync($"Now ignoring accounts that's younger than {time.Value.Humanize()}", - Color.Green); - } - - await db.SaveChangesAsync(); - } - - [Name("Welcome Reward")] - [Command("welcreward", "wreward")] - [Description("Rewards users for welcoming a new member")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - [RequirePremium] - public async Task WelcomeRewardAsync(int reward = 0) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(Context.Guild); - if (reward == 0) - { - cfg.Reward = null; - await ReplyAsync("Disabled welcome rewards!", Color.Green); - } - else - { - cfg.Reward = reward; - await ReplyAsync($"Enabled or set welcome rewards to {reward}!"); - } - - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Suggestion/Suggestion.cs b/Hanekawa/Bot/Modules/Suggestion/Suggestion.cs deleted file mode 100644 index 51205a2e..00000000 --- a/Hanekawa/Bot/Modules/Suggestion/Suggestion.cs +++ /dev/null @@ -1,195 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Suggestion -{ - [Name("Suggestion")] - [Description( - "Module for creating suggestions for a server, adds up/down votes for users to show if they think it's a good idea or not.")] - public partial class Suggestion : HanekawaCommandModule - { - [Name("Suggest")] - [Command("suggest")] - [Description("Sends a suggestion to the server, if they have it enabled")] - [RequiredChannel] - public async Task SuggestAsync([Remainder] string suggestion) - { - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (!cfg.Channel.HasValue) return; - var caseId = await db.CreateSuggestion(Context.User, Context.Guild, DateTime.UtcNow); - var embed = new LocalEmbedBuilder().Create(suggestion, Context.Colour.Get(Context.Guild.Id.RawValue)); - embed.Author = new LocalEmbedAuthorBuilder - {IconUrl = Context.User.GetAvatarUrl(), Name = Context.Member.DisplayName}; - embed.Footer = new LocalEmbedFooterBuilder {Text = $"Suggestion ID: {caseId.Id}"}; - embed.Timestamp = DateTimeOffset.UtcNow; - if (Context.Message.Attachments.Count > 0) embed.WithImageUrl(Context.Message.Attachments.First().Url); - var msg = await Context.Guild.GetTextChannel(cfg.Channel.Value).ReplyAsync(embed); - caseId.MessageId = msg.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAndDeleteAsync(null, false, - new LocalEmbedBuilder().Create("Suggestion sent!", Color.Green)); - await ApplyEmotesAsync(msg, cfg); - } - - [Name("Approve Suggestion")] - [Command("approve", "ar")] - [Description("Approves a suggestion by its Id with a optional reason")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task ApproveSuggestionAsync(int id, [Remainder] string reason = null) - { - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (!cfg.Channel.HasValue) return; - var suggestion = await db.Suggestions.FindAsync(id, Context.Guild.Id.RawValue); - if (suggestion?.MessageId == null) - { - await Context.ReplyAsync("Couldn't find a suggestion with that id.", Color.Red); - return; - } - - var msg = (IUserMessage) await Context.Guild.GetTextChannel(cfg.Channel.Value) - .GetMessageAsync(suggestion.MessageId.Value); - if (msg == null) return; - var sugstMessage = await CommentSuggestion(Context.Member, msg, reason, Color.Green); - await RespondUser(suggestion, sugstMessage, reason); - } - - [Name("Decline Suggestion")] - [Command("decline", "dr")] - [Description("Decline a suggestion by its ID with a optional reason")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task DeclineSuggestionAsync(int id, [Remainder] string reason = null) - { - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (!cfg.Channel.HasValue) return; - var suggestion = await db.Suggestions.FindAsync(id, Context.Guild.Id.RawValue); - if (suggestion?.MessageId == null) - { - await Context.ReplyAsync("Couldn't find a suggestion with that id.", Color.Red); - return; - } - - if (!(await Context.Guild.GetTextChannel(cfg.Channel.Value) - .GetMessageAsync(suggestion.MessageId.Value) is IUserMessage msg)) return; - var sugstMessage = await CommentSuggestion(Context.Member, msg, reason, Color.Red); - await RespondUser(suggestion, sugstMessage, reason); - } - - [Name("Comment Suggestion")] - [Command("Comment", "rr")] - [Description("Adds a comment onto a suggestion, usable by user suggesting and server admin")] - [RequiredChannel] - public async Task CommentSuggestionAsync(int id, [Remainder] string reason = null) - { - await Context.Message.TryDeleteMessageAsync(); - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (!cfg.Channel.HasValue) return; - var suggestion = await db.Suggestions.FindAsync(id, Context.Guild.Id.RawValue); - if (!Context.Member.Permissions.Has(Permission.ManageGuild) && - Context.User.Id.RawValue != suggestion.UserId) return; - - if (suggestion?.MessageId == null) - { - await Context.ReplyAsync("Couldn't find a suggestion with that id.", Color.Red); - return; - } - - if (!(await Context.Guild.GetTextChannel(cfg.Channel.Value) - .GetMessageAsync(suggestion.MessageId.Value) is IUserMessage msg)) return; - var sugstMessage = await CommentSuggestion(Context.Member, msg, reason); - if (Context.User.Id.RawValue != suggestion.UserId) await RespondUser(suggestion, sugstMessage, reason); - } - - private async Task ApplyEmotesAsync(IUserMessage msg, SuggestionConfig cfg) - { - LocalCustomEmoji iYes; - LocalCustomEmoji iNo; - if (LocalCustomEmoji.TryParse(cfg.EmoteYes, out var yesEmote)) - { - iYes = yesEmote; - } - else - { - LocalCustomEmoji.TryParse("<:1yes:403870491749777411>", out var defaultYes); - iYes = defaultYes; - } - - if (LocalCustomEmoji.TryParse(cfg.EmoteNo, out var noEmote)) - { - iNo = noEmote; - } - else - { - LocalCustomEmoji.TryParse("<:2no:403870492206825472>", out var defaultNo); - iNo = defaultNo; - } - - var result = new List {iYes, iNo}; - for (var i = 0; i < result.Count; i++) - { - var x = result[i]; - await msg.AddReactionAsync(x); - } - } - - private async Task CommentSuggestion(CachedMember user, IUserMessage msg, string message, - Color? color = null) - { - var embed = msg.Embeds.First().ToEmbedBuilder(); - if (color.HasValue) embed.Color = color; - embed.AddField(user.DisplayName, message); - await msg.ModifyAsync(x => x.Embed = embed.Build()); - return embed.Description; - } - - private async Task RespondUser(Database.Tables.Moderation.Suggestion suggestion, string sugst, string response) - { - try - { - var suggestUser = await Context.Guild.GetOrFetchMemberAsync(suggestion.UserId) as CachedMember; - if (suggestUser == null) return; - var embed = new LocalEmbedBuilder().Create( - $"Your suggestion got a response in {Context.Guild.Name}!\n" + - "Suggestion:\n" + - $"{sugst.Truncate(300)}\n" + - $"Answer from {Context.User}:\n" + - $"{response.Truncate(1200)}", Context.Colour.Get(Context.Guild.Id.RawValue)); - if (suggestUser.DmChannel != null) await suggestUser.DmChannel.SendMessageAsync(null, false, embed.Build()); - else - { - var dm = await suggestUser.CreateDmChannelAsync(); - await dm.SendMessageAsync(null, false, embed.Build()); - } - } - catch - { - /*IGNORE*/ - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Suggestion/SuggestionAdmin.cs b/Hanekawa/Bot/Modules/Suggestion/SuggestionAdmin.cs deleted file mode 100644 index bdf95e57..00000000 --- a/Hanekawa/Bot/Modules/Suggestion/SuggestionAdmin.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Suggestion -{ - public partial class Suggestion - { - [Name("Suggestion Channel")] - [Command("ssc", "sschannel")] - [Description( - "Sets a channel as channel to receive suggestions. don't mention a channel to disable suggestions.")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetSuggestionChannelAsync(CachedTextChannel channel = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (cfg.Channel.HasValue && channel == null) - { - cfg.Channel = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Disabled suggestion channel", Color.Green); - return; - } - - channel ??= Context.Channel as CachedTextChannel; - if (channel == null) return; - cfg.Channel = channel.Id.RawValue; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"All suggestions will now be sent to {channel.Mention} !", - Color.Green); - } - - [Name("Suggest Yes Emote")] - [Command("ssy", "ssyes")] - [Description("Set custom yes emote for suggestions")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetSuggestEmoteYesAsync(LocalCustomEmoji emote = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (emote == null) - { - cfg.EmoteYes = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Set `no` reaction to default emote", Color.Green); - return; - } - - cfg.EmoteYes = emote.MessageFormat; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set `no` reaction to {emote}", Color.Green); - } - - [Name("Suggest No Emote")] - [Command("ssn", "ssno")] - [Description("Set custom no emote for suggestions")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public async Task SetSuggestEmoteNoAsync(LocalCustomEmoji emote = null) - { - - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateSuggestionConfigAsync(Context.Guild); - if (emote == null) - { - cfg.EmoteNo = null; - await db.SaveChangesAsync(); - await Context.ReplyAsync("Set `no` reaction to default emote", Color.Green); - return; - } - - cfg.EmoteNo = emote.MessageFormat; - await db.SaveChangesAsync(); - await Context.ReplyAsync($"Set `no` reaction to {emote}", Color.Green); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Utility/AutoMessage.cs b/Hanekawa/Bot/Modules/Utility/AutoMessage.cs deleted file mode 100644 index 515c6aae..00000000 --- a/Hanekawa/Bot/Modules/Utility/AutoMessage.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Services.AutoMessage; -using Hanekawa.Database; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Hanekawa.Utility; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Utility -{ - [Name("Auto Message")] - [Description("Create a message that'll be posted automatically within a interval (ie. every hour)")] - [RequireMemberGuildPermissions(Permission.ManageGuild)] - public class AutoMessage : HanekawaCommandModule - { - private readonly AutoMessageService _service; - public AutoMessage(AutoMessageService service) => _service = service; - - [Name("Add Auto Message")] - [Description("Create a automated message with a interval (ie. 1h30m). You can have up to 3 active messages")] - [Command("amadd")] - public async Task AddAsync(string name, CachedTextChannel channel, TimeSpan interval, [Remainder] string message) - { - await Context.Channel.SendMessageAsync($"Preview of message, does this look good? (y/n)", false, - new LocalEmbedBuilder().Create(MessageUtil.FormatMessage(message, null, Context.Guild), - Context.Colour.Get(Context.Guild.Id.RawValue)).Build()); - var response = await Context.Bot.GetInteractivity().WaitForMessageAsync(x => - x.Message.Author.Id == Context.User.Id && x.Message.Channel.Id == Context.Channel.Id); - if (response == null) - { - await ReplyAsync("Abort...", Color.Red); - return; - } - - if (response.Message.Content.ToLower() != "y") - { - await ReplyAsync("Cancelling...", Color.Red); - return; - } - - await ReplyAsync(MessageUtil.FormatMessage(message, null, Context.Guild), - Context.Colour.Get(Context.Guild.Id.RawValue)); - if (await _service.AddAutoMessage(Context.Member, channel, interval, name, message)) - await ReplyAsync( - $"Succesfully added a message by name '{name}' that'll be sent every {interval.Humanize()}", - Color.Green); - else - await ReplyAsync( - $"Couldn't add, you possibly already have 3 active messages, or there's already a message with this name ({name})", - Color.Red); - } - - [Name("Remove Auto Message")] - [Description("Removes a automated message by its name")] - [Command("amremove")] - public async Task RemoveAsync(string name) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - if (_service.RemoveAutoMessage(Context.Guild.Id.RawValue, name, db)) - await ReplyAsync($"Removed auto message by the name {name} !", Color.Green); - else await ReplyAsync($"Couldn't find or remove a auto message by the name {name}", Color.Green); - } - - [Name("List Auto Messages")] - [Description("List all active automated messages (up to 3)")] - [Command("amlist")] - public async Task ListAsync() - { - var list = _service.GetList(Context.Guild.Id.RawValue); - await Context.PaginatedReply(list, Context.Guild, - $"Automated messages in {Context.Guild.Name}!"); - } - - [Name("Edit existing message with different message")] - [Description("Edit the content of a automated message by providing a new one")] - [Command("amedit")] - public async Task EditContentAsync(string name, [Remainder] string editedMessage) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - if (await _service.EditMessageAsync(Context.Guild.Id.RawValue, name, editedMessage, db)) - await ReplyAsync($"Changed message to '{editedMessage}' !", Color.Green); - else - await ReplyAsync($"Couldn't find a automated message by that name ({name}), or something went wrong...", - Color.Red); - } - - [Name("Edit existing message with different interval")] - [Description("Change the interval a message is being posted, ie. from 1hr to 3hrs")] - [Command("amedit")] - public async Task EditedIntervalAsync(string name, TimeSpan editedInterval) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - if (await _service.EditIntervalAsync(Context.Guild.Id.RawValue, name, editedInterval, db)) - await ReplyAsync($"Changed message interval to '{editedInterval.Humanize()}' !", Color.Green); - else - await ReplyAsync( - $"Couldn't find a automated message by that name ({name}), or something went wrong...", Color.Red); - } - } -} diff --git a/Hanekawa/Bot/Modules/Utility/Utility.cs b/Hanekawa/Bot/Modules/Utility/Utility.cs deleted file mode 100644 index 2703e517..00000000 --- a/Hanekawa/Bot/Modules/Utility/Utility.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Hanekawa.Shared.Command; -using NLog; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Utility -{ - public class Utility : HanekawaCommandModule - { - private readonly HttpClient _httpClient; - public Utility(HttpClient httpClient) => _httpClient = httpClient; - - [Name("Add Emote")] - [Command("emote")] - [Description("Add(s) emotes to the server by its name")] - [RequireMemberGuildPermissions(Permission.ManageEmojis)] - public async Task AddEmotesAsync(params LocalCustomEmoji[] emote) - { - var list = new StringBuilder(); - foreach (var x in emote) - { - try - { - var stream = new MemoryStream(); - var stream1 = await _httpClient.GetStreamAsync(x.GetUrl()); - await stream1.FlushAsync(); - await stream1.CopyToAsync(stream); - stream.Position = 0; - try - { - var result = await Context.Guild.CreateEmojiAsync(stream, x.Name); - list.Append($"{result} "); - } - catch(Exception e) - { - LogManager.GetCurrentClassLogger().Log(LogLevel.Error, e, $"{e.Message}\n{e.StackTrace}"); - var result = await Context.Guild.CreateEmojiAsync(stream, "ToBeRenamed"); - list.Append($"{result} (rename)"); - } - } - catch (Exception e) - { - LogManager.GetCurrentClassLogger().Log(LogLevel.Error, e, $"{e.Message}\n{e.StackTrace}"); - // Ignore - } - } - await ReplyAsync($"Added emotes\n {list}"); - } - - [Name("Avatar")] - [Command("avatar", "pfp")] - [Description("Sends a embeded message containing the profile picture of user provided, if empty it'll return your own.")] - [RequiredChannel] - [RequireBotGuildPermissions(Permission.EmbedLinks, Permission.SendMessages)] - public async Task AvatarAsync(CachedMember user = null) - { - user ??= Context.Member; - var restUser = await user.Guild.GetMemberAsync(user.Id); - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder {Name = $"{user}"}, - Title = "Avatar URL", - Url = restUser.GetAvatarUrl(), - ImageUrl = restUser.GetAvatarUrl(), - Color = Context.Colour.Get(user.Guild.Id.RawValue) - }; - await ReplyAsync(embed); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Modules/Utility/VoiceRole.cs b/Hanekawa/Bot/Modules/Utility/VoiceRole.cs deleted file mode 100644 index 0ef0c44e..00000000 --- a/Hanekawa/Bot/Modules/Utility/VoiceRole.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Tables; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Modules.Utility -{ - [Name("Voice Role")] - [Description("Link a voice channel to a role. Usable to make the text channel only visible while in VC")] - public class VoiceRole : HanekawaCommandModule - { - [Name("Add/Remove Linked Role")] - [Command("vrole")] - [Description("Adds channel user is connected to for the specified role")] - [RequireMemberGuildPermissions(Permission.ManageChannels)] - public async Task AddAsync([Remainder] CachedRole role) - { - if (Context.Member.VoiceState == null) - { - await ReplyAsync("Couldn't link role to a VC as you didn't supply a VC or connected to one", Color.Red); - return; - } - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var check = await db.VoiceRoles.FindAsync(Context.Guild.Id.RawValue, - Context.Member.VoiceState.ChannelId.RawValue); - if (check == null) - { - await db.VoiceRoles.AddAsync(new VoiceRoles - { - GuildId = Context.Guild.Id.RawValue, - VoiceId = Context.Member.VoiceState.ChannelId.RawValue, - RoleId = role.Id.RawValue - }); - await db.SaveChangesAsync(); - await ReplyAsync($"Added {role.Mention} as a VC role for {Context.Member.VoiceChannel.Name}!", - Color.Green); - return; - } - - if (Context.Member.VoiceState.ChannelId.RawValue != check.VoiceId) - { - check.VoiceId = Context.Member.VoiceState.ChannelId.RawValue; - await db.SaveChangesAsync(); - await ReplyAsync($"Changed voice channel role to {Context.Member.VoiceChannel.Name}!", Color.Green); - return; - } - - db.VoiceRoles.Remove(check); - await db.SaveChangesAsync(); - await ReplyAsync($"Removed {role.Mention} as VC role for {Context.Member.VoiceChannel.Name}!", Color.Green); - } - - [Name("Add/Remove Linked Role")] - [Command("vrole")] - [Description("Adds voice channel and role as linked")] - [RequireMemberGuildPermissions(Permission.ManageChannels)] - public async Task AddAsync(CachedRole role, [Remainder] CachedVoiceChannel vc) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var check = await db.VoiceRoles.FindAsync(Context.Guild.Id.RawValue, - vc.Id.RawValue); - if (check == null) - { - await db.VoiceRoles.AddAsync(new VoiceRoles - { - GuildId = Context.Guild.Id.RawValue, - VoiceId = vc.Id.RawValue, - RoleId = role.Id.RawValue - }); - await db.SaveChangesAsync(); - await ReplyAsync($"Added {role.Mention} as a VC role for {vc.Name}!", - Color.Green); - return; - } - - if (vc.Id.RawValue != check.VoiceId) - { - check.VoiceId = vc.Id.RawValue; - await db.SaveChangesAsync(); - await ReplyAsync($"Changed voice channel role to {vc.Name}!", Color.Green); - return; - } - - db.VoiceRoles.Remove(check); - await db.SaveChangesAsync(); - await ReplyAsync($"Removed {Context.Guild.GetRole(check.RoleId)} as VC role for {vc.Name}!", Color.Green); - } - - [Name("Remove Linked Role")] - [Command("vrr")] - [Description("Removes a role linked to mentioned voice channel")] - [RequireMemberGuildPermissions(Permission.ManageChannels)] - public async Task RemoveAsync([Remainder] CachedVoiceChannel channel) - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var check = await db.VoiceRoles.FindAsync(Context.Guild.Id.RawValue, - channel.Id.RawValue); - if (check == null) - { - await ReplyAsync("No role linked to this voice channel!", Color.Red); - return; - } - - db.VoiceRoles.Remove(check); - await db.SaveChangesAsync(); - await ReplyAsync($"Removed {Context.Guild.GetRole(check.RoleId).Mention} from {channel.Name}!"); - } - - [Name("List Voice-Text linked channels")] - [Command("vtlist")] - [Description("Lists all voice channels linked to a role")] - [RequireMemberGuildPermissions(Permission.ManageChannels)] - public async Task ListAsync() - { - await using var db = Context.Scope.ServiceProvider.GetRequiredService(); - var list = await db.VoiceRoles.Where(x => x.GuildId == Context.Guild.Id.RawValue).ToListAsync(); - if (list == null || list.Count == 0) - { - await Context.ReplyAsync("No voice channel roles added"); - return; - } - - var result = new List(); - foreach (var x in list) - { - var role = Context.Guild.GetRole(x.RoleId) ?? - Context.Guild.Roles.FirstOrDefault(z => z.Key.RawValue == x.RoleId).Value; - var vc = Context.Guild.GetVoiceChannel(x.VoiceId) ?? - Context.Guild.VoiceChannels.FirstOrDefault(e => e.Key.RawValue == x.VoiceId).Value; - if (role != null) result.Add($"**{vc.Name} -> {role.Mention}**"); - } - - await Context.PaginatedReply(result, Context.Guild, - $"Voice Channel Roles {Context.Guild.Name}"); - } - } -} diff --git a/Hanekawa/Bot/Preconditions/RequirePremium.cs b/Hanekawa/Bot/Preconditions/RequirePremium.cs deleted file mode 100644 index 5dcca027..00000000 --- a/Hanekawa/Bot/Preconditions/RequirePremium.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading.Tasks; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Preconditions -{ - public class RequirePremium : CheckAttribute - { - public override async ValueTask CheckAsync(CommandContext _) - { - if (!(_ is DiscordCommandContext context)) return CheckResult.Unsuccessful("wrong right context."); - if(context.Guild == null) return CheckResult.Unsuccessful("Needs to be executed in a guild!"); - using var scope = context.ServiceProvider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateGuildConfigAsync(context.Guild); - return cfg.Premium - ? CheckResult.Successful - : CheckResult.Unsuccessful("Command is only available for premium servers!"); - } - } -} diff --git a/Hanekawa/Bot/Preconditions/RequiredChannel.cs b/Hanekawa/Bot/Preconditions/RequiredChannel.cs deleted file mode 100644 index f86073f8..00000000 --- a/Hanekawa/Bot/Preconditions/RequiredChannel.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System.Collections.Concurrent; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Qmmands; - -namespace Hanekawa.Bot.Preconditions -{ - public class RequiredChannel : CheckAttribute, INService - { - private static ConcurrentDictionary IgnoreAll { get; } - = new ConcurrentDictionary(); - - private static ConcurrentDictionary> ChannelEnable { get; } - = new ConcurrentDictionary>(); - - public override async ValueTask CheckAsync(CommandContext _) - { - if (!(_ is DiscordCommandContext context)) return CheckResult.Unsuccessful("woopsie command context wrong :)"); - if (context.Member.Permissions.ManageGuild) - return CheckResult.Successful; - - var ignoreAll = IgnoreAll.TryGetValue(context.Guild.Id.RawValue, out var status); - if (!ignoreAll) status = await UpdateIgnoreAllStatus(context); - - var pass = status ? EligibleChannel(context, true) : EligibleChannel(context); - - switch (pass) - { - case true: - return CheckResult.Successful; - case false: - return CheckResult.Unsuccessful("Not a eligible channel"); - } - } - - public async Task AddOrRemoveChannel(CachedTextChannel channel, DbService db) - { - var check = await db.IgnoreChannels.FindAsync(channel.Guild.Id.RawValue, channel.Id.RawValue); - if (check != null) - { - var ch = ChannelEnable.GetOrAdd(channel.Guild.Id.RawValue, new ConcurrentDictionary()); - ch.TryRemove(channel.Id.RawValue, out _); - - var result = - await db.IgnoreChannels.FirstOrDefaultAsync(x => - x.GuildId == channel.Guild.Id.RawValue && x.ChannelId == channel.Id.RawValue); - db.IgnoreChannels.Remove(result); - await db.SaveChangesAsync(); - return false; - } - else - { - var ch = ChannelEnable.GetOrAdd(channel.Guild.Id.RawValue, new ConcurrentDictionary()); - ch.TryAdd(channel.Id.RawValue, true); - - var data = new IgnoreChannel - { - GuildId = channel.Guild.Id.RawValue, - ChannelId = channel.Id.RawValue - }; - await db.IgnoreChannels.AddAsync(data); - await db.SaveChangesAsync(); - return true; - } - } - - private static async Task UpdateIgnoreAllStatus(DiscordCommandContext context) - { - using var scope = context.ServiceProvider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateAdminConfigAsync(context.Guild); - return cfg.IgnoreAllChannels; - } - - private static bool EligibleChannel(DiscordCommandContext context, bool ignoreAll = false) - { - // True = command passes - // False = command fails - var ch = ChannelEnable.GetOrAdd(context.Guild.Id.RawValue, new ConcurrentDictionary()); - var ignore = ch.TryGetValue(context.Channel.Id.RawValue, out var status); - if (!ignore) ignore = DoubleCheckChannel(context); - return !ignoreAll ? !ignore : ignore; - } - - private static bool DoubleCheckChannel(DiscordCommandContext context) - { - using var scope = context.ServiceProvider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - var check = db.IgnoreChannels.Find(context.Guild.Id.RawValue, context.Channel.Id.RawValue); - if (check == null) return false; - var ch = ChannelEnable.GetOrAdd(context.Guild.Id.RawValue, new ConcurrentDictionary()); - ch.TryAdd(context.Channel.Id.RawValue, true); - return true; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Prefix/GuildPrefix.cs b/Hanekawa/Bot/Prefix/GuildPrefix.cs deleted file mode 100644 index cec4f2cd..00000000 --- a/Hanekawa/Bot/Prefix/GuildPrefix.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot.Prefixes; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Prefix -{ - public class GuildPrefix : IPrefixProvider, INService - { - private readonly IServiceProvider _provider; - - public GuildPrefix(IServiceProvider provider) => _provider = provider; - - public async ValueTask> GetPrefixesAsync(CachedUserMessage message) - { - if (message.Channel is IPrivateChannel) return null; - var prefixService = _provider.GetRequiredService(); - var prefixCollection = prefixService.GetCollection(message.Guild.Id); - if (prefixCollection != null) - { - prefixService.IsMentionPrefix(message, out _); - return prefixCollection; - } - - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateGuildConfigAsync(message.Guild.Id); - var prefix = new StringPrefix(cfg.Prefix); - prefixService.AddOrUpdatePrefix(message.Guild, cfg.Prefix); - prefixService.IsMentionPrefix(message, out _); - var collection = prefixService.GetCollection(message.Guild.Id); - - return collection.Contains(prefix) - ? collection - : null; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Achievement/AchievementData.cs b/Hanekawa/Bot/Services/Achievement/AchievementData.cs deleted file mode 100644 index 5df6264d..00000000 --- a/Hanekawa/Bot/Services/Achievement/AchievementData.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Hanekawa.Bot.Services.Achievement -{ - public partial class AchievementService - { - private const int Special = 1; - private const int Voice = 2; - private const int Level = 3; - private const int Drop = 4; - private const int PvP = 5; - private const int PvE = 6; - private const int Fun = 7; - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Achievement/AchievementService.cs b/Hanekawa/Bot/Services/Achievement/AchievementService.cs deleted file mode 100644 index 4ab77791..00000000 --- a/Hanekawa/Bot/Services/Achievement/AchievementService.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Achievement; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using LogLevel = NLog.LogLevel; - -namespace Hanekawa.Bot.Services.Achievement -{ - public partial class AchievementService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly IServiceProvider _provider; - - public AchievementService(Hanekawa client, IServiceProvider provider) - { - _client = client; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - - _client.MessageReceived += MessageCount; - } - - private Task MessageCount(MessageReceivedEventArgs e) - { - _ = Task.Run(async () => - { - var msg = e.Message; - if (!(msg.Author is CachedMember user)) return; - if (user.IsBot) return; - if (msg.Content.Length != 1499) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var achievements = await db.Achievements.Where(x => x.TypeId == Fun).ToListAsync(); - if (achievements == null) return; - - if (achievements.Any(x => x.Requirement == msg.Content.Length && x.Once)) - { - var achieve = - achievements.FirstOrDefault(x => x.Requirement == msg.Content.Length && x.Once); - if (achieve != null) - { - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = Fun, - UserId = user.Id.RawValue, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - } - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Achievement Service) Error for {user.Id.RawValue} in {user.Guild.Id.RawValue} for Message Count - {e.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Achievement/DropAchievement.cs b/Hanekawa/Bot/Services/Achievement/DropAchievement.cs deleted file mode 100644 index 30c3a3fa..00000000 --- a/Hanekawa/Bot/Services/Achievement/DropAchievement.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Achievement; -using Microsoft.EntityFrameworkCore; -using NLog; - -namespace Hanekawa.Bot.Services.Achievement -{ - public partial class AchievementService - { - public async Task DropClaim(CachedMember user, DbService db) - { - var achievements = await db.Achievements.Where(x => x.TypeId == Drop).ToListAsync(); - var progress = await db.GetOrCreateAchievementProgress(user, Drop); - - if (progress == null) return; - if (achievements == null) return; - var progCount = progress.Count + 1; - if (achievements.Any(x => x.Requirement == progCount && !x.Once)) - { - var achieve = achievements.FirstOrDefault(x => x.Requirement == progCount && !x.Once); - if (achieve == null) return; - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = Drop, - Achievement = achieve, - UserId = user.Id.RawValue - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - else - { - var below = achievements.Where(x => x.Requirement < progCount && !x.Once).ToList(); - if (below.Count != 0) - { - var unlocked = await db.AchievementUnlocks.Where(x => x.UserId == user.Id.RawValue).ToListAsync(); - foreach (var x in below) - { - if (unlocked.Any(y => y.AchievementId == x.AchievementId)) continue; - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = Drop, - UserId = user.Id.RawValue, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - - progress.Count++; - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Achievement/GameAchievement.cs b/Hanekawa/Bot/Services/Achievement/GameAchievement.cs deleted file mode 100644 index 4ad15b72..00000000 --- a/Hanekawa/Bot/Services/Achievement/GameAchievement.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Achievement; -using Microsoft.EntityFrameworkCore; -using NLog; - -namespace Hanekawa.Bot.Services.Achievement -{ - public partial class AchievementService - { - public async Task PvpKill(CachedMember user, DbService db) => await PvpKill(user.Id.RawValue, user.Guild.Id.RawValue, db).ConfigureAwait(false); - public async Task PvpKill(ulong userId, ulong guildId, DbService db) - { - var achievements = await db.Achievements.Where(x => x.TypeId == PvP && !x.Once).ToListAsync(); - var progress = await db.GetOrCreateAchievementProgress(userId, PvP); - if (progress == null) return; - - if (achievements == null) return; - - if (achievements.Any(x => x.Requirement == progress.Count + 1 && !x.Once)) - { - var achieve = achievements.First(x => x.Requirement == progress.Count + 1); - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = PvP, - UserId = userId, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {userId} scored {achieve.Name} in {guildId}"); - } - else - { - var below = achievements.Where(x => x.Requirement < progress.Count + 1).ToList(); - if (below.Count != 0) - { - var unlocked = await db.AchievementUnlocks.Where(x => x.UserId == userId).ToListAsync(); - foreach (var x in below) - { - if (unlocked.Any(y => y.AchievementId == x.AchievementId)) continue; - - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = PvP, - UserId = userId, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - - progress.Count += 1; - await db.SaveChangesAsync(); - } - - public async Task PveKill(CachedMember user, DbService db) - { - var achievements = await db.Achievements.Where(x => x.TypeId == PvE && !x.Once).ToListAsync(); - var progress = await db.GetOrCreateAchievementProgress(user.Id.RawValue, PvE); - if (progress == null) return; - if (achievements == null) return; - - var progCount = progress.Count + 1; - - if (achievements.Any(x => x.Requirement == progCount)) - { - var achieve = achievements.First(x => x.Requirement == progCount); - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = PvE, - UserId = user.Id.RawValue, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - else - { - var below = achievements.Where(x => x.Requirement < progCount).ToList(); - if (below.Count != 0) - { - var unlocked = await db.AchievementUnlocks.Where(x => x.UserId == user.Id.RawValue).ToListAsync(); - foreach (var x in below) - { - if (unlocked.Any(y => y.AchievementId == x.AchievementId)) continue; - - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = PvE, - UserId = user.Id.RawValue, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - - progress.Count = progCount; - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Achievement/LevelAchievement.cs b/Hanekawa/Bot/Services/Achievement/LevelAchievement.cs deleted file mode 100644 index b516707b..00000000 --- a/Hanekawa/Bot/Services/Achievement/LevelAchievement.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Database.Tables.Achievement; -using Microsoft.EntityFrameworkCore; -using NLog; - -namespace Hanekawa.Bot.Services.Achievement -{ - public partial class AchievementService - { - public async Task ServerLevel(CachedMember user, Account userData, DbService db) - { - var achievements = - await db.Achievements.Where(x => x.TypeId == Level && !x.Once && !x.Global).ToListAsync(); - if (achievements == null || achievements.Count == 0) return; - var unlocked = await db.AchievementUnlocks.Where(x => x.UserId == user.Id.RawValue).ToListAsync(); - if (achievements.Any(x => x.Requirement == userData.Level)) - { - var achieve = achievements.First(x => x.Requirement == userData.Level); - var check = unlocked.FirstOrDefault(x => x.Achievement == achieve); - if (check != null) return; - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = Level, - UserId = user.Id.RawValue, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - else - { - var belowAchieves = achievements - .Where(x => x.Requirement < userData.Level).ToList(); - if (belowAchieves.Count > 0) - { - foreach (var x in belowAchieves) - { - if (unlocked.Any(y => y.AchievementId == x.AchievementId)) continue; - - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = Level, - UserId = user.Id.RawValue, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - } - - public async Task GlobalLevel(CachedMember user, AccountGlobal userData, DbService db) - { - var achievements = await db.Achievements - .Where(x => x.TypeId == Level && !x.Once && x.Global).ToListAsync(); - if (achievements == null || achievements.Count == 0) return; - - if (achievements.Any(x => x.Requirement == userData.Level)) - { - var achieve = achievements.First(x => x.Requirement == userData.Level); - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = Level, - UserId = user.Id.RawValue, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - else - { - var belowAchieves = achievements.Where(x => x.Requirement < userData.Level).ToList(); - if (belowAchieves.Count > 0) - { - var unlocked = await db.AchievementUnlocks.Where(x => x.UserId == user.Id.RawValue).ToListAsync(); - foreach (var x in belowAchieves) - { - if (unlocked.Any(y => y.AchievementId == x.AchievementId)) continue; - - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = Level, - UserId = user.Id.RawValue, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Achievement/VoiceAchievement.cs b/Hanekawa/Bot/Services/Achievement/VoiceAchievement.cs deleted file mode 100644 index 569d98ae..00000000 --- a/Hanekawa/Bot/Services/Achievement/VoiceAchievement.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Achievement; -using Microsoft.EntityFrameworkCore; -using NLog; - -namespace Hanekawa.Bot.Services.Achievement -{ - public partial class AchievementService - { - public async Task TotalTime(CachedMember user, TimeSpan time, DbService db) - { - var achievements = await db.Achievements.Where(x => x.TypeId == Voice && x.AchievementNameId == 15) - .ToListAsync(); - var progress = await db.GetOrCreateAchievementProgress(user, Voice); - if (achievements == null || achievements.Count == 0) return; - if (progress == null) return; - - var totalTime = Convert.ToInt32(time.TotalMinutes); - var progCount = progress.Count + totalTime; - if (achievements.Any(x => x.Requirement == progCount && !x.Once)) - { - var achieve = achievements.FirstOrDefault(x => - x.Requirement == progCount && x.Once == false); - if (achieve != null) - { - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = Voice, - UserId = user.Id.RawValue, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - } - else - { - var below = achievements.Where(x => x.Requirement < progCount && !x.Once).ToList(); - if (below.Count != 0) - { - var unlocked = await db.AchievementUnlocks.Where(x => x.TypeId == Voice).ToListAsync(); - foreach (var x in below) - { - if (unlocked.Any(y => y.AchievementId == x.AchievementId)) continue; - - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = Voice, - UserId = user.Id.RawValue, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - - progress.Count = progCount; - await db.SaveChangesAsync(); - } - - public async Task TimeAtOnce(CachedMember user, TimeSpan time, DbService db) - { - var achievements = await db.Achievements.Where(x => x.TypeId == Voice).ToListAsync(); - if (achievements == null || achievements.Count == 0) return; - - var totalTime = Convert.ToInt32(time.TotalMinutes); - if (achievements.Any(x => x.Requirement == totalTime && x.AchievementNameId == 8)) - { - var achieve = achievements.First(x => x.Requirement == totalTime && x.Once); - var unlockCheck = await db.AchievementUnlocks.FirstOrDefaultAsync(x => - x.AchievementId == achieve.AchievementId && x.UserId == user.Id.RawValue); - if (unlockCheck != null) return; - - var data = new AchievementUnlock - { - AchievementId = achieve.AchievementId, - TypeId = Voice, - UserId = user.Id.RawValue, - Achievement = achieve - }; - await db.AchievementUnlocks.AddAsync(data); - await db.SaveChangesAsync(); - - _log.Log(LogLevel.Info, $"(Achievement Service) {user.Id.RawValue} scored {achieve.Name} in {user.Guild.Id.RawValue}"); - } - else - { - var below = achievements.Where(x => x.Requirement < totalTime).ToList(); - var unlock = await db.AchievementUnlocks.Where(x => x.UserId == user.Id.RawValue && x.TypeId == Voice) - .ToListAsync(); - foreach (var x in below) - { - if (unlock.Any(y => y.AchievementId == x.AchievementId)) continue; - - var data = new AchievementUnlock - { - AchievementId = x.AchievementId, - TypeId = Level, - UserId = user.Id.RawValue, - Achievement = x - }; - await db.AchievementUnlocks.AddAsync(data); - } - - await db.SaveChangesAsync(); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Administration/BlacklistService.cs b/Hanekawa/Bot/Services/Administration/BlacklistService.cs deleted file mode 100644 index 14c492a2..00000000 --- a/Hanekawa/Bot/Services/Administration/BlacklistService.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Administration -{ - public class BlacklistService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly IServiceProvider _provider; - - public BlacklistService(Hanekawa client, IServiceProvider provider) - { - _client = client; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - - _client.JoinedGuild += BlacklistCheck; - } - - private Task BlacklistCheck(JoinedGuildEventArgs e) - { - _ = Task.Run(async () => - { - var guild = e.Guild; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var check = await db.Blacklists.FindAsync(guild.Id.RawValue); - if (check == null) return; - await guild.LeaveAsync(); - _log.Log(LogLevel.Info, $"Left {guild.Id.RawValue} as the server is blacklisted"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Blacklist Service) Error for {guild.Id.RawValue} - {e.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Administration/Mute/MuteService.cs b/Hanekawa/Bot/Services/Administration/Mute/MuteService.cs deleted file mode 100644 index 5bfad031..00000000 --- a/Hanekawa/Bot/Services/Administration/Mute/MuteService.cs +++ /dev/null @@ -1,206 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Bot.Services.Logging; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Database.Tables.Moderation; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Administration.Mute -{ - public partial class MuteService : INService, IRequired - { - private readonly Hanekawa _client; - - private readonly OverwritePermissions _denyOverwrite - = new OverwritePermissions(ChannelPermissions.None, new ChannelPermissions(34880)); - private readonly NLog.Logger _log; - private readonly ColourService _colour; - private readonly LogService _logService; - private readonly IServiceProvider _provider; - - public MuteService(Hanekawa client, LogService logService, IServiceProvider provider, ColourService colour) - { - _client = client; - _logService = logService; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - _colour = colour; - - _client.MemberJoined += MuteCheck; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - foreach (var x in db.MuteTimers) - { - try - { - var after = x.Time - TimeSpan.FromMinutes(2) <= DateTime.UtcNow - ? TimeSpan.FromMinutes(2) - : x.Time - DateTime.UtcNow; - StartUnMuteTimer(x.GuildId, x.UserId, after); - } - catch (Exception e) - { - db.Remove(x); - _log.Log(NLog.LogLevel.Error, e, $"(Mute Service) Couldn't create unmute timer in {x.GuildId} for {x.UserId}"); - } - } - db.SaveChanges(); - } - - private Task MuteCheck(MemberJoinedEventArgs e) - { - if (e.Member.IsBot) return Task.CompletedTask; - _ = Task.Run(async () => - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var check = await db.MuteTimers.FindAsync(e.Member.Id.RawValue, e.Member.Guild.Id.RawValue); - if (check == null) return; - if(!await Mute(e.Member, db)) return; - var muteTimers = _unMuteTimers.GetOrAdd(e.Member.Guild.Id.RawValue, new ConcurrentDictionary()); - if (muteTimers.TryGetValue(e.Member.Id, out _)) return; - var after = check.Time - TimeSpan.FromMinutes(2) <= DateTime.UtcNow - ? TimeSpan.FromMinutes(2) - : check.Time - DateTime.UtcNow; - StartUnMuteTimer(e.Member.Guild.Id.RawValue, e.Member.Id.RawValue, after); - }); - return Task.CompletedTask; - } - - public async Task Mute(CachedMember user, DbService db) - { - var role = await GetMuteRoleAsync(user.Guild, db); - var check = await user.TryAddRoleAsync(role as CachedRole); - if (!check) return false; - _ = ApplyPermissions(user.Guild, role); - await user.TryMute(); - _log.Log(NLog.LogLevel.Info, $"(Mute service) Muted {user.Id.RawValue} in {user.Guild.Id.RawValue}"); - return true; - } - - public async Task UnMuteUser(CachedMember user, DbService db) - { - await StopUnMuteTimerAsync(user.Guild.Id.RawValue, user.Id.RawValue, db); - await user.TryUnMute(); - _log.Log(NLog.LogLevel.Info, $"(Mute service) Unmuted {user.Id.RawValue} in {user.Guild.Id.RawValue}"); - return await user.TryRemoveRoleAsync(await GetMuteRoleAsync(user.Guild, db) as CachedRole); - } - - public async Task TimedMute(CachedMember user, CachedMember staff, TimeSpan after, DbService db, - string reason) - { - await Mute(user, db).ConfigureAwait(false); - var unMuteAt = DateTime.UtcNow + after; - var muteCheck = await db.MuteTimers.FindAsync(user.Id.RawValue, user.Guild.Id.RawValue); - if (muteCheck == null) - { - await db.MuteTimers.AddAsync(new MuteTimer - { - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Time = unMuteAt - }); - } - else - { - muteCheck.Time = unMuteAt; - } - await db.SaveChangesAsync(); - StartUnMuteTimer(user.Guild.Id.RawValue, user.Id.RawValue, after); - await _logService.Mute(user, staff, reason, after, db); - await NotifyUser(user, after); - _log.Log(NLog.LogLevel.Info, $"(Mute service) {staff.Id.RawValue} muted {user.Id.RawValue} in {user.Guild.Id.RawValue} for {after.Humanize(2)}"); - return true; - } - - public async Task GetMuteTime(CachedMember user, DbService db) - { - var warns = await db.Warns.Where(x => - x.GuildId == user.Guild.Id.RawValue && - x.UserId == user.Id.RawValue && - x.Type == WarnReason.Muted && - x.Time >= DateTime.UtcNow.AddDays(-30)).ToListAsync(); - return warns == null || warns.Count == 0 - ? TimeSpan.FromHours(1) - : TimeSpan.FromHours(warns.Count + 2); - } - - private async Task NotifyUser(CachedMember user, TimeSpan duration) - { - try - { - await user.SendMessageAsync(null, false, - new LocalEmbedBuilder().Create($"You've been muted in {user.Guild.Name} for {duration.Humanize()}", _colour.Get(user.Guild.Id.RawValue)).Build()); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, "Couldn't DM user"); - } - } - - private async Task GetMuteRoleAsync(CachedGuild guild, DbService db) - { - var cfg = await db.GetOrCreateAdminConfigAsync(guild); - var role = !cfg.MuteRole.HasValue - ? await CreateRole(guild, cfg, db) - : guild.GetRole(cfg.MuteRole.Value) ?? await CreateRole(guild, cfg, db); - return role; - } - - private static async Task CreateRole(CachedGuild guild, AdminConfig cfg, DbService db) - { - var role = guild.Roles.FirstOrDefault(x => x.Value.Name.ToLower() == "mute" && x.Value.Position < guild.CurrentMember.Hierarchy).Value as IRole; - if (role == null) - { - var cRole = await guild.CreateRoleAsync(x => - { - x.Name = "mute"; - x.Permissions = Optional.Empty; - x.IsHoisted = false; - x.IsMentionable = false; - x.Color = new Optional(Color.DarkRed); - }); - role = cRole; - } - cfg.MuteRole = role.Id.RawValue; - await db.SaveChangesAsync(); - return role; - } - - private async Task ApplyPermissions(CachedGuild guild, IRole role) - { - for (var i = 0; i < guild.TextChannels.Count; i++) - { - var x = guild.TextChannels.ElementAt(i); - if (x.Value.Overwrites.Select(z => z.Permissions).Contains(_denyOverwrite)) continue; - try - { - await x.Value.TryApplyPermissionOverwriteAsync(new LocalOverwrite(role, _denyOverwrite)) - .ConfigureAwait(false); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Mute service) Couldn't apply permission overwrite in {x.Value.Guild.Id.RawValue} in channel {x.Key}"); - } - - await Task.Delay(200).ConfigureAwait(false); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Administration/Mute/Timers.cs b/Hanekawa/Bot/Services/Administration/Mute/Timers.cs deleted file mode 100644 index 042de52e..00000000 --- a/Hanekawa/Bot/Services/Administration/Mute/Timers.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace Hanekawa.Bot.Services.Administration.Mute -{ - public partial class MuteService - { - private readonly ConcurrentDictionary> _unMuteTimers - = new ConcurrentDictionary>(); - - private void StartUnMuteTimer(ulong guildId, ulong userId, TimeSpan duration) - { - try - { - var unMuteTimers = _unMuteTimers.GetOrAdd(guildId, new ConcurrentDictionary()); - var toAdd = new Timer(async _ => - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - try - { - var guild = _client.GetGuild(guildId); - if (guild == null) - { - await RemoveTimerFromDbAsync(guildId, userId, db); - return; - } - var user = await guild.GetOrFetchMemberAsync(userId); - if (user == null) - { - await RemoveTimerFromDbAsync(guildId, userId, db); - return; - } - await UnMuteUser(user as CachedMember, db); - } - catch (Exception e) - { - await RemoveTimerFromDbAsync(guildId, userId, db); - _log.Log(NLog.LogLevel.Error, e, - $"(Mute Service) Error for {userId} in {guildId} for UnMute - {e.Message}"); - } - }, null, duration, Timeout.InfiniteTimeSpan); - - unMuteTimers.AddOrUpdate(userId, key => toAdd, (key, old) => - { - old.Dispose(); - return toAdd; - }); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Mute Service) Couldn't create unmute timer in {guildId} for {userId}"); - } - } - - private async Task StopUnMuteTimerAsync(ulong guildId, ulong userId, DbService db) - { - await RemoveTimerFromDbAsync(guildId, userId, db); - if (!_unMuteTimers.TryGetValue(guildId, out var unMuteTimers)) return; - if (!unMuteTimers.TryRemove(userId, out var removed)) return; - await removed.DisposeAsync(); - } - - private static async Task RemoveTimerFromDbAsync(ulong guildId, ulong userId, DbService db) - { - var data = await db.MuteTimers.FirstOrDefaultAsync(x => x.GuildId == guildId && x.UserId == userId); - if (data == null) return; - db.MuteTimers.Remove(data); - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Administration/Warning/WarnService.cs b/Hanekawa/Bot/Services/Administration/Warning/WarnService.cs deleted file mode 100644 index 0cc33407..00000000 --- a/Hanekawa/Bot/Services/Administration/Warning/WarnService.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Bot.Services.Logging; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Moderation; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using Quartz; -using Quartz.Util; - -namespace Hanekawa.Bot.Services.Administration.Warning -{ - public partial class WarnService : INService, IJob - { - private readonly NLog.Logger _log; - private readonly LogService _logService; - private readonly ColourService _colourService; - private readonly IServiceProvider _provider; - - public WarnService(LogService logService, ColourService colourService, IServiceProvider provider) - { - _logService = logService; - _log = LogManager.GetCurrentClassLogger(); - _colourService = colourService; - _provider = provider; - } - - public Task Execute(IJobExecutionContext context) => VoidWarning(); - - private async Task VoidWarning() - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - await db.Warns.Where(x => x.Time.AddDays(7).Date <= DateTime.UtcNow.Date) - .ForEachAsync(x => x.Valid = false); - await db.SaveChangesAsync(); - } - - public async Task AddWarn(DbService db, CachedMember user, CachedMember staff, string reason, - WarnReason warnType, - bool notify = false, TimeSpan? muteTime = null) - { - var number = await db.Warns.CountAsync(x => x.GuildId == user.Guild.Id.RawValue); - await db.Warns.AddAsync(new Warn - { - Id = number + 1, - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Moderator = staff.Id.RawValue, - MuteTimer = muteTime, - Reason = reason, - Time = DateTime.UtcNow, - Type = warnType, - Valid = true - }); - await db.SaveChangesAsync(); - await NotifyUser(user, staff, warnType, reason, muteTime); - await _logService.Warn(user, staff, reason, db); - _log.Log(LogLevel.Info, $"(Warn Service) Warned {user.Id.RawValue} in {user.Guild.Id.RawValue}"); - } - - private async Task NotifyUser(CachedMember user, IMentionable staff, WarnReason type, string reason, - TimeSpan? duration = null) - { - try - { - if (reason.IsNullOrWhiteSpace()) reason = "No reason provided"; - if (!(user.DmChannel is IDmChannel dm)) dm = await user.CreateDmChannelAsync(); - var content = new StringBuilder(); - content.AppendLine($"You've been {type} in {user.Guild.Name} by {staff.Mention}"); - content.AppendLine($"Reason: {reason.ToLower()}"); - var embed = new LocalEmbedBuilder().Create(content.ToString(), _colourService.Get(user.Guild.Id.RawValue)); - if (duration != null) embed.AddField("Duration", $"{duration.Value.Humanize(2)} ({duration.Value})"); - await dm.SendMessageAsync(null, false, embed.Build()); - } - catch(Exception e) - { - _log.Log(LogLevel.Warn, e, $"(Warn Service) Couldn't direct message {user.Id.RawValue}, privacy settings?"); - /* IGNORE, maybe I shouldn't ignore this ? handle what kind of exception is thrown, if user has dms closed, ignore else log it*/ - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Administration/Warning/Warnlog.cs b/Hanekawa/Bot/Services/Administration/Warning/Warnlog.cs deleted file mode 100644 index 6ed301ee..00000000 --- a/Hanekawa/Bot/Services/Administration/Warning/Warnlog.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Humanizer; -using Microsoft.EntityFrameworkCore; - -namespace Hanekawa.Bot.Services.Administration.Warning -{ - public partial class WarnService - { - public async Task GetSimpleWarnlogAsync(CachedMember user, DbService db) - { - var userdata = await db.GetOrCreateUserData(user); - var roleList = (from x in user.Roles where x.Value.Name != "@everyone" select x.Value.Name).ToList(); - var roles = string.Join(", ", roleList); - var warnings = await GetWarnings(user, db); - var content = "**⮞ User Information**\n" + - $"Created: {user.CreatedAt.Humanize(DateTimeOffset.UtcNow)} ({user.CreatedAt})\n" + - "\n" + - "**⮞ Member Information**\n" + - $"Joined: {user.JoinedAt.Humanize(DateTimeOffset.UtcNow)} ({user.JoinedAt})\n" + - $"Roles: {roles}\n" + - "\n" + - "**⮞ Activity**\n" + - $"Last Message: {userdata.LastMessage.Humanize()} \n" + - $"First Message: {userdata.FirstMessage.Humanize()} \n" + - "\n" + - "**⮞ Session**\n" + - $"Amount: {userdata.Sessions}\n" + - $"Time: {userdata.StatVoiceTime.Humanize(2)} ({userdata.StatVoiceTime})"; - var embed = new LocalEmbedBuilder() - .Create(content, _colourService.Get(user.Guild.Id.RawValue)); - embed.Author = new LocalEmbedAuthorBuilder - {IconUrl = user.GetAvatarUrl(), Name = $"{user.Name}#{user.Discriminator} ({user.Id.RawValue})"}; - foreach (var x in warnings) embed.AddField(x); - return embed; - } - - public static async Task> GetFullWarnlogAsync(CachedMember user, DbService db) - { - var userdata = await db.GetOrCreateUserData(user); - var warns = await db.Warns.Where(x => x.GuildId == user.Guild.Id.RawValue && x.UserId == user.Id.RawValue).ToListAsync(); - var roleList = (from x in user.Roles where x.Value.Name != "@everyone" select x.Value.Name).ToList(); - var roles = string.Join(", ", roleList); - var result = new List - { - "**⮞ User Information**\n" + - $"Created: {user.CreatedAt.Humanize(DateTimeOffset.UtcNow)} ({user.CreatedAt})\n", - "**⮞ Member Information**\n" + - $"Joined: {user.JoinedAt.Humanize(DateTimeOffset.UtcNow)} ({user.JoinedAt})\n" + - $"Roles: {roles}\n" - }; - if (userdata.FirstMessage != null) - result.Add("**⮞ Activity**\n" + - $"Last Message: {userdata.LastMessage.Humanize()}\n" + - $"First Message: {userdata.FirstMessage.Value.Humanize()}\n"); - else - result.Add("**⮞ Activity**\n" + - $"Last Message: {userdata.LastMessage.Humanize()}\n" + - $"First Message: {user.JoinedAt.Humanize()}\n"); - result.Add("**⮞ Voice Session**\n" + - $"Amount: {userdata.Sessions}\n" + - $"Time: {userdata.StatVoiceTime.Humanize(2)} ({userdata.StatVoiceTime})\n"); - result.Add("**⮞ Warnings**\n" + - $"Active Warnings: {warns.Count(x => x.Valid)}\n" + - $"Inactive Warnings: {warns.Count(x => !x.Valid)}\n" + - $"Total: {warns.Count}\n" + - "Next pages contain specific warnings"); - foreach (var x in warns) - { - var input = $"**⮞ {x.Id} - {x.Type}**\n" + - $"Moderator: {(await user.Guild.GetOrFetchMemberAsync(x.Moderator)).Mention ?? $"{x.Id}"}\n" + - $"Reason: {x.Reason}\n"; - if (x.MuteTimer.HasValue) - input += $"Mute duration: {x.MuteTimer.Value.Humanize(2)} ({x.MuteTimer.Value})\n"; - input += $"Date: {x.Time.Humanize()} ({x.Time})"; - result.Add(input); - } - - return result; - } - - private static async Task> GetWarnings(CachedMember user, DbService db) - { - var result = new List(); - var list = await db.Warns.Where(x => x.GuildId == user.Guild.Id.RawValue && x.UserId == user.Id.RawValue && x.Valid) - .ToListAsync(); - var count = list.Count; - if (count > 10) count = 10; - for (var i = 0; i < count; i++) - { - var x = list[i]; - var input = $"Moderator: {(await user.Guild.GetOrFetchMemberAsync(x.Moderator)).Mention ?? $"{x.Id}"}\n" + - $"Reason: {x.Reason}\n"; - if (x.MuteTimer.HasValue) - input += $"Mute duration: {x.MuteTimer.Value.Humanize(2)} ({x.MuteTimer.Value})\n"; - input += $"Date: {x.Time.Humanize()} ({x.Time})"; - result.Add(new LocalEmbedFieldBuilder - { Name = $"Warn ID: {x.Id} - {x.Type}", IsInline = true, Value = input.Truncate(999)} ); - } - - return result; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Anime/SimulCastService.cs b/Hanekawa/Bot/Services/Anime/SimulCastService.cs deleted file mode 100644 index 5e10fd75..00000000 --- a/Hanekawa/Bot/Services/Anime/SimulCastService.cs +++ /dev/null @@ -1,139 +0,0 @@ -using System; -using System.Linq; -using System.ServiceModel.Syndication; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using NLog; - -namespace Hanekawa.Bot.Services.Anime -{ - public class SimulCastService : BackgroundService, INService, IRequired - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly IServiceProvider _provider; - private readonly ColourService _colourService; - - private const string RssFeed = "https://www.crunchyroll.com/rss/anime?lang=enGB"; - private string _lastItem; - - public SimulCastService(Hanekawa client, IServiceProvider provider, ColourService colourService) - { - _client = client; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - _colourService = colourService; - } - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - try - { - using (var reader = XmlReader.Create(RssFeed)) - { - var feed = SyndicationFeed.Load(reader).Items.FirstOrDefault(); - if (feed != null) - { - _lastItem = feed.Id; - } - } - } - catch - { - // ignored - } - - while (stoppingToken.IsCancellationRequested) - { - try - { - using var reader = XmlReader.Create(RssFeed); - var feed = SyndicationFeed.Load(reader).Items.FirstOrDefault(); - feed = SyndicationFeed.Load(reader).Items.FirstOrDefault(); - if (feed == null) return; - if (feed.Id == _lastItem) return; - feed.Id = _lastItem; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var premiumList = await db.GuildConfigs.Where(x => x.Premium).ToListAsync(cancellationToken: stoppingToken).ConfigureAwait(false); - for (var i = 0; i < premiumList.Count; i++) - { - var x = premiumList[i]; - try - { - var data = new AnimeData - { - Title = feed.Title.Text, - Time = feed.PublishDate - }; - var url = feed.Links.FirstOrDefault(); - if (url != null) data.Url = url.Uri.AbsoluteUri; - await PostAsync(x, data); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Anime Cast Service) Unable to post to {x.GuildId}"); - } - } - - await db.SaveChangesAsync(stoppingToken); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, "(Anime Cast Service) Error reading feed"); - } - await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken); - } - } - - private async Task PostAsync(GuildConfig cfg, AnimeData data) - { - try - { - if (!cfg.AnimeAirChannel.HasValue) return; - var guild = _client.GetGuild(cfg.GuildId); - if (guild == null) return; - _log.Log(LogLevel.Info, $"Posting anime event to {guild.Name}"); - var channel = guild.GetTextChannel(cfg.AnimeAirChannel.Value); - if (channel == null) - { - cfg.AnimeAirChannel = null; - return; - } - await channel.ReplyAsync(BuildEmbed(data, cfg.GuildId)); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Anime Simulcast) Error for {cfg.GuildId} - {e.Message}"); - } - } - - private LocalEmbedBuilder BuildEmbed(AnimeData data, ulong guild) - { - var embed = new LocalEmbedBuilder() - .Create(null, _colourService.Get(guild)) - .WithAuthor(new LocalEmbedAuthorBuilder {Name = "New Episode Available!"}) - .WithTitle($"{data.Title}") - .WithUrl(data.Url) - .WithTimestamp(data.Time); - return embed; - } - } - - public class AnimeData - { - public string Title { get; set; } - public string Url { get; set; } - public DateTimeOffset Time { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/AutoMessage/AutoMessageService.cs b/Hanekawa/Bot/Services/AutoMessage/AutoMessageService.cs deleted file mode 100644 index 172d2bd0..00000000 --- a/Hanekawa/Bot/Services/AutoMessage/AutoMessageService.cs +++ /dev/null @@ -1,262 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Hanekawa.Utility; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.AutoMessage -{ - public class AutoMessageService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly IServiceProvider _provider; - private readonly ColourService _colour; - private readonly NLog.Logger _log; - private readonly ConcurrentDictionary> _timers = new ConcurrentDictionary>(); - - public AutoMessageService(Hanekawa client, IServiceProvider provider, ColourService colour, InternalLogService log) - { - _client = client; - _provider = provider; - _colour = colour; - _log = LogManager.GetCurrentClassLogger(); - - _client.LeftGuild += ClearMessages; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - foreach (var x in db.AutoMessages.ToList()) - { - var timers = _timers.GetOrAdd(x.GuildId, new ConcurrentDictionary()); - timers.TryAdd(x.Name, new Timer(async _ => - { - var guild = _client.GetGuild(x.GuildId); - if (guild == null) - { - timers.TryRemove(x.Name, out var toDispose); - if (toDispose != null) await toDispose.DisposeAsync(); - RemoveFromDb(x.GuildId, x.Name); - return; - } - var channel = guild.GetTextChannel(x.ChannelId); - if (channel == null) - { - timers.TryRemove(x.Name, out var toDispose); - if (toDispose != null) await toDispose.DisposeAsync(); - RemoveFromDb(x.GuildId, x.Name); - return; - } - await channel.SendMessageAsync(null, false, - new LocalEmbedBuilder().Create(x.Message, _colour.Get(x.GuildId)).Build()); - }, null, new TimeSpan(0, (60 - DateTime.UtcNow.Minute), 0), x.Interval)); - } - } - - private Task ClearMessages(LeftGuildEventArgs e) - { - _ = Task.Run(async () => - { - if (!_timers.TryGetValue(e.Guild.Id.RawValue, out var timers)) return; - foreach (var x in timers.Values) - { - try - { - await x.DisposeAsync(); - } - catch - { /* IGNORE */} - } - - _timers.TryRemove(e.Guild.Id.RawValue, out _); - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var toRemove = await db.AutoMessages.Where(x => x.GuildId == e.Guild.Id.RawValue).ToListAsync(); - db.AutoMessages.RemoveRange(toRemove); - await db.SaveChangesAsync(); - }); - return Task.CompletedTask; - } - - public async Task AddAutoMessage(CachedMember user, CachedTextChannel channel, TimeSpan interval, string name, string message) - { - var timers = _timers.GetOrAdd(user.Guild.Id.RawValue, new ConcurrentDictionary()); - if (timers.Count >= 3) return false; - var timer = CreateTimer(channel, new TimeSpan(0, (60 - DateTime.UtcNow.Minute), 0), interval, message, user.Guild.Id.RawValue, name); - if (timers.TryAdd(name, timer)) - { - await AddToDatabase(user, channel, interval, name, message); - return true; - } - await timer.DisposeAsync(); - return false; - } - - public bool RemoveAutoMessage(ulong guildId, string name, DbService db) - { - if (!_timers.TryGetValue(guildId, out var timers)) return false; - if (!timers.TryRemove(name, out var timer)) return false; - timer?.Dispose(); - return RemoveFromDb(guildId, name, db); - } - - public List GetList(ulong guildId) - { - var timers = _timers.GetOrAdd(guildId, new ConcurrentDictionary()); - var result = new List(); - if (timers.IsEmpty) return null; - foreach (var (name, timer) in timers) - { - var sb = new StringBuilder(); - sb.AppendLine($"Name: {name}\n" + - $"Interval: {timer}"); - sb.AppendLine(); - result.Add(sb.ToString()); - } - return result; - } - - public async Task EditMessageAsync(ulong guildId, string name, string newMessage, DbService db) - { - try - { - var timers = _timers.GetOrAdd(guildId, new ConcurrentDictionary()); - if (!timers.TryGetValue(name, out var timer)) return false; - var dbTimer = await db.AutoMessages.FindAsync(guildId, name); - if (dbTimer == null) - { - await timer.DisposeAsync(); - return false; - } - - dbTimer.Message = newMessage; - var newTimer = CreateTimer(_client.GetGuild(guildId).GetTextChannel(dbTimer.ChannelId), - new TimeSpan(0, (60 - DateTime.UtcNow.Minute), 0), - dbTimer.Interval, newMessage, guildId, name); - timers.AddOrUpdate(name, newTimer, (s, _) => newTimer); - await db.SaveChangesAsync(); - return true; - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Auto Message Service) Couldn't edit message for existing timer for {guildId}"); - return false; - } - } - - public async Task EditIntervalAsync(ulong guildId, string name, TimeSpan newInterval, DbService db) - { - var timers = _timers.GetOrAdd(guildId, new ConcurrentDictionary()); - if (!timers.TryGetValue(name, out var timer)) return false; - var dbTimer = await db.AutoMessages.FindAsync(guildId, name); - if (dbTimer == null) - { - await timer.DisposeAsync(); - return false; - } - - dbTimer.Interval = newInterval; - var change = timer.Change(new TimeSpan(0, (60 - DateTime.UtcNow.Minute), 0), newInterval); - if (change) await db.SaveChangesAsync(); - return change; - } - - private Timer CreateTimer(CachedTextChannel channel, TimeSpan firstPost, TimeSpan interval, string message, - ulong guildId, string name) => - new Timer(async _ => - { - var timers = _timers.GetOrAdd(guildId, new ConcurrentDictionary()); - var guild = _client.GetGuild(guildId); - if (guild == null) - { - timers.TryRemove(name, out var toDispose); - if (toDispose != null) await toDispose.DisposeAsync(); - RemoveFromDb(guildId, name); - return; - } - - var txt = guild.GetTextChannel(channel.Id.RawValue); - if (txt == null) - { - timers.TryRemove(name, out var toDispose); - if (toDispose != null) await toDispose.DisposeAsync(); - RemoveFromDb(guildId, name); - return; - } - - await channel.SendMessageAsync(null, false, - new LocalEmbedBuilder().Create(MessageUtil.FormatMessage(message, null, txt.Guild), _colour.Get(guildId)).Build()); - }, null, firstPost, interval); - - private async Task AddToDatabase(CachedMember user, CachedTextChannel channel, TimeSpan interval, string name, string message) - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - await db.AutoMessages.AddAsync(new Database.Tables.AutoMessage.AutoMessage - { - GuildId = user.Guild.Id.RawValue, - Creator = user.Id.RawValue, - ChannelId = channel.Id.RawValue, - Name = name, - Message = message, - Interval = interval - }); - await db.SaveChangesAsync(); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Auto Message Service) Couldn't save auto message to database for {user.Guild.Id.RawValue}"); - throw; - } - } - - private bool RemoveFromDb(ulong guildId, string name, DbService db) - { - try - { - var toRemove = db.AutoMessages.Find(guildId, name); - if (toRemove == null) return false; - db.AutoMessages.Remove(toRemove); - db.SaveChanges(); - return true; - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Auto Message Service) Couldn't remove {name} from {guildId}"); - return false; - } - } - - private bool RemoveFromDb(ulong guildId, string name) - { - try - { - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - var toRemove = db.AutoMessages.Find(guildId, name); - if (toRemove == null) return false; - db.AutoMessages.Remove(toRemove); - db.SaveChanges(); - return true; - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Auto Message Service) Couldn't remove {name} from {guildId}"); - return false; - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/AutoModerator/AutoModService.cs b/Hanekawa/Bot/Services/AutoModerator/AutoModService.cs deleted file mode 100644 index 02bae95f..00000000 --- a/Hanekawa/Bot/Services/AutoModerator/AutoModService.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Bot.Services.Administration.Mute; -using Hanekawa.Bot.Services.Logging; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.AutoModerator -{ - public class AutoModService - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly LogService _logService; - private readonly MuteService _muteService; - private readonly IServiceProvider _provider; - - public AutoModService(Hanekawa client, LogService logService, MuteService muteService, IServiceProvider provider) - { - _client = client; - _logService = logService; - _muteService = muteService; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - - //_client.MessageReceived += MessageLength; - //_client.MessageReceived += InviteFilter; - } - - private Task InviteFilter(MessageReceivedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Message.Channel is CachedTextChannel channel)) return; - if (!(e.Message.Author is CachedMember user)) return; - if (user.IsBot) return; - if (user.Permissions.ManageGuild) return; - if (!e.Message.Content.IsDiscordInvite(out var invite)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateAdminConfigAsync(user.Guild); - if (!cfg.FilterInvites) return; - await e.Message.TryDeleteMessagesAsync(); - await _muteService.Mute(user, db); - await _logService.Mute(user, user.Guild.CurrentMember, $"Invite link - {invite.Truncate(80)}", - db); - - _log.Log(LogLevel.Info, $"(Automod) Deleted message from {user.Id.RawValue} in {user.Guild.Id.RawValue}. reason: Invite link ({invite})"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Automod) Error in {channel.Guild.Id.RawValue} for Invite link - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task MessageLength(MessageReceivedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Message.Channel is CachedTextChannel channel)) return; - if (!(e.Message.Author is CachedMember user)) return; - if (user.IsBot) return; - if (user.Permissions.ManageMessages) return; - var message = e.Message; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateAdminConfigAsync(user.Guild); - if (!cfg.FilterMsgLength.HasValue) return; - if (message.Content.Length < cfg.FilterMsgLength.Value) return; - await message.TryDeleteMessagesAsync(); - - _log.Log(LogLevel.Info, $"(Automod) Deleted message from {user.Id.RawValue} in {user.Guild.Id.RawValue}. reason: Message length ({message.Content.Length})"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Automod) Error in {channel.Guild.Id.RawValue} for Message Length - {e.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Board/BoardData.cs b/Hanekawa/Bot/Services/Board/BoardData.cs deleted file mode 100644 index d3f87812..00000000 --- a/Hanekawa/Bot/Services/Board/BoardData.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Collections.Concurrent; -using Disqord; -using Microsoft.Extensions.Caching.Memory; - -#nullable enable - -namespace Hanekawa.Bot.Services.Board -{ - public partial class BoardService - { - private static readonly ConcurrentDictionary ReactionEmote - = new ConcurrentDictionary(); - - private static readonly ConcurrentDictionary ReactionMessages - = new ConcurrentDictionary(); - - private static int GetReactionAmount(CachedGuild guild, IMessage msg) - { - var messages = ReactionMessages.GetOrAdd(guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - var check = messages.TryGetValue(msg.Id.RawValue, out var result); - if (check) - { - var amount = (int) result; - messages.Set(msg.Id.RawValue, amount, TimeSpan.FromDays(1)); - return amount; - } - - return 0; - } - - private static void IncreaseReactionAmount(CachedGuild guild, IMessage msg) - { - var messages = ReactionMessages.GetOrAdd(guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - var check = messages.TryGetValue(msg.Id.RawValue, out var result); - if (check) - { - var amount = (int) result; - messages.Set(msg.Id.RawValue, amount + 1, TimeSpan.FromDays(1)); - return; - } - - messages.Set(msg.Id.RawValue, 1, TimeSpan.FromDays(1)); - } - - private static void DecreaseReactionAmount(CachedGuild guild, IMessage msg) - { - var messages = ReactionMessages.GetOrAdd(guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - var check = messages.TryGetValue(msg.Id.RawValue, out var result); - if (!check) return; - var amount = (int) result; - if (amount - 1 <= 0) - messages.Remove(msg.Id.RawValue); - else - messages.Set(msg.Id.RawValue, amount - 1, TimeSpan.FromDays(1)); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Board/BoardEmote.cs b/Hanekawa/Bot/Services/Board/BoardEmote.cs deleted file mode 100644 index 4e49e851..00000000 --- a/Hanekawa/Bot/Services/Board/BoardEmote.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; - -namespace Hanekawa.Bot.Services.Board -{ - public partial class BoardService - { - public void SetBoardEmote(CachedGuild guild, string emote) => - ReactionEmote.AddOrUpdate(guild.Id.RawValue, emote, (key, value) => emote); - - public static async Task GetEmote(CachedGuild guild, DbService db) - { - var check = ReactionEmote.TryGetValue(guild.Id.RawValue, out var emoteString); - if (!check) - { - var cfg = await db.GetOrCreateBoardConfigAsync(guild); - if (LocalCustomEmoji.TryParse(cfg.Emote, out var dbEmote)) - { - ReactionEmote.TryAdd(guild.Id.RawValue, dbEmote.MessageFormat); - return dbEmote; - } - - cfg.Emote = null; - await db.SaveChangesAsync(); - return new LocalEmoji("U+2B50"); - } - - return LocalCustomEmoji.TryParse(emoteString, out var emote) ? (IEmoji) emote : new LocalEmoji("U+2B50"); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Board/BoardService.cs b/Hanekawa/Bot/Services/Board/BoardService.cs deleted file mode 100644 index 6ef63af3..00000000 --- a/Hanekawa/Bot/Services/Board/BoardService.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Disqord.Rest; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Board -{ - public partial class BoardService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly IServiceProvider _provider; - - public BoardService(Hanekawa client, IServiceProvider provider) - { - _client = client; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - - _client.ReactionAdded += ReactionAddedAsync; - _client.ReactionRemoved += ReactionRemovedAsync; - _client.ReactionsCleared += ReactionsClearedAsync; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - foreach (var x in db.BoardConfigs) ReactionEmote.TryAdd(x.GuildId, x.Emote ?? "⭐"); - } - - private Task ReactionAddedAsync(ReactionAddedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Channel is CachedTextChannel ch)) return; - if (ch.IsNsfw) return; - if (!(e.User.Value is CachedMember user)) return; - if (user.IsBot) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var emote = await GetEmote(user.Guild, db); - if (!e.Emoji.Equals(emote)) return; - var cfg = await db.GetOrCreateBoardConfigAsync(ch.Guild); - if (!cfg.Channel.HasValue) return; - - var stat = await db.GetOrCreateBoard(ch.Guild, e.Message.Value); - var giver = await db.GetOrCreateUserData(user); - var receiver = await db.GetOrCreateUserData(e.Message.Value.Author as CachedMember); - receiver.StarReceived++; - giver.StarGiven++; - stat.StarAmount++; - await db.SaveChangesAsync(); - IncreaseReactionAmount(user.Guild, e.Message.Value); - if (GetReactionAmount(user.Guild, e.Message.Value) >= 4 && !stat.Boarded.HasValue) - { - stat.Boarded = new DateTimeOffset(DateTime.UtcNow); - await db.SaveChangesAsync(); - await SendMessageAsync(user, e.Message.Value as CachedUserMessage, cfg); - } - _log.Log(LogLevel.Info, $"(Board Service) {user.Id.RawValue} added a reaction in {user.Guild.Id.RawValue}"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Board Service) Error in {ch.Guild.Id.RawValue} for Reaction Added - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task ReactionRemovedAsync(ReactionRemovedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Channel is CachedTextChannel ch)) return; - if (ch.IsNsfw) return; - if (!(e.User.Value is CachedMember user)) return; - if (user.IsBot) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var emote = await GetEmote(user.Guild, db); - if (!e.Emoji.Equals(emote)) return; - var stat = await db.GetOrCreateBoard(ch.Guild, e.Message.Value); - var giver = await db.GetOrCreateUserData(user); - var receiver = await db.GetOrCreateUserData(e.Message.Value.Author as CachedMember); - receiver.StarReceived--; - giver.StarGiven--; - stat.StarAmount--; - await db.SaveChangesAsync(); - DecreaseReactionAmount(user.Guild, e.Message.Value); - _log.Log(LogLevel.Info, $"(Board Service) {user.Id.RawValue} removed a reaction in {user.Guild.Id.RawValue}"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Board Service) Error in {ch.Guild.Id.RawValue} for Reaction Removed - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task ReactionsClearedAsync(ReactionsClearedEventArgs e) - { - _ = Task.Run(() => - { - if (!(e.Channel is CachedTextChannel ch)) return; - var msgCheck = ReactionMessages.TryGetValue(ch.Guild.Id.RawValue, out var messages); - if (!msgCheck) return; - if (messages.TryGetValue(e.Message.Id.RawValue, out _)) messages.Remove(e.Message.Id.RawValue); - }); - return Task.CompletedTask; - } - - private static async Task SendMessageAsync(CachedMember rctUser, CachedUserMessage msg, BoardConfig cfg) - { - var user = msg.Author as CachedMember; - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder - { - Name = $"{user?.DisplayName ?? msg.Author.Name} (Jump!)", - IconUrl = user?.GetAvatarUrl() ?? msg.Author.GetAvatarUrl() - }, - Color = user?.Roles.OrderByDescending(x => x.Value.Position) - .FirstOrDefault(x => x.Value.Color != null && x.Value.Color.Value != 0).Value.Color, - Description = msg.Content, - Footer = new LocalEmbedFooterBuilder {Text = msg.Channel.Name}, - Timestamp = msg.CreatedAt - }; - if (msg.Attachments.Count > 0) embed.ImageUrl = msg.Attachments.First().Url; - if (!cfg.Channel.HasValue) return null; - embed.AddField("Original", $"[Jump!]({msg.JumpUrl})"); - var channel = rctUser.Guild.GetTextChannel(cfg.Channel.Value); - return await channel.SendMessageAsync(null, false, embed.Build()); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Boost/BoostService.cs b/Hanekawa/Bot/Services/Boost/BoostService.cs deleted file mode 100644 index 2551b26e..00000000 --- a/Hanekawa/Bot/Services/Boost/BoostService.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Bot.Services.Economy; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Hanekawa.Utility; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using Quartz; - -namespace Hanekawa.Bot.Services.Boost -{ - public class BoostService : IRequired, INService, IJob - { - private readonly Hanekawa _client; - private readonly ExpService _exp; - private readonly IServiceProvider _provider; - private readonly NLog.Logger _log; - private readonly ColourService _colour; - private readonly CurrencyService _currency; - - public BoostService(Hanekawa client, IServiceProvider provider, ExpService exp, ColourService colour, CurrencyService currency) - { - _client = client; - _provider = provider; - _exp = exp; - _log = LogManager.GetCurrentClassLogger(); - _colour = colour; - _currency = currency; - - _client.MemberUpdated += BoostCheck; - } - - private Task BoostCheck(MemberUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - if (!e.OldMember.IsBoosting && e.NewMember.IsBoosting) await StartedBoostingAsync(e.NewMember); - if (e.OldMember.IsBoosting && !e.NewMember.IsBoosting) await EndedBoostingAsync(e.NewMember); - }); - return Task.CompletedTask; - } - - private async Task StartedBoostingAsync(CachedMember user) - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(user); - var config = await db.GetOrCreateBoostConfigAsync(user.Guild); - await _exp.AddExpAsync(user, userData, config.ExpGain, config.CreditGain, db); - if (config.SpecialCreditGain > 0) userData.CreditSpecial += config.SpecialCreditGain; - await db.SaveChangesAsync(); - if (config.ChannelId.HasValue) - { - var channel = user.Guild.GetTextChannel(config.ChannelId.Value); - if (channel != null) - { - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder - { - Name = $"{user.DisplayName} Boosted the server!", - IconUrl = user.GetAvatarUrl() - }, - Description = MessageUtil.FormatMessage(config.Message, user, user.Guild), - ThumbnailUrl = user.GetAvatarUrl() - }; - await channel.SendMessageAsync(null, false, embed.Build(), LocalMentions.NoEveryone); - } - } - - var logCfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!logCfg.LogAvi.HasValue) return; - var logChannel = user.Guild.GetTextChannel(logCfg.LogAvi.Value); - if (logChannel == null) return; - var logEmbed = new LocalEmbedBuilder - { - Title = "Started Boosting", - Description = $"{user.Mention} has started boosting the server!", - Color = _colour.Get(user.Guild.Id.RawValue), - Timestamp = DateTimeOffset.UtcNow, - Footer = new LocalEmbedFooterBuilder - { - Text = $"Username: {user} ({user.Id})", - IconUrl = user.GetAvatarUrl() - } - }; - await logChannel.SendMessageAsync(null, false, logEmbed.Build(), LocalMentions.NoEveryone); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Boost Service) Error for start boosting in {user.Guild.Id.RawValue} for {user.Id.RawValue} - {e.Message}"); - } - } - - private async Task EndedBoostingAsync(CachedMember user) - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var logCfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!logCfg.LogAvi.HasValue) return; - var channel = user.Guild.GetTextChannel(logCfg.LogAvi.Value); - if (channel == null) return; - var embed = new LocalEmbedBuilder - { - Title = "Stopped Boosting", - Description = $"{user.Mention} has stopped boosting the server!", - Color = _colour.Get(user.Guild.Id.RawValue), - Timestamp = DateTimeOffset.UtcNow, - Footer = new LocalEmbedFooterBuilder - { - Text = $"User: {user} ({user.Id})", - IconUrl = user.GetAvatarUrl() - } - }; - await channel.SendMessageAsync(null, false, embed.Build(), LocalMentions.NoEveryone); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Boost Service) Error for end boosting in {user.Guild.Id.RawValue} for {user.Id.RawValue} - {e.Message}"); - } - } - - public Task Execute(IJobExecutionContext context) - { - _ = Reward(); - return Task.CompletedTask; - } - - private async Task Reward() - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var configs = await db.BoostConfigs.ToListAsync(); - for (var i = 0; i < configs.Count; i++) - { - var x = configs[i]; - try - { - var guild = _client.GetGuild(x.GuildId); - if (guild == null) continue; - var users = guild.Members.Where(u => u.Value.IsBoosting).ToList(); - var currencyCfg = await db.GetOrCreateCurrencyConfigAsync(guild); - foreach (var (_, member) in users) - { - try - { - var userData = await db.GetOrCreateUserData(member); - await _exp.AddExpAsync(member, userData, x.ExpGain, x.CreditGain, db); - userData.CreditSpecial += x.SpecialCreditGain; - - var channel = member.DmChannel ?? (IDmChannel)await member.CreateDmChannelAsync(); - var sb = new StringBuilder(); - - sb.AppendLine( - $"Thank you for boosting {guild.Name} for {(DateTimeOffset.UtcNow - member.BoostedAt.Value).Humanize()}!"); - if (x.ExpGain != 0 || x.CreditGain != 0 || x.SpecialCreditGain != 0) - sb.AppendLine("You've been rewarded:"); - if (x.ExpGain != 0) sb.AppendLine($"{x.ExpGain} exp"); - if (x.CreditGain != 0) - sb.AppendLine( - $"{currencyCfg.CurrencyName}: {_currency.ToCurrency(currencyCfg, x.CreditGain)}"); - if (x.SpecialCreditGain != 0) - sb.AppendLine( - $"{currencyCfg.SpecialCurrencyName}: {_currency.ToCurrency(currencyCfg, x.SpecialCreditGain, true)}"); - await channel.ReplyAsync(new LocalEmbedBuilder - { - Title = "Boost Rewards!", - Color = _colour.Get(guild.Id.RawValue), - Description = sb.ToString() - }); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Boost Service) Error in {x.GuildId} when rewarding {member.Id.RawValue} - {e.Message}"); - } - } - - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"Rewarded {users.Count} boosters in {guild.Id.RawValue}"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Boost Service) Error in {x.GuildId} when rewarding users - {e.Message}"); - } - } - - _log.Log(LogLevel.Info, - "(Boost Service) Finished rewarding users in all guilds configured for it"); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Caching/CacheService.cs b/Hanekawa/Bot/Services/Caching/CacheService.cs deleted file mode 100644 index ef2396e5..00000000 --- a/Hanekawa/Bot/Services/Caching/CacheService.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using Disqord; -using Disqord.Bot.Prefixes; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.Caching.Memory; - -namespace Hanekawa.Bot.Services.Caching -{ - public class CacheService : INService - { - public readonly ConcurrentDictionary BanCache = new(); - public readonly ConcurrentDictionary QuoteCache = new(); - private readonly ConcurrentDictionary> _prefixCollection = new (); - - public HashSet GetCollection(Snowflake snowflake) => - _prefixCollection.TryGetValue(snowflake, out var prefixes) - ? prefixes - : null; - - public void AddOrUpdatePrefix(CachedGuild guild, string prefix) - { - var prefixes = new HashSet() {new StringPrefix(prefix)}; - _prefixCollection.AddOrUpdate(guild.Id, prefixes, (snowflake, set) => prefixes); - } - - public bool IsMentionPrefix(CachedUserMessage message, out IPrefix mentionPrefix) - { - var contentSpan = message.Content.AsSpan(); - if (contentSpan.Length > 17 - && contentSpan[0] == '<' - && contentSpan[1] == '@') - { - var closingBracketIndex = contentSpan.IndexOf('>'); - if (closingBracketIndex != -1) - { - var idSpan = contentSpan[2] == '!' - ? contentSpan.Slice(3, closingBracketIndex - 3) - : contentSpan.Slice(2, closingBracketIndex - 2); - if (Snowflake.TryParse(idSpan, out var id) && id == message.Client.CurrentUser.Id) - { - mentionPrefix = contentSpan[2] == '!' ? new StringPrefix($"<@!{id}>") : new StringPrefix($"<@{id}>"); - var collection = _prefixCollection.GetOrAdd(message.Guild.Id, new HashSet()); - collection.Add(mentionPrefix); - _prefixCollection.AddOrUpdate(message.Guild.Id, new HashSet(), - (snowflake, set) => collection); - return true; - } - } - } - - mentionPrefix = null; - return false; - } - } -} diff --git a/Hanekawa/Bot/Services/Club/ClubAdvertise.cs b/Hanekawa/Bot/Services/Club/ClubAdvertise.cs deleted file mode 100644 index 55c3b9c8..00000000 --- a/Hanekawa/Bot/Services/Club/ClubAdvertise.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Club; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Quartz.Util; - -namespace Hanekawa.Bot.Services.Club -{ - public partial class ClubService - { - public async Task AdNameAsync(HanekawaCommandContext context, string name) - { - if (name.IsNullOrWhiteSpace()) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == context.Guild.Id.RawValue && x.LeaderId == context.User.Id.RawValue); - if (club == null) return; - await context.Message.TryDeleteMessageAsync(); - var cfg = await db.GetOrCreateClubConfigAsync(context.Guild); - club.Name = name; - await db.SaveChangesAsync(); - await context.ReplyAsync($"Updated club name to `{name}` !"); - if (club.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(club.AdMessage.Value) as IUserMessage; - await UpdatePostNameAsync(msg, name); - } - - if (club.Role.HasValue) - { - var role = context.Guild.GetRole(club.Role.Value); - await role.ModifyAsync(x => x.Name = name); - } - - if (club.Channel.HasValue) - { - var channel = context.Guild.GetTextChannel(club.Channel.Value); - await channel.ModifyAsync(x => x.Name = name); - } - } - - public async Task AdDescAsync(HanekawaCommandContext context, string desc) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var leader = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == context.Guild.Id.RawValue && x.LeaderId == context.User.Id.RawValue); - if (leader == null) return; - await context.Message.TryDeleteMessageAsync(); - var cfg = await db.GetOrCreateClubConfigAsync(context.Guild); - leader.Description = desc; - await db.SaveChangesAsync(); - await context.ReplyAsync("Updated description of club!", Color.Green); - if (leader.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(leader.AdMessage.Value) as IUserMessage; - await UpdatePostDescriptionAsync(msg, desc); - } - } - - public async Task AdImageAsync(HanekawaCommandContext context, string image) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var leader = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == context.Guild.Id.RawValue && x.LeaderId == context.User.Id.RawValue); - if (leader == null) return; - await context.Message.TryDeleteMessageAsync(); - var cfg = await db.GetOrCreateClubConfigAsync(context.Guild); - leader.ImageUrl = image; - await db.SaveChangesAsync(); - await context.ReplyAsync("Updated description of club!", Color.Green); - if (leader.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(leader.AdMessage.Value) as IUserMessage; - await UpdatePostImageAsync(msg, image); - } - } - - public async Task AdIconAsync(HanekawaCommandContext context, string icon) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var leader = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == context.Guild.Id.RawValue && x.LeaderId == context.User.Id.RawValue); - if (leader == null) return; - await context.Message.TryDeleteMessageAsync(); - var cfg = await db.GetOrCreateClubConfigAsync(context.Guild); - leader.IconUrl = icon; - await db.SaveChangesAsync(); - await context.ReplyAsync("Updated description of club!", Color.Green); - if (leader.AdMessage.HasValue && cfg.AdvertisementChannel.HasValue) - { - var msg = await context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(leader.AdMessage.Value) as IUserMessage; - await UpdatePostIconAsync(msg, icon); - } - } - - public async Task AdPublicAsync(HanekawaCommandContext context) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == context.Guild.Id.RawValue && x.LeaderId == context.User.Id.RawValue); - if (club == null) return; - if (club.Public) - { - club.Public = false; - await db.SaveChangesAsync(); - await context.ReplyAsync("Club is no longer public. People need invite to enter the club.", - Color.Green); - if (club.AdMessage.HasValue) await PublicHandle(db, context, club, context.Guild, false); - } - else - { - club.Public = true; - await db.SaveChangesAsync(); - await context.ReplyAsync("Set club as public. Anyone can join!", Color.Green); - if (club.AdMessage.HasValue) await PublicHandle(db, context, club, context.Guild, true); - } - } - - public async Task AdAdvertiseAsync(HanekawaCommandContext context) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var leader = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == context.Guild.Id.RawValue && x.LeaderId == context.User.Id.RawValue); - if (leader == null) return; - var cfg = await db.GetOrCreateClubConfigAsync(context.Guild); - if (!cfg.AdvertisementChannel.HasValue) - { - await context.ReplyAsync("This server hasn't setup or doesn't allow club advertisement.", - Color.Red); - return; - } - - if (!leader.AdMessage.HasValue) - { - await SendPostAsync(db, cfg, context.Guild, leader); - await context.ReplyAsync("Posted ad!", Color.Green); - } - else - { - var msg = await context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(leader.AdMessage.Value); - if (msg == null) - { - await SendPostAsync(db, cfg, context.Guild, leader); - await context.ReplyAsync("Posted ad!", Color.Green); - } - else - { - await msg.DeleteAsync(); - await SendPostAsync(db, cfg, context.Guild, leader); - await context.ReplyAsync("Re-posted ad!", Color.Green); - } - } - } - - public static async Task UpdatePostNameAsync(IUserMessage msg, string name) - { - var embedDesc = msg.Embeds.First().ToEmbedBuilder(); - embedDesc.Author.Name = name; - await msg.ModifyAsync(x => x.Embed = embedDesc.Build()); - } - - public static async Task UpdatePostDescriptionAsync(IUserMessage msg, string content) - { - var embedDesc = msg.Embeds.First().ToEmbedBuilder(); - embedDesc.Description = content; - await msg.ModifyAsync(x => x.Embed = embedDesc.Build()); - } - - public static async Task UpdatePostIconAsync(IUserMessage msg, string icon) - { - var embedDesc = msg.Embeds.First().ToEmbedBuilder(); - embedDesc.Author.IconUrl = icon; - await msg.ModifyAsync(x => x.Embed = embedDesc.Build()); - } - - public static async Task UpdatePostImageAsync(IUserMessage msg, string image) - { - var embedDesc = msg.Embeds.First().ToEmbedBuilder(); - embedDesc.ImageUrl = image; - await msg.ModifyAsync(x => x.Embed = embedDesc.Build()); - } - - private async Task SendPostAsync(DbService db, ClubConfig cfg, CachedGuild guild, ClubInformation club) - { - if (!cfg.AdvertisementChannel.HasValue) return; - var embed = new LocalEmbedBuilder() - .Create(club.Description ?? "No description added", _colourService.Get(guild.Id.RawValue)) - .WithAuthor(new LocalEmbedAuthorBuilder() {Name = club.Name}) - .WithImageUrl(club.ImageUrl); - var msg = await guild.GetTextChannel(cfg.AdvertisementChannel.Value).ReplyAsync(embed); - club.AdMessage = msg.Id.RawValue; - await db.SaveChangesAsync(); - if (club.Public) await msg.AddReactionAsync(new LocalEmoji("\u2714")); - } - - private async Task PublicHandle(DbService db, DiscordCommandContext context, ClubInformation club, CachedGuild guild, - bool enabled) - { - var cfg = await db.GetOrCreateClubConfigAsync(context.Guild); - if (cfg.AdvertisementChannel.HasValue) - { - IUserMessage msg = null; - if (club.AdMessage.HasValue) - msg = await context.Guild.GetTextChannel(cfg.AdvertisementChannel.Value) - .GetMessageAsync(club.AdMessage.Value) as IUserMessage; - if (enabled) - { - if (msg == null) await SendPostAsync(db, cfg, guild, club); - else await msg.AddReactionAsync(new LocalEmoji("\u2714")); - } - else - { - if (msg == null) - { - club.AdMessage = null; - await db.SaveChangesAsync(); - } - else - { - await msg.ClearReactionsAsync(); - } - } - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Club/ClubManagement.cs b/Hanekawa/Bot/Services/Club/ClubManagement.cs deleted file mode 100644 index 7d533b6a..00000000 --- a/Hanekawa/Bot/Services/Club/ClubManagement.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Rest; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Club; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Extensions; -using Microsoft.EntityFrameworkCore; -using NLog; - -namespace Hanekawa.Bot.Services.Club -{ - public partial class ClubService - { - public static async Task PromoteUserAsync(CachedMember user, ClubUser clubUser, ClubInformation clubInfo, - DbService db) - { - if (clubUser.Rank == 2) - { - var leader = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.ClubId == clubInfo.Id && x.GuildId == user.Guild.Id.RawValue && x.UserId == clubInfo.LeaderId); - if (leader == null || clubInfo.LeaderId == 1) return; - leader.Rank++; - clubUser.Rank--; - clubInfo.LeaderId = user.Id.RawValue; - } - else - { - clubUser.Rank--; - } - - await db.SaveChangesAsync(); - } - - public static async Task DemoteAsync(ClubUser clubUser, DbService db) - { - if (clubUser.Rank == 3) return; - clubUser.Rank++; - await db.SaveChangesAsync(); - } - - public async Task AddUserAsync(CachedMember user, int id, DbService db) - { - await db.ClubPlayers.AddAsync(new ClubUser - { - ClubId = id, - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - JoinDate = DateTimeOffset.UtcNow, - Rank = 3 - }); - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"(Club Service) Added {user.Id.RawValue} to club {id} in {user.Guild.Id.RawValue}"); - } - - public async Task RemoveUserAsync(CachedUser user, CachedGuild guild, int id, DbService db, ClubConfig cfg = null) - { - if (cfg == null) cfg = await db.GetOrCreateClubConfigAsync(guild); - var clubUser = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.UserId == user.Id.RawValue && x.GuildId == guild.Id.RawValue && x.ClubId == id); - if (clubUser == null) return false; - var clubInfo = - await db.ClubInfos.FirstOrDefaultAsync(x => x.GuildId == guild.Id.RawValue && x.Id == clubUser.ClubId); - if (clubUser.Rank == 1) - { - var clubMembers = await db.ClubPlayers - .Where(x => x.GuildId == guild.Id.RawValue && x.ClubId == clubUser.ClubId) - .ToListAsync(); - if (clubMembers.Count > 1) - { - var officers = clubMembers.Where(x => x.Rank == 2).ToList(); - var newLeader = officers.Count >= 1 - ? officers[_random.Next(officers.Count)] - : clubMembers[_random.Next(clubMembers.Count)]; - _log.Log(LogLevel.Info, $"(Club Service) Replaced club leader from club id {clubInfo.Id} in {guild.Id.RawValue} from {clubUser.UserId} to {newLeader.Id}"); - newLeader.Rank = 1; - clubInfo.LeaderId = newLeader.UserId; - } - } - - db.ClubPlayers.Remove(clubUser); - await RemoveRoleOrChannelPermissions(user, guild, clubInfo, cfg); - await Disband(user, clubInfo, db); - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"(Club Service) Removed {clubUser.UserId} from {clubInfo.Id} in {guild.Id.RawValue}"); - return true; - } - - public async Task AddBlacklist(CachedUser user, CachedUser leader, CachedGuild guild, ClubInformation clubInfo, - DbService db, string reason = "N/A") - { - var check = await db.ClubBlacklists.FindAsync(clubInfo.Id, guild.Id.RawValue, user.Id.RawValue); - if (check != null) return false; - await db.ClubBlacklists.AddAsync(new ClubBlacklist - { - ClubId = clubInfo.Id, - GuildId = guild.Id.RawValue, - BlackListUser = user.Id.RawValue, - IssuedUser = leader.Id.RawValue, - Reason = reason, - Time = DateTimeOffset.UtcNow - }); - await db.SaveChangesAsync(); - var club = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.UserId == user.Id.RawValue && x.GuildId == guild.Id.RawValue && x.ClubId == clubInfo.Id); - if (club != null) await RemoveUserAsync(user, guild, clubInfo.Id, db); - _log.Log(LogLevel.Info, $"(Club Service) Added blacklist on user {user.Id.RawValue} in club id {clubInfo.Id} in guild {guild.Id.RawValue}"); - return true; - } - - public async Task RemoveBlacklist(CachedUser user, CachedGuild guild, ClubInformation clubInfo, DbService db) - { - var clubUser = await db.ClubBlacklists.FindAsync(clubInfo.Id, guild.Id.RawValue, user.Id.RawValue); - if (clubUser == null) return false; - db.ClubBlacklists.Remove(clubUser); - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"(Club Service) Removed blacklist on user {user.Id.RawValue} in club id {clubInfo.Id} in guild {guild.Id.RawValue}"); - return true; - } - - private async Task AddRoleOrChannelPermissions(CachedMember user, ClubInformation club, DbService db, - ClubConfig cfg = null) - { - cfg ??= await db.GetOrCreateClubConfigAsync(user.Guild); - if (cfg.RoleEnabled && club.Role.HasValue) - await (await user.Guild.GetOrFetchMemberAsync(user.Id.RawValue) as CachedMember).TryAddRoleAsync(user.Guild.GetRole(club.Role.Value)); - if (!cfg.RoleEnabled && club.Channel.HasValue) - await user.Guild.GetTextChannel(club.Channel.Value).AddOrModifyOverwriteAsync(new LocalOverwrite(user.Id.RawValue, OverwriteTargetType.Member, _allowOverwrite)); - } - - private static async Task RemoveRoleOrChannelPermissions(CachedUser user, CachedGuild guild, ClubInformation club, - ClubConfig cfg = null) - { - try - { - if (!club.Channel.HasValue) return; - if (cfg.RoleEnabled && club.Role.HasValue) - await (await guild.GetOrFetchMemberAsync(user.Id.RawValue) as CachedMember).TryRemoveRoleAsync(guild.GetRole(club.Role.Value)); - if (!cfg.RoleEnabled) - await guild.GetTextChannel(club.Channel.Value).DeleteOverwriteAsync(user.Id.RawValue, RestRequestOptions.FromReason("Club Removal")); - } - catch - { - // Ignore - } - } - - private static async Task Disband(CachedUser user, ClubInformation club, DbService db) - { - var clubMembers = await db.ClubPlayers.Where(x => x.ClubId == club.Id).ToListAsync(); - if (clubMembers.Count == 0) - { - club.AdMessage = null; - club.AutoAdd = false; - club.Channel = null; - club.Description = null; - club.IconUrl = null; - club.ImageUrl = null; - club.LeaderId = 1; - club.Public = false; - club.Role = null; - club.Name = "Disbanded"; - db.Update(club); - await db.SaveChangesAsync(); - } - - if (clubMembers.Count == 1) - { - var clubUser = clubMembers.FirstOrDefault(); - if (clubUser == null) return; - if (clubUser.UserId == user.Id.RawValue) - { - club.AdMessage = null; - club.AutoAdd = false; - club.Channel = null; - club.Description = null; - club.IconUrl = null; - club.ImageUrl = null; - club.LeaderId = 1; - club.Public = false; - club.Role = null; - club.Name = "Disbanded"; - db.Update(club); - await db.SaveChangesAsync(); - } - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Club/ClubService.cs b/Hanekawa/Bot/Services/Club/ClubService.cs deleted file mode 100644 index ab87b191..00000000 --- a/Hanekawa/Bot/Services/Club/ClubService.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Club -{ - public partial class ClubService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly Random _random; - private readonly IServiceProvider _provider; - private readonly ColourService _colourService; - - private readonly OverwritePermissions _denyOverwrite = new OverwritePermissions(ChannelPermissions.None, new ChannelPermissions(19520)); - private readonly OverwritePermissions _allowOverwrite = new OverwritePermissions(new ChannelPermissions(19520), ChannelPermissions.None); - - public ClubService(Hanekawa client, Random random, IServiceProvider provider, ColourService colourService) - { - _client = client; - _random = random; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - _colourService = colourService; - - _client.ReactionAdded += ClubReactionAdded; - _client.ReactionRemoved += ClubReactionRemoved; - _client.MemberLeft += ClubUserLeft; - } - - private Task ClubUserLeft(MemberLeftEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.User; - var guild = e.Guild; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var clubs = await db.ClubPlayers.Where(x => x.GuildId == guild.Id.RawValue && x.UserId == user.Id.RawValue) - .ToListAsync(); - if (clubs.Count == 0) return; - var cfg = await db.GetOrCreateClubConfigAsync(guild); - foreach (var x in clubs) await RemoveUserAsync(user, guild, x.Id, db, cfg); - _log.Log(LogLevel.Info, $"(Club Service) {user.Id.RawValue} left {guild.Id.RawValue} and left {clubs.Count} clubs"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Club Service) Error in {guild.Id.RawValue} for User Left- {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task ClubReactionRemoved(ReactionRemovedEventArgs e) => - ClubJoinLeave(e.Message, e.Channel, e.User, e.Emoji, e.Reaction); - - private Task ClubReactionAdded(ReactionAddedEventArgs e) => - ClubJoinLeave(e.Message, e.Channel, e.User, e.Emoji, e.Reaction); - - private Task ClubJoinLeave(FetchableSnowflakeOptional msg, ICachedMessageChannel ch, FetchableSnowflakeOptional usr, IEmoji emoji, Optional reaction) - { - _ = Task.Run(async () => - { - // if (!reaction.Emote.Equals(new Emoji("\u2714"))) return; - // if (!(reaction.User.GetValueOrDefault() is SocketGuildUser user)) return; - if (emoji.Name != "star") return; - if (!usr.HasValue) return; - var user = usr.Value; - if (user.IsBot) return; - if (!(ch is CachedTextChannel channel)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateClubConfigAsync(channel.Guild); - if (!cfg.AdvertisementChannel.HasValue) return; - if (cfg.AdvertisementChannel.Value != channel.Id.RawValue) return; - - var club = await db.ClubInfos.FirstOrDefaultAsync(x => - x.GuildId == channel.Guild.Id.RawValue && x.AdMessage == msg.Id.RawValue); - if (club == null || !club.Public) return; - - var clubUser = await db.ClubPlayers.FirstOrDefaultAsync(x => - x.UserId == user.Id.RawValue && x.GuildId == channel.Guild.Id.RawValue && x.ClubId == club.Id); - if (clubUser == null) await AddUserAsync(user as CachedMember, club.Id, db); - else await RemoveUserAsync(user as CachedUser, channel.Guild, club.Id, db, cfg); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Club Service) Error in {channel.Guild.Id.RawValue} for Reaction added or removed - {e.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Command/CommandHandlingService.cs b/Hanekawa/Bot/Services/Command/CommandHandlingService.cs deleted file mode 100644 index 89c8d2f3..00000000 --- a/Hanekawa/Bot/Services/Command/CommandHandlingService.cs +++ /dev/null @@ -1,77 +0,0 @@ -/* -namespace Hanekawa.Bot.Services.Command -{ - public class CommandHandlingService : INService, IRequired - { - - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly ColourService _colourService; - private readonly ConcurrentDictionary _prefixes = new ConcurrentDictionary(); - private readonly IServiceProvider _provider; - - public CommandHandlingService(Hanekawa client, CommandService command, IServiceProvider provider, - ColourService colourService, InternalLogService log) - { - _client = client; - _provider = provider; - _colourService = colourService; - _log = log; - - _client.LeftGuild += ClientLeft; - _client.JoinedGuild += ClientJoined; - - _client.CommandExecutionFailed += log => - { - _ = OnCommandError(log); - return Task.CompletedTask; - }; - - using (var scope = _provider.CreateScope()) - using (var db = scope.ServiceProvider.GetRequiredService()) - { - foreach (var x in db.GuildConfigs) - { - _prefixes.TryAdd(x.GuildId, x.CacheService); - _colourService.AddOrUpdate(x.GuildId, new Color((int)x.EmbedColor)); - } - } - } - - public string GetPrefix(ulong id) => _prefixes.GetOrAdd(id, "h."); - - public async Task AddPrefix(ulong id, string prefix, DbService db) - { - var cfg = await db.GetOrCreateGuildConfigAsync(id); - cfg.CacheService = prefix; - _prefixes.AddOrUpdate(id, prefix, (key, old) => prefix); - await db.SaveChangesAsync(); - return true; - } - - private Task ClientJoined(JoinedGuildEventArgs e) - { - _ = Task.Run(async () => - { - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateGuildConfigAsync(e.Guild); - _prefixes.TryAdd(e.Guild.Id.RawValue, cfg.CacheService); - _colourService.AddOrUpdate(e.Guild.Id.RawValue, new Color((int)cfg.EmbedColor)); - }); - return Task.CompletedTask; - } - - private Task ClientLeft(LeftGuildEventArgs e) - { - _ = Task.Run(() => - { - _prefixes.TryRemove(e.Guild.Id.RawValue, out _); - _colourService.TryRemove(e.Guild.Id.RawValue); - }); - return Task.CompletedTask; - } - - } -} - */ \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Drop/DropData.cs b/Hanekawa/Bot/Services/Drop/DropData.cs deleted file mode 100644 index 499094ba..00000000 --- a/Hanekawa/Bot/Services/Drop/DropData.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Config; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Caching.Memory; - -namespace Hanekawa.Bot.Services.Drop -{ - public partial class DropService - { - private static readonly MemoryCache _guildCooldown = new MemoryCache(new MemoryCacheOptions()); - - private static readonly ConcurrentDictionary> _lootChannels - = new ConcurrentDictionary>(); - - private static readonly ConcurrentDictionary _normalLoot = - new ConcurrentDictionary(); - - private static readonly ConcurrentDictionary _spawnedLoot = - new ConcurrentDictionary(); - - private static readonly ConcurrentDictionary _userCooldown = - new ConcurrentDictionary(); - - public async Task AddLootChannel(CachedTextChannel channel, DbService db) - { - var channels = _lootChannels.GetOrAdd(channel.Guild.Id.RawValue, new ConcurrentDictionary()); - if (channels.ContainsKey(channel.Id.RawValue)) return false; - channels.TryAdd(channel.Id.RawValue, true); - var data = new LootChannel - { - GuildId = channel.Guild.Id.RawValue, - ChannelId = channel.Id.RawValue - }; - await db.LootChannels.AddAsync(data); - await db.SaveChangesAsync(); - return true; - } - - public async Task RemoveLootChannel(CachedTextChannel channel, DbService db) - { - var channels = _lootChannels.GetOrAdd(channel.Guild.Id.RawValue, new ConcurrentDictionary()); - if (!channels.ContainsKey(channel.Id.RawValue)) return false; - channels.TryRemove(channel.Id.RawValue, out _); - var data = await db.LootChannels.FirstOrDefaultAsync(x => - x.GuildId == channel.Guild.Id.RawValue && x.ChannelId == channel.Id.RawValue); - if (data != null) - { - db.LootChannels.Remove(data); - await db.SaveChangesAsync(); - } - - return true; - } - - private bool IsDropChannel(CachedTextChannel channel) - { - var channels = _lootChannels.GetOrAdd(channel.Guild.Id.RawValue, new ConcurrentDictionary()); - return channels.TryGetValue(channel.Id.RawValue, out _); - } - - private bool IsDropMessage(ulong guildId, ulong messageId, out bool special) - { - var regular = _normalLoot.GetOrAdd(guildId, new MemoryCache(new MemoryCacheOptions())); - var spawned = _spawnedLoot.GetOrAdd(guildId, new MemoryCache(new MemoryCacheOptions())); - if (regular.TryGetValue(messageId, out _)) - { - special = false; - return true; - } - - if (spawned.TryGetValue(messageId, out _)) - { - special = true; - return true; - } - - special = false; - return false; - } - - private bool OnUserCooldown(CachedMember user) - { - var users = _userCooldown.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (users.TryGetValue(user.Id.RawValue, out _)) return true; - users.Set(user.Id.RawValue, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1)); - return false; - } - - private bool OnGuildCooldown(CachedGuild guild) - { - if (_guildCooldown.TryGetValue(guild.Id.RawValue, out _)) return true; - _guildCooldown.Set(guild.Id.RawValue, true, TimeSpan.FromMinutes(1)); - return false; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Drop/DropEmote.cs b/Hanekawa/Bot/Services/Drop/DropEmote.cs deleted file mode 100644 index fa64bdee..00000000 --- a/Hanekawa/Bot/Services/Drop/DropEmote.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Drop -{ - public partial class DropService - { - private readonly ConcurrentDictionary _emotes = new ConcurrentDictionary(); - - public async Task ChangeEmote(CachedGuild guild, LocalCustomEmoji emote) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateDropConfig(guild); - cfg.Emote = emote.MessageFormat; - _emotes.AddOrUpdate(guild.Id.RawValue, emote, (key, value) => emote); - await db.SaveChangesAsync(); - } - - private async Task> ReturnEmotes(CachedGuild guild, DbService db) - { - var emotes = guild.Emojis.Count >= 4 - ? guild.Emojis.ToList() - : _client.GetGuild(431617676859932704).Emojis.ToList(); - - var result = new List(); - for (var x = 0; x < 4; x++) - { - var (_, emote) = emotes[_random.Next(emotes.Count)]; - if (result.Contains(emote) || !emote.IsAvailable) - { - x--; - continue; - } - result.Add(emote); - } - - result.Add(_emotes.TryGetValue(guild.Id.RawValue, out var claimEmote) - ? claimEmote - : _emotes.GetOrAdd(guild.Id.RawValue, await GetClaimEmote(guild, db))); - return result; - } - - private async Task GetClaimEmote(CachedGuild guild, DbService db) - { - var cfg = await db.GetOrCreateDropConfig(guild); - var isEmote = LocalCustomEmoji.TryParse(cfg.Emote, out var emote); - return isEmote ? emote : GetDefaultEmote(); - } - - private IEmoji GetDefaultEmote() - { - LocalCustomEmoji.TryParse("<:realsip:429809346222882836>", out var real); - return real; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Drop/DropService.cs b/Hanekawa/Bot/Services/Drop/DropService.cs deleted file mode 100644 index e288a355..00000000 --- a/Hanekawa/Bot/Services/Drop/DropService.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Events; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Drop -{ - public partial class DropService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly ExpService _expService; - private readonly NLog.Logger _log; - private readonly Random _random; - private readonly IServiceProvider _provider; - private readonly ColourService _colourService; - - public DropService(Hanekawa client, Random random, ExpService expService, IServiceProvider provider, ColourService colourService) - { - _client = client; - _random = random; - _expService = expService; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - _colourService = colourService; - - _client.MessageReceived += DropChance; - _client.ReactionAdded += OnReactionAdded; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - foreach (var x in db.DropConfigs) - { - _emotes.TryAdd(x.GuildId, - LocalCustomEmoji.TryParse(x.Emote, out var result) ? result : GetDefaultEmote()); - } - - foreach (var x in db.LootChannels) - { - var channels = _lootChannels.GetOrAdd(x.GuildId, new ConcurrentDictionary()); - channels.TryAdd(x.ChannelId, true); - } - } - - private Task OnEmoteUpdated(GuildEmojisUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - try - { - if ((e.NewEmojis.Count + 1) == e.OldEmojis.Count) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateDropConfig(e.Guild); - using var removed = e.OldEmojis.Except(e.NewEmojis).GetEnumerator(); - var list = new List(); - while (removed.MoveNext()) - { - list.Add(removed.Current.Value); - } - - if (list.Count == 0) return; - for (var i = 0; i < list.Count; i++) - { - var x = list[i]; - if (x.MessageFormat != cfg.Emote) continue; - cfg.Emote = null; - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"Removed drop emote from {x.Guild.Id} as it was deleted"); - return; - } - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, exception.Message); - } - }); - return Task.CompletedTask; - } - - public async Task SpawnAsync(DiscordCommandContext context) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var claim = await GetClaimEmote(context.Guild, db); - var triggerMsg = await context.Channel.ReplyAsync( - $"{context.Member.DisplayName} has spawned a crate! \nClick {claim} reaction on this message to claim it```", - _colourService.Get(context.Guild.Id.RawValue)); - var emotes = await ReturnEmotes(context.Guild, db); - foreach (var x in emotes.OrderBy(x => _random.Next()).Take(emotes.Count)) - try - { - if (x.Name == claim.Name) - { - var messages = _spawnedLoot.GetOrAdd(context.Guild.Id.RawValue, - new MemoryCache(new MemoryCacheOptions())); - messages.Set(triggerMsg.Id.RawValue, false, TimeSpan.FromHours(1)); - } - - await triggerMsg.AddReactionAsync(x); - } - catch - { - break; - } - } - - private Task DropChance(MessageReceivedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Message.Author is CachedMember user)) return; - if (user.IsBot) return; - if (!(e.Message.Channel is CachedTextChannel ch)) return; - if (!IsDropChannel(ch)) return; - if (OnGuildCooldown(ch.Guild)) return; - if (OnUserCooldown(user)) return; - var rand = _random.Next(0, 10000); - if (rand < 200) - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var claim = await GetClaimEmote(ch.Guild, db); - var triggerMsg = await ch.SendMessageAsync( - $"A drop event has been triggered \nClick the {claim} reaction on this message to claim it!"); - var emotes = await ReturnEmotes(ch.Guild, db); - foreach (var x in emotes.OrderBy(x => _random.Next()).Take(emotes.Count)) - { - if (x.Name == claim.Name) - { - var messages = _normalLoot.GetOrAdd(ch.Guild.Id.RawValue, - new MemoryCache(new MemoryCacheOptions())); - messages.Set(triggerMsg.Id.RawValue, false, TimeSpan.FromHours(1)); - } - - await triggerMsg.AddReactionAsync(x); - } - - _log.Log(LogLevel.Info, $"(Drop Service) Drop event created in {user.Guild.Id.RawValue}"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Drop Service) Error in {user.Guild.Id.RawValue} for drop create - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task OnReactionAdded(ReactionAddedEventArgs e) - { - var _ = Task.Run(async () => - { - if (!(e.Channel is CachedTextChannel channel)) return; - if (!e.User.HasValue) await e.User.GetAsync(); - if (!(e.User.Value is CachedMember user)) return; - if (user.IsBot) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var check = _emotes.TryGetValue(user.Guild.Id.RawValue, out var claim); - if(!check) claim = await GetClaimEmote(user.Guild, db); - if (e.Emoji.MessageFormat != claim.MessageFormat) return; - if (!IsDropMessage(user.Guild.Id.RawValue, e.Message.Id.RawValue, out var special)) return; - var message = await e.Message.GetAsync(); - if (special) await ClaimSpecial(message, channel, user, db); - else await ClaimNormal(message, channel, user, db); - - _log.Log(LogLevel.Info, $"(Drop Service) Drop event claimed by {user.Id.RawValue} in {user.Guild.Id.RawValue}"); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Drop Service) Error in {user.Guild.Id.RawValue} for drop claim - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private async Task ClaimSpecial(IMessage msg, CachedTextChannel channel, CachedMember user, DbService db) - { - try - { - await msg.DeleteAsync(); - } - catch { /* Ignore */} - var loots = _spawnedLoot.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - loots.Remove(msg.Id.RawValue); - var rand = _random.Next(150, 250); - var userData = await db.GetOrCreateUserData(user); - var exp = await _expService.AddExpAsync(user, userData, rand, rand, db); - var trgMsg = - await channel.SendMessageAsync( - $"Rewarded {user.Mention} with {exp} exp & {rand} credit!"); - try - { - await Task.Delay(5000); - await trgMsg.DeleteAsync(); - } - catch - { - // Ignore - } - } - - private async Task ClaimNormal(IMessage msg, CachedTextChannel channel, CachedMember user, DbService db) - { - try { await msg.DeleteAsync(); } - catch { /* Ignore */} - - var loots = _normalLoot.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - loots.Remove(msg.Id.RawValue); - var rand = _random.Next(15, 150); - var userData = await db.GetOrCreateUserData(user); - var exp = await _expService.AddExpAsync(user, userData, rand, rand, db); - var trgMsg = - await channel.SendMessageAsync( - $"Rewarded {user.Mention} with {exp} exp & {rand} credit!"); - try - { - await Task.Delay(5000); - await trgMsg.DeleteAsync(); - } - catch - { - // Ignore - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Economy/CurrencyService.cs b/Hanekawa/Bot/Services/Economy/CurrencyService.cs deleted file mode 100644 index feb140c0..00000000 --- a/Hanekawa/Bot/Services/Economy/CurrencyService.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Shared.Interfaces; - -namespace Hanekawa.Bot.Services.Economy -{ - public class CurrencyService : INService - { - private readonly string[] _currencySigns = {"$", "€", "£"}; - - public async Task ToCurrency(DbService db, ulong guildId, int amount, bool isSpecial = false) - => ToCurrency(await db.GetOrCreateCurrencyConfigAsync(guildId), amount, isSpecial); - - public string ToCurrency(CurrencyConfig cfg, int amount, bool isSpecial = false) - { - if (isSpecial) - return cfg.SpecialEmoteCurrency - ? ParseEmote(cfg.SpecialCurrencySign, amount) - : ParseString(cfg.SpecialCurrencySign, amount); - return cfg.EmoteCurrency ? ParseEmote(cfg.CurrencySign, amount) : ParseString(cfg.CurrencySign, amount); - } - - private string ParseEmote(string sign, int amount) => $"{amount} {CurrencySignEmote(sign)}"; - - private string ParseString(string sign, int amount) => - _currencySigns.Contains(sign) - ? $"{sign}{amount}" - : $"{amount} {sign}"; - - private IEmoji CurrencySignEmote(string emoteString) - { - if (LocalCustomEmoji.TryParse(emoteString, out var emote)) return emote; - LocalCustomEmoji.TryParse("", out var defaultEmote); - return defaultEmote; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Experience/Cooldown.cs b/Hanekawa/Bot/Services/Experience/Cooldown.cs deleted file mode 100644 index 934bb633..00000000 --- a/Hanekawa/Bot/Services/Experience/Cooldown.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Concurrent; -using Disqord; -using Microsoft.Extensions.Caching.Memory; - -namespace Hanekawa.Bot.Services.Experience -{ - public partial class ExpService - { - private readonly MemoryCache _globalCooldown = new MemoryCache(new MemoryCacheOptions()); - - private readonly ConcurrentDictionary _serverExpCooldown - = new ConcurrentDictionary(); - - private bool OnServerCooldown(CachedMember user) - { - var users = _serverExpCooldown.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (users.TryGetValue(user.Id.RawValue, out _)) return true; - users.Set(user.Id.RawValue, user, TimeSpan.FromSeconds(60)); - return false; - } - - private bool OnGlobalCooldown(CachedMember user) - { - if (_globalCooldown.TryGetValue(user.Id.RawValue, out _)) return true; - _globalCooldown.Set(user.Id.RawValue, user, TimeSpan.FromMinutes(1)); - return false; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Experience/Decay.cs b/Hanekawa/Bot/Services/Experience/Decay.cs deleted file mode 100644 index 0622c588..00000000 --- a/Hanekawa/Bot/Services/Experience/Decay.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Account; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Quartz; - -namespace Hanekawa.Bot.Services.Experience -{ - public partial class ExpService : IJob - { - public Task Execute(IJobExecutionContext context) - { - _ = DecayAsync(); - return Task.CompletedTask; - } - - private async Task DecayAsync() - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var limit = DateTime.UtcNow.AddDays(-14); - var servers = await db.LevelConfigs.Where(x => x.Decay).ToArrayAsync(); - if (servers.Length <= 0) return; - _log.Log(NLog.LogLevel.Info, $"(Exp Service: Decay) Executing decay in {servers.Length} servers"); - foreach (var x in servers) - { - var server = _client.GetGuild(x.GuildId); - if (server == null) continue; - var levelRewards = await db.LevelRewards.Where(e => e.GuildId == x.GuildId).ToListAsync(); - var users = await db.Accounts.Where(e => - e.GuildId == x.GuildId && e.Active && e.LastMessage <= limit && e.Decay < e.TotalExp).ToArrayAsync(); - _log.Log(NLog.LogLevel.Info, $"(Exp Service: Decay) Executing decay for server {server.Name} ({x.GuildId})"); - foreach (var user in users) - { - if (user.TotalExp == user.Decay) continue; - var member = server.GetMember(user.UserId); - if (member == null) - { - user.Active = false; - continue; - } - if (member.IsBoosting) continue; - try - { - var decay = Convert.ToInt32((DateTime.UtcNow - user.LastMessage).TotalDays) * 1000; - if (decay == user.Decay) continue; - if (user.TotalExp <= user.Decay + decay) user.Decay = user.TotalExp; - if (user.TotalExp > user.Decay + decay) user.Decay = decay; - var decayLevels = LevelDecay(user, decay); - if (decayLevels == 0) continue; - _log.Log(NLog.LogLevel.Info, $"(Exp Service: Decay) Executing role check on {member} ({member.Id.RawValue}) in {server.Name} ({x.GuildId})"); - await RoleCheckAsync(member, x, user, levelRewards, db, decayLevels); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Exp Service: Decay) Couldn't executing role check on {member} ({member.Id.RawValue}) in {server.Name} ({x.GuildId})\n{e.Message}"); - } - } - await db.SaveChangesAsync(); - } - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Exp Service: Decay) Error occured during decay - {e.Message}"); - } - } - - private int LevelDecay(Account userData, int decay) - { - var decayExp = decay; - var decayLevel = 0; - var currentExp = userData.Exp; - while (decayExp >= 0) - { - if (currentExp - decay <= 0) - { - decayExp =- currentExp; - decayLevel++; - currentExp = ExpToNextLevel(userData.Level - decayLevel); - continue; - } - decayExp = 0; - } - - return decayLevel; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Experience/EventHandler.cs b/Hanekawa/Bot/Services/Experience/EventHandler.cs deleted file mode 100644 index 9b5dfdbb..00000000 --- a/Hanekawa/Bot/Services/Experience/EventHandler.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Giveaway; -using Hanekawa.Shared; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using Account = Hanekawa.Database.Tables.Account.Account; - -namespace Hanekawa.Bot.Services.Experience -{ - public partial class ExpService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly Logger _log; - private readonly Random _random; - private readonly IServiceProvider _provider; - - public readonly ConcurrentDictionary> ServerCategoryReduction = - new ConcurrentDictionary>(); - - public readonly ConcurrentDictionary> ServerTextChanReduction = - new ConcurrentDictionary>(); - - public readonly ConcurrentDictionary> ServerVoiceChanReduction = - new ConcurrentDictionary>(); - - public ExpService(Hanekawa client, Random random, InternalLogService log, IServiceProvider provider) - { - _client = client; - _random = random; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - - _ = EventHandler(new CancellationToken()); - - _client.MessageReceived += ServerMessageExpAsync; - _client.MessageReceived += GlobalMessageExpAsync; - _client.VoiceStateUpdated += VoiceExpAsync; - _client.MemberJoined += GiveRolesBackAsync; - _client.RoleDeleted += RemoveRole; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - foreach (var x in db.LevelConfigs) - { - _textExpMultiplier.TryAdd(x.GuildId, x.TextExpMultiplier); - _voiceExpMultiplier.TryAdd(x.GuildId, x.VoiceExpMultiplier); - } - - foreach (var x in db.LevelExpReductions) - { - try - { - switch (x.ChannelType) - { - case ChannelType.Category: - { - var categories = ServerCategoryReduction.GetOrAdd(x.GuildId, new HashSet()); - categories.Add(x.ChannelId); - ServerCategoryReduction.AddOrUpdate(x.GuildId, new HashSet(), - (arg1, list) => categories); - break; - } - - case ChannelType.Text: - { - var channel = ServerTextChanReduction.GetOrAdd(x.GuildId, new HashSet()); - channel.Add(x.ChannelId); - ServerTextChanReduction.AddOrUpdate(x.GuildId, new HashSet(), - (arg1, list) => channel); - break; - } - - case ChannelType.Voice: - { - var channel = ServerVoiceChanReduction.GetOrAdd(x.GuildId, new HashSet()); - channel.Add(x.ChannelId); - ServerVoiceChanReduction.AddOrUpdate(x.GuildId, new HashSet(), - (arg1, list) => channel); - break; - } - default: - continue; - } - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"Couldn't load {x.GuildId} reward plugin for {x.ChannelId}, remove?"); - } - } - } - - private Task GlobalMessageExpAsync(MessageReceivedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Message.Author is CachedMember user)) return; - if (!(e.Message.Channel is CachedTextChannel channel)) return; - if (user.IsBot) return; - if (OnGlobalCooldown(user)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateGlobalUserData(user); - await AddExpAsync(userData, GetExp(channel), _random.Next(1, 3), db); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(Exp Service) Error in {user.Guild.Id.RawValue} for Global Exp - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task ServerMessageExpAsync(MessageReceivedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Message.Author is CachedMember user)) return; - if (!(e.Message.Channel is CachedTextChannel channel)) return; - if (user.IsBot) return; - if (OnServerCooldown(user)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(user); - userData.LastMessage = DateTime.UtcNow; - userData.FirstMessage ??= DateTime.UtcNow; - await AddExpAsync(user, userData, GetExp(channel), _random.Next(0, 3), db); - await MvpCount(db, userData, user); - await GiveawayAsync(db, user); - } - catch (Exception z) - { - _log.Log(NLog.LogLevel.Error, z, - $"(Exp Service) Error in {user.Guild.Id.RawValue} for Server Exp - {z.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task VoiceExpAsync(VoiceStateUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - if (e.Member.IsBot) return; - var user = e.Member; - var after = e.NewVoiceState; - var before = e.OldVoiceState; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLevelConfigAsync(user.Guild); - if (!cfg.VoiceExpEnabled) return; - if (before != null && after != null) return; - var userData = await db.GetOrCreateUserData(user); - if (before == null && after != null) - { - userData.VoiceExpTime = DateTime.UtcNow; - await db.SaveChangesAsync(); - return; - } - - if (before != null && after == null) - { - user.Guild.VoiceChannels.TryGetValue(before.ChannelId, out var vcChannel); - var exp = GetExp(vcChannel, DateTime.UtcNow - userData.VoiceExpTime); - await AddExpAsync(user, userData, exp, Convert.ToInt32(exp / 2), db); - } - } - catch (Exception z) - { - _log.Log(NLog.LogLevel.Error, z, - $"(Exp Service) Error in {user.Guild.Id.RawValue} for Voice - {z.Message}"); - } - }); - return Task.CompletedTask; - } - - private int GetExp(CachedTextChannel channel) - { - var xp = _random.Next(10, 20); - if (IsReducedExp(channel)) xp = Convert.ToInt32(xp / 10); - return xp; - } - - private int GetExp(CachedVoiceChannel channel, TimeSpan period) - { - var xp = Convert.ToInt32(period.TotalMinutes * 2); - if (IsReducedExp(channel)) xp = Convert.ToInt32(xp / 10); - return xp; - } - - private bool IsReducedExp(CachedTextChannel channel) - { - var isChannel = ServerTextChanReduction.TryGetValue(channel.Guild.Id.RawValue, out var channels); - var isCategory = ServerCategoryReduction.TryGetValue(channel.Guild.Id.RawValue, out var category); - return !isCategory - ? isChannel && channels.TryGetValue(channel.Id.RawValue, out _) - : !channel.CategoryId.HasValue - ? isChannel && channels.TryGetValue(channel.Id.RawValue, out _) - : category.TryGetValue(channel.CategoryId.Value, out _) || - isChannel && channels.TryGetValue(channel.Id.RawValue, out _); - } - - private bool IsReducedExp(CachedVoiceChannel channel) - { - var isChannel = ServerVoiceChanReduction.TryGetValue(channel.Guild.Id.RawValue, out var channels); - var isCategory = ServerCategoryReduction.TryGetValue(channel.Guild.Id.RawValue, out var category); - return !isCategory - ? isChannel && channels.TryGetValue(channel.Id.RawValue, out _) - : !channel.CategoryId.HasValue - ? isChannel && channels.TryGetValue(channel.Id.RawValue, out _) - : category.TryGetValue(channel.CategoryId.Value, out _) || - isChannel && channels.TryGetValue(channel.Id.RawValue, out _); - } - - private async Task MvpCount(DbService db, Account userData, CachedMember user) - { - var cfg = await db.GetOrCreateGuildConfigAsync(user.Guild); - if (!cfg.Premium) return; - userData.MvpCount++; - await db.SaveChangesAsync(); - } - - private async Task GiveawayAsync(DbService db, CachedMember user) - { - var giveaways = await db.Giveaways - .Where(x => x.GuildId == user.Guild.Id.RawValue && x.Type == GiveawayType.Activity && x.Active) - .ToListAsync(); - if (giveaways.Count == 0) return; - for (var i = 0; i < giveaways.Count; i++) - { - var x = giveaways[i]; - if (!x.Active) continue; - if (x.CloseAtOffset.HasValue && x.CloseAtOffset.Value >= DateTimeOffset.UtcNow) continue; - if (!x.Stack) - { - var check = await db.GiveawayParticipants.FirstOrDefaultAsync(e => - e.UserId == user.Id.RawValue && e.GiveawayId == x.Id); - if(check != null) continue; - } - - await db.GiveawayParticipants.AddAsync(new GiveawayParticipant - { - Id = Guid.NewGuid(), - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Entry = DateTimeOffset.UtcNow, - GiveawayId = x.Id, - Giveaway = x - }); - } - - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Experience/ExpEventHandler.cs b/Hanekawa/Bot/Services/Experience/ExpEventHandler.cs deleted file mode 100644 index 813ce4bf..00000000 --- a/Hanekawa/Bot/Services/Experience/ExpEventHandler.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Shared.Command; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Experience -{ - public partial class ExpService - { - private Tuple _expEventTimer; - - public async Task StartEventAsync(DbService db, DiscordCommandContext context, double multiplier, TimeSpan duration, - bool announce = false) - { - var checkExisting = await db.LevelExpEvents.FindAsync(context.Guild.Id.RawValue); - if (checkExisting != null && _expEventTimer != null) - { - checkExisting.Time = DateTime.UtcNow + duration; - checkExisting.Multiplier = multiplier; - if (_expEventTimer.Item1 == context.Guild.Id.RawValue) _expEventTimer.Item2.Dispose(); - } - else - { - await db.LevelExpEvents.AddAsync(new LevelExpEvent - { - GuildId = context.Guild.Id.RawValue, - Multiplier = multiplier, - Time = DateTime.UtcNow + duration, - ChannelId = null, - MessageId = null - }); - } - - await db.SaveChangesAsync(); - _voiceExpMultiplier.AddOrUpdate(context.Guild.Id.RawValue, multiplier, (k, v) => multiplier); - _textExpMultiplier.AddOrUpdate(context.Guild.Id.RawValue, multiplier, (key, v) => multiplier); - } - - private async Task EventHandler(CancellationToken stopToken) - { - while (stopToken.IsCancellationRequested) - { - using (var scope = _provider.CreateScope()) - await using (var db = scope.ServiceProvider.GetRequiredService()) - { - var nextEvent = await db.LevelExpEvents.OrderBy(x => x.Time).FirstOrDefaultAsync(stopToken); - - if (_expEventTimer != null && nextEvent != null) - { - if (nextEvent.Time <= DateTime.UtcNow) - { - var cfg = await db.GetOrCreateLevelConfigAsync(nextEvent.GuildId); - - _voiceExpMultiplier.AddOrUpdate(nextEvent.GuildId, cfg.VoiceExpMultiplier, - (k, v) => cfg.VoiceExpMultiplier); - _textExpMultiplier.AddOrUpdate(nextEvent.GuildId, cfg.TextExpMultiplier, - (k, v) => cfg.TextExpMultiplier); - - db.LevelExpEvents.Remove(nextEvent); - await db.SaveChangesAsync(stopToken); - } - else - { - var timer = new Timer(async _ => - { - await using var dbService = scope.ServiceProvider.GetRequiredService(); - var cfg = await dbService.GetOrCreateLevelConfigAsync(nextEvent.GuildId); - - _voiceExpMultiplier.AddOrUpdate(nextEvent.GuildId, cfg.VoiceExpMultiplier, - (k, v) => cfg.VoiceExpMultiplier); - _textExpMultiplier.AddOrUpdate(nextEvent.GuildId, cfg.TextExpMultiplier, - (k, v) => cfg.TextExpMultiplier); - - dbService.LevelExpEvents.Remove(nextEvent); - await dbService.SaveChangesAsync(stopToken); - }, null, nextEvent.Time - DateTime.UtcNow, Timeout.InfiniteTimeSpan); - _expEventTimer = new Tuple(nextEvent.GuildId, timer); - } - } - } - - await Task.Delay(TimeSpan.FromMinutes(10), stopToken); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Experience/LevelHandler.cs b/Hanekawa/Bot/Services/Experience/LevelHandler.cs deleted file mode 100644 index bdf462ea..00000000 --- a/Hanekawa/Bot/Services/Experience/LevelHandler.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account; -using Microsoft.Extensions.Logging; - -#nullable enable - -namespace Hanekawa.Bot.Services.Experience -{ - public partial class ExpService - { - private readonly ConcurrentDictionary _textExpMultiplier = - new ConcurrentDictionary(); - - private readonly ConcurrentDictionary _voiceExpMultiplier = - new ConcurrentDictionary(); - - public int ExpToNextLevel(Account userdata) => 3 * userdata.Level * userdata.Level + 150; - - private static int ExpToNextLevel(AccountGlobal userdata) => 50 * userdata.Level * userdata.Level + 300; - - public int ExpToNextLevel(int level) => 3 * level * level + 150; - - public async Task AddExpAsync(CachedMember user, Account userData, int exp, int credit, DbService db) - { - if (user.IsBoosting) - { - var cfg = await db.GetOrCreateLevelConfigAsync(user.Guild); - exp = Convert.ToInt32(exp * cfg.BoostExpMultiplier); - } - - if (userData.Exp + exp >= ExpToNextLevel(userData)) - { - userData.Exp = userData.Exp + exp - ExpToNextLevel(userData); - userData.Level += 1; - await NewLevelManagerAsync(userData, user, db); - _log.Log(NLog.LogLevel.Info, - $"(Exp Service | Server) {userData.UserId} Leveled up {userData.Level} and gained {exp} exp {credit} credit"); - } - else if (userData.Exp + exp < 0) - { - userData.Level -= 1; - userData.Exp = userData.Exp + ExpToNextLevel(userData.Level - 1) + exp; - _log.Log(NLog.LogLevel.Info, - $"(Exp Service | Server) {userData.UserId} de-leveled to {userData.Level} and gained {exp} exp {credit} credit"); - } - else - { - userData.Exp += exp; - _log.Log(NLog.LogLevel.Info, - $"(Exp Service | Server) {userData.UserId} gained {exp} exp {credit} credit"); - } - - if(userData.Decay != 0) userData.Decay = 0; - userData.TotalExp += exp; - userData.Credit += credit; - if (!userData.Active) userData.Active = true; - await db.SaveChangesAsync(); - return exp; - } - - private async Task AddExpAsync(AccountGlobal userData, int exp, int credit, DbService db) - { - if (userData.Exp + exp >= ExpToNextLevel(userData)) - { - userData.Level += 1; - userData.Exp = userData.Exp + exp - ExpToNextLevel(userData); - _log.Log(NLog.LogLevel.Info, - $"(Exp Service | Global) {userData.UserId} Leveled up {userData.Level} and gained {exp} exp {credit} credit"); - } - else - { - userData.Exp += exp; - _log.Log(NLog.LogLevel.Info, - $"(Exp Service | Global) {userData.UserId} gained {exp} exp {credit} credit"); - } - - userData.TotalExp += exp; - userData.Credit += credit; - await db.SaveChangesAsync(); - } - - public void AdjustTextMultiplier(ulong guildId, double multiplier) - => _textExpMultiplier.AddOrUpdate(guildId, multiplier, (key, value) => multiplier); - - public void AdjustVoiceMultiplier(ulong guildId, double multiplier) - => _voiceExpMultiplier.AddOrUpdate(guildId, multiplier, (key, value) => multiplier); - - public double GetMultiplier(ulong guildId) - { - return _textExpMultiplier.GetOrAdd(guildId, 1); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Experience/RoleHandling.cs b/Hanekawa/Bot/Services/Experience/RoleHandling.cs deleted file mode 100644 index 28c79f61..00000000 --- a/Hanekawa/Bot/Services/Experience/RoleHandling.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Extensions; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; - -namespace Hanekawa.Bot.Services.Experience -{ - public partial class ExpService - { - private Task GiveRolesBackAsync(MemberJoinedEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.Member; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - - var userData = await db.GetOrCreateUserData(user); - if (userData == null || userData.Level < 2) return; - - var cfg = await db.GetOrCreateLevelConfigAsync(user.Guild); - var levelRewards = await db.LevelRewards.Where(x => x.GuildId == user.Guild.Id.RawValue).ToListAsync(); - var roles = GetRolesAsync(user, userData, db, cfg.StackLvlRoles, levelRewards, 0); - await user.TryAddRolesAsync(roles); - }); - return Task.CompletedTask; - } - - private Task RemoveRole(RoleDeletedEventArgs e) - { - _ = Task.Run(async () => - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var role = await db.LevelRewards.FirstOrDefaultAsync(x => - x.GuildId == e.Role.Guild.Id.RawValue && x.Role == e.Role.Id.RawValue); - if (role == null) return; - db.LevelRewards.Remove(role); - await db.SaveChangesAsync(); - _log.Log(NLog.LogLevel.Info, $"Removed Level Reward from guild {e.Role.Guild.Id.RawValue} for level {role.Level} - role id: {e.Role.Id.RawValue}"); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, exception.Message); - } - }); - return Task.CompletedTask; - } - - public async Task NewLevelManagerAsync(Account userData, CachedMember user, DbService db, int levelDecay = 0) - { - var roles = await db.LevelRewards.Where(x => x.GuildId == user.Guild.Id.RawValue).ToListAsync(); - if (roles == null || roles.Count == 0) return; - - var lvRole = roles.FirstOrDefault(x => (x.Level - levelDecay) == userData.Level); - var cfg = await db.GetOrCreateLevelConfigAsync(user.Guild); - - if (lvRole == null) - { - await RoleCheckAsync(user, cfg, userData, roles, db, levelDecay); - return; - } - var role = user.Guild.GetRole(lvRole.Role); - if (role == null) - { - db.LevelRewards.Remove(lvRole); - await db.SaveChangesAsync(); - return; - } - if (!cfg.StackLvlRoles) await RemoveLevelRolesAsync(user, roles); - await user.TryAddRoleAsync(role); - await RoleCheckAsync(user, cfg, userData, roles, db, levelDecay); - } - - private static async Task RoleCheckAsync(CachedMember user, LevelConfig cfg, Account userData, List levelRoles, DbService db, int levelDecay) - { - var roles = GetRolesAsync(user, userData, db, cfg.StackLvlRoles, levelRoles, levelDecay); - - var missingRoles = new List(); - var toRemove = new List(); - var currentUser = user.Guild.CurrentMember; - for (var i = 0; i < roles.Count; i++) - { - var x = roles[i]; - if (!user.Roles.Values.Contains(x) && currentUser.HierarchyCheck(x)) - missingRoles.Add(x); - } - - for (var i = 0; i < levelRoles.Count; i++) - { - var x = levelRoles[i]; - if(x.Level <= userData.Level - levelDecay) continue; - if (user.Roles.ContainsKey(x.Role)) - { - if(x.NoDecay && userData.Level >= x.Level) continue; - var remove = user.Guild.GetRole(x.Role); - if(remove == null) continue; - toRemove.Add(remove); - } - } - - if (missingRoles.Count != 0) await user.TryAddRolesAsync(missingRoles); - if (toRemove.Count != 0) await user.TryRemoveRolesAsync(toRemove); - } - - private static List GetRolesAsync(CachedMember user, Account userData, DbService db, - bool stack, List roleList, int levelDecay) - { - var roles = new List(); - ulong role = 0; - var currentUser = user.Guild.CurrentMember; - - foreach (var x in roleList) - { - var getRole = user.Guild.GetRole(x.Role); - if (getRole == null) continue; - if (stack) - { - if ((userData.Level - levelDecay) < x.Level) continue; - if (currentUser.HierarchyCheck(getRole)) roles.Add(getRole); - } - else - { - if ((userData.Level - levelDecay) >= x.Level && x.Stackable && currentUser.HierarchyCheck(getRole)) - { - roles.Add(getRole); - } - - if ((userData.Level - levelDecay) >= x.Level) role = x.Role; - } - } - - if (stack) return roles; - if (role == 0) return roles; - var getSingleRole = user.Guild.GetRole(role); - if (currentUser.HierarchyCheck(getSingleRole)) roles.Add(getSingleRole); - return roles; - } - - private static async Task RemoveLevelRolesAsync(CachedMember user, List rolesRewards) - { - for (var i = 0; i < rolesRewards.Count; i++) - { - var x = rolesRewards[i]; - if (x.Stackable) continue; - if (user.Roles.Values.Contains(user.Guild.GetRole(x.Role))) - await user.TryRemoveRoleAsync(user.Guild.GetRole(x.Role)); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/ChanceGenerator.cs b/Hanekawa/Bot/Services/Game/HungerGames/ChanceGenerator.cs deleted file mode 100644 index 6a2d6549..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/ChanceGenerator.cs +++ /dev/null @@ -1,83 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Shared.Game.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames -{ - public partial class HungerGame - { - private const int Loot = 400; - private const int Kill = 100; - private const int Idle = 200; - private const int Meet = 100; - private const int Hack = 25; - private const int Die = 1; - private const int Sleep = 1; - private const int Eat = 1; - - private ActionType DeterminationEvent(HungerGameProfile profile) - { - var loot = LootChance(profile); - var kill = KillChance(profile); - var idle = IdleChance(profile); - var meet = MeetChance(profile); - var hack = HackChance(profile); - var die = DieChance(); - var sleep = SleepChance(profile); - var eat = EatChance(profile); - - var result = loot + kill + idle + meet + hack + die + sleep + eat; - var generator = _rand.Next(result); - if (generator <= loot) return ActionType.Loot; - if (generator <= loot + kill) return ActionType.Attack; - if (generator <= loot + kill + idle) return ActionType.Idle; - if (generator <= loot + kill + idle + meet) return ActionType.Meet; - if (generator <= loot + kill + idle + meet + hack) return ActionType.Hack; - if (generator <= loot + kill + idle + meet + hack + die) return ActionType.Die; - return generator <= loot + kill + idle + meet + hack + die + sleep ? ActionType.Sleep : ActionType.Eat; - } - - private static int LootChance(HungerGameProfile profile) - { - if (profile.Water == 0) return Loot + 400; - if (profile.Food == 0) return Loot + 400; - return profile.MeleeWeapon == 0 || (profile.RangeWeapon == 0 && profile.Bullets == 0) ? Loot + 400 : 0; - } - - private static int KillChance(HungerGameProfile profile) - { - if (profile.Water == 0 || profile.Food == 0) - return 0; - if (profile.Water == 1 || profile.Food == 1) return Kill; - if (profile.Weapons >= 1 && (profile.Water > 2 || - profile.Food > 2)) - return Kill + 10000; - if (profile.Water > 1 || profile.Food > 1) - return Kill + 1500; - return Kill; - } - - private static int SleepChance(HungerGameProfile profile) - { - if (profile.Tiredness >= 90) return Sleep + 1000; - if (profile.Tiredness >= 75) return Sleep + 750; - return profile.Tiredness >= 50 ? Sleep : 0; - } - - private static int EatChance(HungerGameProfile profile) - { - if (profile.Hunger >= 20 && profile.Food >= 1) return Eat + 1000; - if (profile.Hunger >= 50 && profile.Food >= 1) return Eat + 500; - if (profile.Hunger >= 75 && profile.Food >= 1) return Eat; - if (profile.Hunger >= 90 && profile.Food >= 1) return 0; - return Eat; - } - - private static int IdleChance(HungerGameProfile profile) => profile.Move == ActionType.Idle ? 0 : Idle; - - private static int MeetChance(HungerGameProfile profile) => profile.Move == ActionType.Meet ? 0 : Meet; - - private static int HackChance(HungerGameProfile profile) => profile.Move == ActionType.Hack ? 0 : Hack; - - private static int DieChance() => Die; - } -} diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/Attack.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/Attack.cs deleted file mode 100644 index a32776e6..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/Attack.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using Hanekawa.Database.Tables.Account.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - public string Attack(HungerGameProfile participant, List targets) - { - var alive = targets.Where(x => x.Alive && x.Health > 0).ToList(); - HungerGameProfile target = null; - while (target == null) - { - var check = targets[_random.Next(alive.Count)]; - if (check.UserId != participant.UserId && (check.Alive || check.Health > 0)) target = check; - } - - int dmg; - var criticalChance = _random.Next(100); - if (participant.RangeWeapon > 0 && participant.Bullets > 0) - { - participant.Bullets--; - dmg = _random.Next(20, 41); - if (criticalChance <= 20 && !participant.Bot) dmg *= 2; - if (target.Bot) dmg *= 2; - if (participant.Bot) dmg /= 2; - if (target.Health - dmg <= 0) - { - target.Health = 0; - target.Alive = false; - return $"Shot and killed **{target.Name}** with a bow"; - } - target.Health -= dmg; - target.Bleeding = true; - return $"Shot **{target.Name}** with a bow"; - } - - if (participant.MeleeWeapon > 0) - { - dmg = _random.Next(10, 21); - if (criticalChance <= 20 && !participant.Bot) dmg *= 2; - if (target.Bot) dmg *= 2; - if (participant.Bot) dmg /= 2; - if (target.Health - dmg <= 0) - { - target.Health = 0; - target.Alive = false; - return $"Slammed and killed **{target.Name}** with a hammer"; - } - target.Health -= dmg; - return $"Slammed **{target.Name}** with a hammer"; - } - - dmg = _random.Next(5, 11); - if (target.Bot) dmg *= 2; - if (participant.Bot) dmg /= 2; - if (target.Health - dmg <= 0) - { - target.Health = 0; - target.Alive = false; - return $"Bitch slapped and killed **{target.Name}**"; - } - target.Health -= dmg; - return $"Bitch slapped **{target.Name}**"; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/Die.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/Die.cs deleted file mode 100644 index ef61ec6f..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/Die.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - private readonly string[] _dieStrings = - { - "Fell down a tree and died", - "Fell down a mountain and died", - "Ate tons of berries and died of poisoning", - "Got bit by a snake and decided to chop his leg off, bled to death", - "I used to be interested in this game, but then I took an arrow to the knee" - }; - - public string Die(HungerGameProfile participant) - { - participant.Health = 0; - participant.Alive = false; - return _dieStrings[_random.Next(_dieStrings.Length)]; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/EatDrink.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/EatDrink.cs deleted file mode 100644 index 9b4bdcc1..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/EatDrink.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - public string EatAndDrink(HungerGameProfile participant) - { - if (participant.Water > 0 && participant.Food > 0) - { - participant.Water--; - participant.Food--; - return "Ate some beans and drank water"; - } - - if (participant.Water > 0) - { - participant.Water--; - return "Drank water"; - } - - participant.Food--; - return "Ate beans"; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/Hack.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/Hack.cs deleted file mode 100644 index 71478c19..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/Hack.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - public string Hack(HungerGameProfile participant) - { - participant.Water += 10; - participant.Food += 10; - participant.FirstAid++; - participant.Weapons++; - participant.MeleeWeapon++; - participant.RangeWeapon++; - participant.Bullets += 10; - return "Breached the border and smuggled tons of supplies"; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/HgEvent.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/HgEvent.cs deleted file mode 100644 index 64b6f36b..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/HgEvent.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using Hanekawa.Shared.Interfaces; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent : INService - { - private readonly Random _random; - - public HgEvent(Random random) => _random = random; - } -} diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/Idle.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/Idle.cs deleted file mode 100644 index d0b238d5..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/Idle.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - private readonly string[] _idleStrings = { - "Climbs a tree", - "Looks at the sky, pondering about life", - "Frozen in time", - "Standing still, looking at a tree", - "Wonders if its possible to do ninjutsu" - }; - - public string Idle() => _idleStrings[_random.Next(_idleStrings.Length)]; - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/Loot.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/Loot.cs deleted file mode 100644 index 8797d5a6..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/Loot.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - private const int FoodAndWater = 100; - private const int Weapons = 15; - - public string Loot(HungerGameProfile participant) - { - const int pool = FoodAndWater + Weapons; - var result = _random.Next(pool); - if (result <= FoodAndWater) - { - participant.Food++; - participant.Water++; - return "Found some food and water in a crate"; - } - - const int range = 50; - const int melee = 25; - result = _random.Next(range + melee); - if (result <= range) - { - participant.Weapons++; - participant.MeleeWeapon++; - return "Found a hammer in a crate"; - } - - if (participant.RangeWeapon == 0) - { - participant.Weapons++; - participant.RangeWeapon++; - participant.Bullets += 10; - return "Found a bow and arrows in a crate"; - } - - participant.Bullets += 10; - return "Found 10 arrows in a crate"; - } - } -} diff --git a/Hanekawa/Bot/Services/Game/HungerGames/Events/Sleep.cs b/Hanekawa/Bot/Services/Game/HungerGames/Events/Sleep.cs deleted file mode 100644 index a2216c9b..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/Events/Sleep.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; - -namespace Hanekawa.Bot.Services.Game.HungerGames.Events -{ - public partial class HgEvent - { - public string Sleep(HungerGameProfile participant) - { - participant.Tiredness += 80; - participant.Stamina = 100; - if (participant.Tiredness > 100) participant.Tiredness = 100; - return "Fell asleep"; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/HungerGames/GameHandler.cs b/Hanekawa/Bot/Services/Game/HungerGames/GameHandler.cs deleted file mode 100644 index 8e3bf32d..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/GameHandler.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Hanekawa.Bot.Services.Game.HungerGames.Events; -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Models.HungerGame; -using Hanekawa.Shared.Game.HungerGame; -using Hanekawa.Shared.Interfaces; - -namespace Hanekawa.Bot.Services.Game.HungerGames -{ - public partial class HungerGame : INService - { - private readonly Random _rand; - private readonly HgEvent _events; - public HungerGame(Random rand, HgEvent events) - { - _rand = rand; - _events = events; - } - - public List PlayAsync(List participants) - { - var results = new List(); - for (var i = 0; i < participants.Count; i++) - { - var x = participants[i]; - var result = new UserAction { BeforeProfile = new HungerGameProfile - { - GuildId = x.GuildId, - UserId = x.UserId, - Bot = x.Bot, - Name = x.Name, - Avatar = x.Avatar, - Alive = x.Alive, - Health = x.Health, - Stamina = x.Stamina, - Bleeding = x.Bleeding, - Hunger = x.Hunger, - Thirst = x.Thirst, - Tiredness = x.Tiredness, - Move = x.Move, - Food = x.Food, - Water = x.Water, - FirstAid = x.FirstAid, - Weapons = x.Weapons, - MeleeWeapon = x.MeleeWeapon, - RangeWeapon = x.RangeWeapon, - Bullets = x.Bullets - } }; - if (!x.Alive) - { - result.AfterProfile = x; - results.Add(result); - continue; - } - - var hgEvent = DeterminationEvent(x); - switch (hgEvent) - { - case ActionType.Loot: - result.Message = _events.Loot(x); - break; - case ActionType.Attack: - result.Message = _events.Attack(x, participants); - break; - case ActionType.Idle: - result.Message = _events.Idle(); - break; - case ActionType.Meet: - result.Message = _events.Idle(); - break; - case ActionType.Hack: - result.Message = _events.Hack(x); - break; - case ActionType.Die: - result.Message = _events.Die(x); - break; - case ActionType.Sleep: - result.Message = _events.Sleep(x); - break; - case ActionType.Eat: - result.Message = _events.EatAndDrink(x); - break; - case ActionType.None: - result.Message = _events.Idle(); - break; - default: - throw new ArgumentOutOfRangeException(); - } - - var fatigue = Fatigue(x); - if (fatigue != null) - { - result.Message += $"\n{fatigue}"; - } - result.AfterProfile = x; - result.Action = hgEvent; - results.Add(result); - } - - return results; - } - - private string Fatigue(HungerGameProfile profile) - { - profile.Hunger -= 10; - profile.Tiredness -= 10; - profile.Thirst -= 20; - - if ((profile.Hunger >= 100 || profile.Thirst >= 100) && profile.Bleeding) - { - if (profile.Hunger >= 100 && profile.Health >= 100) - { - if (profile.Health - 50 <= 0) - { - profile.Health = 0; - profile.Alive = false; - return "Died from starvation, dehydration and bleeding out"; - } - profile.Health -= 50; - return "Suffered from severe starvation, dehydration and bleeding out"; - } - if (profile.Hunger >= 100) - { - if (profile.Health - 30 <= 0) - { - profile.Health = 0; - profile.Alive = false; - return "Died from starvation and bleeding out"; - } - profile.Health -= 30; - return "Suffered from severe starvation and bleeding out"; - } - - if (profile.Thirst >= 100) - { - if (profile.Health - 40 <= 0) - { - profile.Health = 0; - profile.Alive = false; - return "Died from dehydration and bleeding out"; - } - profile.Health -= 20; - return "Suffered from severe dehydration and bleeding out"; - } - } - - if (profile.Bleeding) - { - if (profile.Health - 20 <= 0) - { - profile.Health = 0; - profile.Alive = false; - return "Bled out and died"; - } - profile.Health -= 20; - return "Suffered from bleeding"; - } - - return null; - } - - private void HungerAndOrThirst(){} - } -} diff --git a/Hanekawa/Bot/Services/Game/HungerGames/HungerGameService.cs b/Hanekawa/Bot/Services/Game/HungerGames/HungerGameService.cs deleted file mode 100644 index 43e0c3f1..00000000 --- a/Hanekawa/Bot/Services/Game/HungerGames/HungerGameService.cs +++ /dev/null @@ -1,579 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Disqord.Rest; -using Hanekawa.Bot.Services.Economy; -using Hanekawa.Bot.Services.ImageGen; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Extensions; -using Hanekawa.Shared.Game.HungerGame; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using Quartz; -using Quartz.Util; - -namespace Hanekawa.Bot.Services.Game.HungerGames -{ - public class HungerGameService : INService, IRequired, IJob - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly CurrencyService _currency; - private readonly ImageGenerator _image; - private readonly HungerGame _game; - private readonly IServiceProvider _provider; - - public HungerGameService(Hanekawa client, IServiceProvider provider, ImageGenerator image, HungerGame game, CurrencyService currency) - { - _client = client; - _provider = provider; - _image = image; - _game = game; - _currency = currency; - _log = LogManager.GetCurrentClassLogger(); - - _client.ReactionAdded += AddParticipant; - _client.ReactionRemoved += RemoveParticipant; - _client.MemberLeft += RemoveParticipant; - _client.MemberUpdated += UpdateNameAndAvatar; - } - - private Task UpdateNameAndAvatar(MemberUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var status = await db.HungerGameStatus.FindAsync(e.NewMember.Guild.Id.RawValue); - if (status == null) return; - var profile = - await db.HungerGameProfiles.FindAsync(e.NewMember.Guild.Id.RawValue, e.NewMember.Id.RawValue); - if (profile == null) return; - profile.Name = e.NewMember.DisplayName; - profile.Avatar = e.NewMember.GetAvatarUrl(ImageFormat.Png); - await db.SaveChangesAsync(); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(Hunger Game Service) Crash when updating participant avatar or name - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task AddParticipant(ReactionAddedEventArgs e) - { - _ = Task.Run(async () => - { - if (!e.User.HasValue) return; - if (e.User.Value.IsBot) return; - if (!(e.User.Value is CachedMember user)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var status = await db.HungerGameStatus.FindAsync(user.Guild.Id.RawValue); - if (status == null) return; - if (status.Stage != HungerGameStage.Signup) return; - if (!LocalCustomEmoji.TryParse(status.EmoteMessageFormat, out var result)) return; - if (e.Emoji.MessageFormat != result.MessageFormat) return; - var dbUser = await db.HungerGameProfiles.FindAsync(user.Guild.Id.RawValue, user.Id.RawValue); - if (dbUser != null) return; - await db.HungerGameProfiles.AddAsync(new HungerGameProfile - { - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Name = user.DisplayName, - Avatar = user.GetAvatarUrl(ImageFormat.Png), - Bot = false, - Alive = true, - Health = 100, - Stamina = 100, - Bleeding = false, - Hunger = 100, - Thirst = 100, - Tiredness = 0, - Move = 0, - Water = 0, - Bullets = 0, - FirstAid = 0, - Food = 0, - MeleeWeapon = 0, - RangeWeapon = 0, - Weapons = 0 - }); - await db.SaveChangesAsync(); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(Hunger Game Service) Crash when adding user - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task RemoveParticipant(MemberLeftEventArgs e) - { - _ = Task.Run(async () => - { - try - { - if (e.User.IsBot) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var status = await db.HungerGameStatus.FindAsync(e.Guild.Id.RawValue); - if (status == null) return; - var dbUser = await db.HungerGameProfiles.FindAsync(e.Guild.Id.RawValue, e.User.Id.RawValue); - if (dbUser == null) return; - switch (status.Stage) - { - case HungerGameStage.OnGoing: - dbUser.Health = 0; - dbUser.Alive = false; - dbUser.Avatar = e.Guild.GetIconUrl(ImageFormat.Png); - await db.SaveChangesAsync(); - break; - case HungerGameStage.Signup: - db.HungerGameProfiles.Remove(dbUser); - await db.SaveChangesAsync(); - break; - case HungerGameStage.Closed: - break; - default: - break; - } - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(Hunger Game Service) Crash when removing user - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task RemoveParticipant(ReactionRemovedEventArgs e) - { - _ = Task.Run(async () => - { - try - { - if (!e.User.HasValue) return; - if (e.User.Value.IsBot) return; - if (!(e.User.Value is CachedMember user)) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var status = await db.HungerGameStatus.FindAsync(user.Guild.Id.RawValue); - if (status == null) return; - if (status.Stage != HungerGameStage.Signup) return; - var dbUser = await db.HungerGameProfiles.FindAsync(user.Guild.Id.RawValue, user.Id.RawValue); - if (dbUser == null) return; - db.HungerGameProfiles.Remove(dbUser); - await db.SaveChangesAsync(); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(Hunger Game Service) Crash when removing user - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - public Task Execute(IJobExecutionContext context) - { - _ = Task.Run(async () => - { - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var list = await db.GuildConfigs.Where(x => x.Premium).ToListAsync(); - foreach (var x in list) - { - var cfg = await db.HungerGameStatus.FindAsync(x.GuildId); - if (cfg == null) continue; - if (!cfg.EventChannel.HasValue) continue; - if (!cfg.SignUpChannel.HasValue) continue; - switch (cfg.Stage) - { - case HungerGameStage.Signup: - await StartGameAsync(cfg, db); - break; - case HungerGameStage.OnGoing: - await NextRoundAsync(cfg, db); - break; - case HungerGameStage.Closed: - await StartSignUpAsync(cfg, db); - break; - default: - continue; - } - - await db.SaveChangesAsync(); - } - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Hunger Game Service) Error executing Hunger Games - {e.Message}"); - } - }); - return Task.CompletedTask; - } - - public async Task StartSignUpAsync(HungerGameStatus cfg, DbService db) - { - if (!LocalCustomEmoji.TryParse(cfg.EmoteMessageFormat, out var result)) return; - if (!cfg.SignUpChannel.HasValue) return; - if (result == null) return; - cfg.Stage = HungerGameStage.Signup; - cfg.SignUpStart = DateTimeOffset.UtcNow; - var msgContent = "New Hunger Game event has started!\n" + - $"To enter, react to this message with {result} !"; - RestUserMessage msg; - try - { - msg = await _client.GetGuild(cfg.GuildId).GetTextChannel(cfg.SignUpChannel.Value).SendMessageAsync(msgContent); - await msg.AddReactionAsync(result); - } - catch - { - cfg.EmoteMessageFormat = "<:Rooree:761209568365248513>"; - LocalCustomEmoji.TryParse("<:Rooree:761209568365248513>", out result); - msg = await _client.GetGuild(cfg.GuildId).GetTextChannel(cfg.SignUpChannel.Value).SendMessageAsync(msgContent); - await msg.AddReactionAsync(result); - } - await db.SaveChangesAsync(); - } - - public async Task StartGameAsync(HungerGameStatus cfg, DbService db, bool test = false) - { - var cd = cfg.SignUpStart.AddHours(-3); - if (!test && cd.AddHours(23) >= DateTimeOffset.UtcNow) return false; - var guild = _client.GetGuild(cfg.GuildId); - cfg.Stage = HungerGameStage.OnGoing; - var participants = await AddDefaultUsers(db, guild); - if (cfg.SignUpChannel.HasValue) - { - var messages = new List(); - var sb = new StringBuilder(); - sb.AppendLine("Sign up is closed and here's the participants for current Hunger Games!"); - for (var i = 0; i < participants.Count;) - { - for (var j = 0; j < 5; j++) - { - var x = participants[i]; - switch (j) - { - case 4: - sb.Append($"**{x.Name}**"); - break; - default: - sb.Append($"**{x.Name}** - "); - break; - } - i++; - } - - sb.AppendLine(); - if (sb.Length < 1800) continue; - messages.Add(sb.ToString()); - sb.Clear(); - } - if(sb.Length > 0) messages.Add(sb.ToString()); - var channel = guild.GetTextChannel(cfg.SignUpChannel.Value); - if (channel != null) - { - for (var i = 0; i < messages.Count; i++) - { - var x = messages[i]; - await channel.SendMessageAsync(x, false, null, LocalMentions.None); - } - } - - if (cfg.EventChannel.HasValue && channel != null) - { - var evtChan = guild.GetTextChannel(cfg.EventChannel.Value); - if (evtChan != null) await channel.SendMessageAsync($"Game starts in {evtChan.Mention}", false, null, LocalMentions.None); - } - } - - await db.HungerGames.AddAsync(new Database.Tables.Account.HungerGame.HungerGame - { - Id = Guid.NewGuid(), - GuildId = cfg.GuildId, - Alive = participants.Count, - Participants = participants.Count, - Round = 0 - }); - await db.SaveChangesAsync(); - var check = await db.HungerGames.FirstOrDefaultAsync(x => x.GuildId == cfg.GuildId); - if (check == null) return true; - cfg.GameId = check.Id; - return true; - } - - public async Task NextRoundAsync(HungerGameStatus cfg, DbService db) - { - var guild = _client.GetGuild(cfg.GuildId); - if (guild == null) return; - // Total participants - var participants = await db.HungerGameProfiles - .Where(x => x.GuildId == cfg.GuildId) - .OrderByDescending(x => x.Alive) - .ThenBy(x => x.Bot) - .ThenBy(x => x.UserId) - .ToListAsync(); - var game = await db.HungerGames.FirstOrDefaultAsync(x => x.GuildId == cfg.GuildId); - var alive = participants.Count(x => x.Alive); - cfg.GameId ??= game.Id; - // Determine each participant event (alive) - var result = _game.PlayAsync(participants); - if (!cfg.EventChannel.HasValue) return; - - var sb = new StringBuilder(); - sb.AppendLine($"**Hunger Game Round {game.Round + 1}!**"); - var messages = new List(); - - // Create text messages - for (var i = 0; i < result.Count; i++) - { - var x = result[i]; - if(!x.BeforeProfile.Alive) continue; - if(x.Message.IsNullOrWhiteSpace()) continue; - var msg = $"**{x.AfterProfile.Name}**: {x.Message}"; - - // var msg = !x.AfterProfile.Bot - // ? $"**{guild.GetMember(x.AfterProfile.UserId).DisplayName ?? "User Left Server"}**: {x.Message}" - // : $"**{x.AfterProfile.Name}**: {x.Message}"; - if (sb.Length + msg.Length >= 2000) - { - messages.Add(sb.ToString()); - sb.Clear(); - sb.AppendLine(msg); - } - else sb.AppendLine(msg); - } - if(sb.Length > 0) messages.Add(sb.ToString()); - - // Generate banners - var tempPart = result.ToList(); - - var imgCount = Math.Ceiling((double) alive / 25); - if (imgCount == 0) imgCount = 1; - var channel = guild.GetTextChannel(cfg.EventChannel.Value); - // Make and send images - for (var i = 0; i < imgCount; i++) - { - var toTake = tempPart.Count >= 25 ? 25 : tempPart.Count; - var amount = tempPart.Take(toTake).OrderByDescending(x => x.BeforeProfile.Alive).ToList(); - tempPart.RemoveRange(0, toTake); - var image = await _image.GenerateEventImageAsync(guild, amount, alive); - await channel.SendMessageAsync(new LocalAttachment(image, "HungerGame.png", false), null, false, - null, LocalMentions.None); - } - - // Send Text - for (var i = 0; i < messages.Count; i++) - { - try - { - await channel.SendMessageAsync(messages[i], false, null, LocalMentions.None); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, e.Message); - } - } - - var resultAlive = result.Count(x => x.AfterProfile.Alive); - game.Alive = resultAlive; - game.Round++; - await db.SaveChangesAsync(); - // Only 1 person alive? Announce and reward - if (resultAlive > 1) return; - IMember user = null; - var winner = result.FirstOrDefault(x => x.AfterProfile.Alive); - if (winner != null && !winner.AfterProfile.Bot) - { - user = await guild.GetOrFetchMemberAsync(winner.AfterProfile.UserId); - var userData = await db.GetOrCreateUserData(winner.AfterProfile.GuildId, winner.AfterProfile.UserId); - userData.Exp += cfg.ExpReward; - userData.Credit += cfg.CreditReward; - userData.CreditSpecial += cfg.SpecialCreditReward; - } - - if (!cfg.SignUpChannel.HasValue) - { - await db.SaveChangesAsync(); - return; - } - var announce = guild.GetTextChannel(cfg.SignUpChannel.Value); - var stringBuilder = new StringBuilder(); - if (user == null && !winner.AfterProfile.Bot) - { - stringBuilder.AppendLine("Couldn't find the winner soooo... new Hunger Game soon !"); - } - else if (winner.AfterProfile.Bot) - { - stringBuilder.AppendLine($"{winner.AfterProfile.Name} is the new Hunger Game Champion, unfortently its a bot so no rewards!"); - } - else - { - var role = await RewardRole(cfg, user as CachedMember); - stringBuilder.AppendLine($"{user.Mention} is the new Hunger Game Champion!"); - stringBuilder.AppendLine("They have been rewarded with the following:"); - var currencyCfg = await db.GetOrCreateCurrencyConfigAsync(guild.Id.RawValue); - if (cfg.ExpReward > 0) stringBuilder.AppendLine($"{cfg.ExpReward} exp"); - if (cfg.CreditReward > 0) stringBuilder.AppendLine($"{currencyCfg.CurrencyName}: {_currency.ToCurrency(currencyCfg, cfg.CreditReward)}"); - if (cfg.SpecialCreditReward > 0) stringBuilder.AppendLine($"{currencyCfg.SpecialCurrencyName}: {_currency.ToCurrency(currencyCfg, cfg.SpecialCreditReward, true)}"); - if (role != null) stringBuilder.AppendLine($"{role.Mention} role"); - } - - await announce.SendMessageAsync(stringBuilder.ToString(), false, null, LocalMentions.None); - try - { - await db.HungerGameHistories.AddAsync(new HungerGameHistory - { - GameId = cfg.GameId.Value, - GuildId = cfg.GuildId, - Winner = winner.AfterProfile.UserId, - CreditReward = cfg.CreditReward, - SpecialCreditReward = cfg.SpecialCreditReward, - ExpReward = cfg.ExpReward - }); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Hunger Game Service) Couldn't add game history - {e.Message}"); - } - db.HungerGameProfiles.RemoveRange(participants); - db.HungerGames.Remove(game); - cfg.Stage = HungerGameStage.Closed; - cfg.GameId = null; - await db.SaveChangesAsync(); - } - - private async Task RewardRole(HungerGameStatus cfg, CachedMember winner) - { - if (!cfg.RoleReward.HasValue) return null; - var role = winner.Guild.GetRole(cfg.RoleReward.Value); - if (role == null) return null; - var toRemove = winner.Guild.Members.Where(x => x.Value.Roles.ContainsKey(role.Id)).ToList(); - foreach (var x in toRemove) - { - try - { - await x.Value.RevokeRoleAsync(role.Id); - } - catch { /* IGNORE */} - } - - try - { - await winner.GrantRoleAsync(role.Id); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Hunger Game Service) Couldn't grant winner role - {e.Message}"); - return null; - } - return role; - } - - private async Task> AddBoosters(DbService db, List participants, CachedGuild guild) - { - var toReturn = new List(); - foreach (var (key, user) in guild.Members.Where(x => x.Value.IsBoosting).ToList()) - { - var check = await db.HungerGameProfiles.FindAsync(guild.Id.RawValue, user.Id.RawValue); - if(check != null) continue; - toReturn.Add(new HungerGameProfile - { - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Name = user.Name, - Avatar = user.GetAvatarUrl(ImageFormat.Png), - Bot = false, - Alive = true, - Health = 100, - Stamina = 100, - Bleeding = false, - Hunger = 100, - Thirst = 100, - Tiredness = 0, - Move = 0, - Water = 0, - Bullets = 0, - FirstAid = 0, - Food = 0, - MeleeWeapon = 0, - RangeWeapon = 0, - Weapons = 0 - }); - } - - return toReturn; - } - - private async Task> AddDefaultUsers(DbService db, CachedGuild guild) - { - var toAdd = 0; - var profiles = await db.HungerGameProfiles.Where(x => x.GuildId == guild.Id.RawValue).ToListAsync(); - var boosters = await AddBoosters(db, profiles, guild); - profiles.AddRange(boosters); - await db.HungerGameProfiles.AddRangeAsync(boosters); - if (profiles.Count == 0) toAdd = 25; - else if (profiles.Count <= 25) toAdd = 25 - profiles.Count; - else - { - toAdd = (Convert.ToInt32(25 * Math.Ceiling((double) (profiles.Count / 25))) - profiles.Count); - if (toAdd < 0) - toAdd = Convert.ToInt32(25 * Math.Ceiling((double) ((profiles.Count + 13) / 25))) - profiles.Count; - } - - var defaults = await db.HungerGameDefaults.Take(toAdd).ToListAsync(); - var toAddefaults = new List(); - for (var i = 0; i < defaults.Count; i++) - { - var x = defaults[i]; - toAddefaults.Add(new HungerGameProfile - { - GuildId = guild.Id.RawValue, - UserId = x.Id, - Name = x.Name, - Avatar = x.Avatar, - Bot = true, - Alive = true, - Health = 50, - Stamina = 100, - Bleeding = false, - Hunger = 100, - Thirst = 100, - Tiredness = 0, - Move = 0, - Water = 0, - Bullets = 0, - FirstAid = 0, - Food = 0, - MeleeWeapon = 0, - RangeWeapon = 0, - Weapons = 0 - }); - } - - profiles.AddRange(toAddefaults); - await db.HungerGameProfiles.AddRangeAsync(toAddefaults); - await db.SaveChangesAsync(); - return profiles; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/Ship/Calculation.cs b/Hanekawa/Bot/Services/Game/Ship/Calculation.cs deleted file mode 100644 index d5da5e80..00000000 --- a/Hanekawa/Bot/Services/Game/Ship/Calculation.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using System.Threading.Tasks; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.BotGame; -using Hanekawa.Shared.Game; - -namespace Hanekawa.Bot.Services.Game.Ship -{ - public partial class ShipGameService - { - private int DefaultHealth { get; } = 10; - private int DefaultDamage { get; } = 1; - - private async Task GetClass(int classId, DbService db) => - await db.GameClasses.FindAsync(classId); - - private int GetHealth(int level, GameClass ass) => - Convert.ToInt32(Math.Round(DefaultHealth * level * ass.ModifierHealth)); - - private int GetHealth(int level, GameEnemy enemyData, GameClass enemyClass) => - Convert.ToInt32(Math.Round((DefaultHealth + enemyData.Health) * level * - enemyClass.ModifierHealth)); - - private int GetDamage(int level) => DefaultDamage * level; - - private int GetDamage(int level, GameEnemy enemyData) => (DefaultDamage + enemyData.Damage) * level; - - private int CalculateDamage(int damage, GameClass attackerClass, GameClass enemyClass, EnemyType type) - { - var avoid = _random.Next(100); - var crit = _random.Next(100); - if (type == EnemyType.Player) - if (avoid <= enemyClass.ChanceAvoid) - return 0; - if (crit <= attackerClass.ChanceCrit) - damage = Convert.ToInt32(damage * attackerClass.ModifierCriticalChance); - var lowDmg = damage / 2; - if (lowDmg <= 0) lowDmg = 5; - var highDmg = damage * 2; - if (lowDmg >= highDmg) highDmg = lowDmg + 10; - damage = new Random().Next(lowDmg, highDmg); - - return damage; - } -/* - private async Task Health(DbService db, int level, SocketGuildUser user) - { - var userdata = await db.GetOrCreateUserData(user); - return _gameStats.GetHealth(level, await GetClass(db, userdata.Class)); - } - - private async Task Health(DbService db, int level, GameEnemy enemy) => - _gameStats.GetHealth(level, enemy, await GetClass(db, enemy.ClassId)); - - private int Damage(int level) => _gameStats.GetDamage(level); - - private int Damage(int level, GameEnemy enemy) => _gameStats.GetDamage(level, enemy); - */ - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/Ship/ShipData.cs b/Hanekawa/Bot/Services/Game/Ship/ShipData.cs deleted file mode 100644 index 7e21b9df..00000000 --- a/Hanekawa/Bot/Services/Game/Ship/ShipData.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Collections.Concurrent; -using Hanekawa.Database.Tables.BotGame; -using Microsoft.Extensions.Caching.Memory; - -namespace Hanekawa.Bot.Services.Game.Ship -{ - public partial class ShipGameService - { - private readonly ConcurrentDictionary _existingBattles - = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary _activeBattles - = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary _activeDuels - = new ConcurrentDictionary(); - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Game/Ship/ShipGameService.cs b/Hanekawa/Bot/Services/Game/Ship/ShipGameService.cs deleted file mode 100644 index bc7cbf97..00000000 --- a/Hanekawa/Bot/Services/Game/Ship/ShipGameService.cs +++ /dev/null @@ -1,541 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Services.Achievement; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Bot.Services.ImageGen; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Database.Tables.BotGame; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Command.Extensions; -using Hanekawa.Shared.Game; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Game.Ship -{ - public partial class ShipGameService : INService - { - private readonly ColourService _colourService; - private readonly ExpService _exp; - private readonly ImageGenerator _img; - private readonly Random _random; - private readonly AchievementService _achievement; - private readonly NLog.Logger _log; - private readonly IServiceProvider _provider; - - public ShipGameService(Random random, ImageGenerator img, ExpService exp, ColourService colourService, AchievementService achievement, IServiceProvider provider) - { - _random = random; - _img = img; - _exp = exp; - _colourService = colourService; - _achievement = achievement; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = db.GameConfigs.Find(1); - if (cfg != null) - { - DefaultDamage = cfg.DefaultDamage; - DefaultHealth = cfg.DefaultHealth; - } - } - - public async Task SearchAsync(DiscordCommandContext context) - { - if (IsInBattleOrDuel(context)) - return new LocalEmbedBuilder().Create($"{context.User.Mention} is already in a fight", - Color.Red); - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var userData = await db.GetOrCreateUserData(context.Member); - var chance = _random.Next(100); - GameEnemy enemy; - /* - if (chance >= 95) - { - var enemies = await db.GameEnemies.Where(x => x.Rare).ToListAsync(); - enemy = enemies[new Random().Next(enemies.Count)]; - } - else if (chance >= 90) - { - var enemies = await db.GameEnemies.Where(x => x.Elite).ToListAsync(); - enemy = enemies[new Random().Next(enemies.Count)]; - } - */ - if (chance >= 40) - { - var enemies = await db.GameEnemies.Where(x => !x.Elite && !x.Rare).ToListAsync(); - enemy = enemies[_random.Next(enemies.Count)]; - } - else - { - return new LocalEmbedBuilder().Create( - $"{context.User.Mention} searched throughout the sea and found no enemy", - Color.Red); - } - - AddBattle(context, enemy); - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder {IconUrl = enemy.ImageUrl, Name = enemy.Name}, - Description = "You encountered an enemy!\n" + - $"{enemy.Name}", - Color = Color.Green - }; - var enemyClass = await GetClass(enemy.ClassId, db); - var health = GetHealth(userData.Level, enemy, enemyClass); - embed.AddField("Type", $"{enemyClass.Name}", true); - embed.AddField("Health", $"{health}", true); - embed.AddField("Level", $"{userData.Level}", true); - return embed; - } - - public async Task AttackAsync(HanekawaCommandContext context) - { - if (!IsInBattleOrDuel(context)) - { - await context.ReplyAsync($"{context.User.Mention} isn't in a fight or duel", Color.Red); - return; - } - - if (OnGoingBattleOrDuel(context)) - { - await context.ReplyAsync($"{context.User.Mention}, a fight or duel is already in progress, please wait.", - Color.Red); - return; - } - - StartBattle(context); - var enemy = GetEnemyData(context); - var playerOneHp = 0; - var playerTwoHp = 0; - var playerOneDmg = 0; - var playerTwoDmg = 0; - var playerOneHpMax = 0; - var playerTwoHpMax = 0; - GameClass playerOne = null; - GameClass playerTwo = null; - - using var scope = _provider.CreateScope(); - await using (var db = scope.ServiceProvider.GetRequiredService()) - { - var userData = await db.GetOrCreateUserData(context.Member); - playerOne = await GetClass(userData.Class, db); - playerTwo = await GetClass(enemy.ClassId, db); - playerOneHp = GetHealth(userData.Level, playerOne); - playerTwoHp = GetHealth(userData.Level, enemy, playerTwo); - playerOneDmg = GetDamage(userData.Level); - playerTwoDmg = GetDamage(userData.Level, enemy); - playerOneHpMax = GetHealth(userData.Level, playerOne); - playerTwoHpMax = GetHealth(userData.Level, enemy, playerTwo); - } - - var msgLog = new LinkedList(); - msgLog.AddFirst($"**{context.Member.DisplayName}** VS **{enemy.Name}**"); - - var img = await _img.ShipGameBuilder(context.User.GetAvatarUrl(ImageFormat.Png), enemy.ImageUrl); - img.Seek(0, SeekOrigin.Begin); - var embed = new LocalEmbedBuilder().Create(UpdateCombatLog(msgLog), _colourService.Get(context.Guild.Id.RawValue)); - embed.AddField($"{context.Member.DisplayName}", $"{playerOneHp}/{playerOneHpMax}", true); - embed.AddField($"{enemy.Name}", $"{playerTwoHp}/{playerTwoHpMax}", true); - var msg = await context.Channel.SendMessageAsync(new LocalAttachment(img, "banner.png"), null, false, embed.Build()); - var alive = true; - await Task.Delay(2000); - while (alive) - { - var usrDmg = CalculateDamage(playerOneDmg, playerOne, playerTwo, EnemyType.Npc); - var npcDmg = CalculateDamage(playerTwoDmg, playerTwo, playerTwo, EnemyType.Player); - - playerTwoHp -= usrDmg; - if (playerTwoHp >= 0) - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst( - $"**{context.Member.DisplayName}** hit **{enemy.Name}** for **{usrDmg}**"); - } - else - { - msgLog.AddFirst( - $"**{context.Member.DisplayName}** hit **{enemy.Name}** for **{usrDmg}**"); - } - } - else - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst( - $"**{context.Member.DisplayName}** hit **{enemy.Name}** for **{usrDmg}**"); - } - else - { - msgLog.AddFirst( - $"**{context.Member.DisplayName}** hit **{enemy.Name}** for **{usrDmg}**"); - } - - // End game - alive = false; - - msgLog.RemoveLast(); - msgLog.AddFirst($"**{context.Member.DisplayName}** defeated **{enemy.Name}**!\n" + - $"Looted **${enemy.CreditGain}** and gained **{enemy.ExpGain}** exp."); - RemoveBattle(context); - await using (var db = scope.ServiceProvider.GetRequiredService()) - { - var userData = await db.GetOrCreateUserData(context.Member); - await _exp.AddExpAsync(context.Member, userData, enemy.ExpGain, enemy.CreditGain, db); - userData.GameKillAmount += 1; - await db.SaveChangesAsync(); - await _achievement.PveKill(context.Member, db); - } - - embed.Color = Color.Green; - embed.Description = UpdateCombatLog(msgLog.Reverse()); - var userField = embed.Fields.First(x => x.Name == $"{context.Member.DisplayName}"); - var enemyField = embed.Fields.First(x => x.Name == $"{enemy.Name}"); - userField.Value = $"{playerOneHp}/{playerOneHpMax}"; - enemyField.Value = $"0/{playerTwoHpMax}"; - await msg.ModifyAsync(x => x.Embed = embed.Build()); - continue; - } - - playerOneHp -= npcDmg; - if (playerOneHp >= 0 && alive) - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst( - $"**{enemy.Name}** hit **{context.Member.DisplayName}** for **{npcDmg}**"); - } - else - { - msgLog.AddFirst( - $"**{enemy.Name}** hit **{context.Member.DisplayName}** for **{npcDmg}**"); - } - } - else - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst( - $"**{enemy.Name}** hit **{context.Member.DisplayName}** for **{npcDmg}**"); - } - else - { - msgLog.AddFirst( - $"**{enemy.Name}** hit **{context.Member.DisplayName}** for **{npcDmg}**"); - } - - // End game - alive = false; - - msgLog.RemoveLast(); - msgLog.AddFirst($"**{enemy.Name}** defeated **{context.Member.DisplayName}**!\n" + - $"**{context.Member.DisplayName}** died."); - RemoveBattle(context); - embed.Color = Color.Red; - embed.Description = UpdateCombatLog(msgLog.Reverse()); - var userField = embed.Fields.First(x => x.Name == $"{context.Member.DisplayName}"); - var enemyField = embed.Fields.First(x => x.Name == $"{enemy.Name}"); - userField.Value = $"0/{playerOneHpMax}"; - enemyField.Value = $"{playerTwoHp}/{playerTwoHpMax}"; - await msg.ModifyAsync(x => x.Embed = embed.Build()); - } - - if (!alive) continue; - { - embed.Description = UpdateCombatLog(msgLog.Reverse()); - var userField = embed.Fields.First(x => x.Name == $"{context.Member.DisplayName}"); - var enemyField = embed.Fields.First(x => x.Name == $"{enemy.Name}"); - userField.Value = $"{playerOneHp}/{playerOneHpMax}"; - enemyField.Value = $"{playerTwoHp}/{playerTwoHpMax}"; - await msg.ModifyAsync(x => x.Embed = embed.Build()); - } - await Task.Delay(2000); - } - - RemoveBattle(context); - _log.Log(LogLevel.Info, "(Ship Game) Completed game"); - } - - public async Task AttackAsync(HanekawaCommandContext context, CachedMember playerTwoUser, int? bet = 0) - { - if (OnGoingBattleOrDuel(context)) - { - await context.ReplyAsync($"{context.User.Mention}, a fight is already in progress, please wait.", - Color.Red); - return; - } - - try - { - AddDuel(context, playerTwoUser); - Account userData; - Account userData2; - var p1Name = context.Member.DisplayName; - var p2Name = playerTwoUser.DisplayName; - int playerOneHp; - int playerTwoHp; - int playerOneDmg; - int playerTwoDmg; - int playerOneHpMax; - int playerTwoHpMax; - GameClass playerOne; - GameClass playerTwo; - Account winner = null; - Account loser = null; - - using var scope = _provider.CreateScope(); - await using (var db = scope.ServiceProvider.GetRequiredService()) - { - userData = await db.GetOrCreateUserData(context.Member); - userData2 = await db.GetOrCreateUserData(playerTwoUser); - if (userData.Credit < bet) return; - if (userData2.Credit < bet) return; - playerOne = await GetClass(userData.Class, db); - playerTwo = await GetClass(userData2.Class, db); - playerOneHp = GetHealth(userData.Level, playerOne); - playerTwoHp = GetHealth(userData.Level, playerTwo); - playerOneDmg = GetDamage(userData.Level); - playerTwoDmg = GetDamage(userData.Level); - playerOneHpMax = GetHealth(userData.Level, playerOne); - playerTwoHpMax = GetHealth(userData.Level, playerTwo); - } - - var msgLog = new LinkedList(); - msgLog.AddFirst($"**{p1Name}** VS **{p2Name}**"); - - var img = await _img.ShipGameBuilder(context.User.GetAvatarUrl(ImageFormat.Png), playerTwoUser.GetAvatarUrl(ImageFormat.Png)); - img.Seek(0, SeekOrigin.Begin); - var embed = new LocalEmbedBuilder().Create(UpdateCombatLog(msgLog), _colourService.Get(context.Guild.Id.RawValue)); - - embed.AddField($"{p1Name}", $"{playerOneHp}/{playerOneHpMax}", true); - embed.AddField($"{p2Name}", $"{playerTwoHp}/{playerTwoHpMax}", true); - var msg = await context.Channel.SendMessageAsync(new LocalAttachment(img, "banner.png"), null, false, embed.Build()); - var alive = true; - while (alive) - { - var playerOneDamage = CalculateDamage(playerOneDmg, playerOne, playerTwo, EnemyType.Player); - var playerTwoDamage = CalculateDamage(playerTwoDmg, playerTwo, playerTwo, EnemyType.Player); - - playerTwoHp -= playerOneDamage; - if (playerTwoHp > 0) - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst($"**{p1Name}** hit **{p2Name}** for **{playerOneDamage}**"); - } - else - { - msgLog.AddFirst($"**{p1Name}** hit **{p2Name}** for **{playerOneDamage}**"); - } - } - else - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst($"**{p1Name}** hit **{p2Name}** for **{playerOneDamage}**"); - } - else - { - msgLog.AddFirst($"**{p1Name}** hit **{p2Name}** for **{playerOneDamage}**"); - } - - // End game - alive = false; - if (bet != 0) - { - msgLog.AddFirst( - $"**{context.User.Mention}** defeated **{playerTwoUser.Mention}** and won the bet of ${bet}!"); - winner = userData; - loser = userData2; - } - else - { - winner = userData; - loser = userData2; - msgLog.AddFirst($"**{context.User.Mention}** defeated **{playerTwoUser.Mention}**!"); - } - - embed.Color = Color.Green; - embed.Description = UpdateCombatLog(msgLog.Reverse()); - var userField = embed.Fields.First(x => x.Name == $"{p1Name}"); - var enemyField = embed.Fields.First(x => x.Name == $"{p2Name}"); - userField.Value = $"{playerOneHp}/{playerOneHpMax}"; - enemyField.Value = $"0/{playerTwoHpMax}"; - await msg.ModifyAsync(x => x.Embed = embed.Build()); - continue; - } - - playerOneHp -= playerTwoDamage; - if (playerOneHp > 0 && alive) - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst($"**{p2Name}** hit **{p1Name}** for **{playerTwoDamage}**"); - } - else - { - msgLog.AddFirst($"**{p2Name}** hit **{p1Name}** for **{playerTwoDamage}**"); - } - } - else - { - if (msgLog.Count == 5) - { - msgLog.RemoveLast(); - msgLog.AddFirst($"**{p2Name}** hit **{p1Name}** for **{playerTwoDamage}**"); - } - else - { - msgLog.AddFirst($"**{p2Name}** hit **{p1Name}** for **{playerTwoDamage}**"); - } - - // End game - alive = false; - if (bet != 0) - { - msgLog - .AddFirst( - $"**{playerTwoUser.Mention}** defeated **{context.User.Mention}** and won the bet of ${bet}!"); - loser = userData; // Loser - winner = userData2; // Winner - } - else - { - winner = userData; - loser = userData2; - msgLog.AddFirst($"**{playerTwoUser.Mention}** defeated **{context.User.Mention}**!"); - } - - embed.Color = Color.Green; - embed.Description = UpdateCombatLog(msgLog.Reverse()); - var userField = embed.Fields.First(x => x.Name == $"{p1Name}"); - var enemyField = embed.Fields.First(x => x.Name == $"{p2Name}"); - userField.Value = $"0/{playerOneHpMax}"; - enemyField.Value = $"{playerTwoHp}/{playerTwoHpMax}"; - await msg.ModifyAsync(x => x.Embed = embed.Build()); - } - - if (!alive) continue; - { - embed.Description = UpdateCombatLog(msgLog.Reverse()); - var userField = embed.Fields.First(x => x.Name == $"{p1Name}"); - var enemyField = embed.Fields.First(x => x.Name == $"{p2Name}"); - userField.Value = $"{playerOneHp}/{playerOneHpMax}"; - enemyField.Value = $"{playerTwoHp}/{playerTwoHpMax}"; - await msg.ModifyAsync(x => x.Embed = embed.Build()); - } - await Task.Delay(2000); - } - - if (bet.HasValue && bet != 0) - { - await using (var db = scope.ServiceProvider.GetRequiredService()) - { - winner.Credit += bet.Value; - loser.Credit -= bet.Value; - await db.SaveChangesAsync(); - await _achievement.PvpKill(winner.UserId, winner.GuildId, db); - } - } - - RemoveDuel(context, playerTwoUser); - _log.Log(LogLevel.Info, "(Ship Game) Completed duel"); - } - catch(Exception e) - { - RemoveDuel(context, playerTwoUser); - _log.Log(NLog.LogLevel.Error, e, "(Ship Game) Duel failed"); - } - } - - private GameEnemy GetEnemyData(DiscordCommandContext context) - { - var battles = _activeBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - battles.TryGetValue(context.User.Id.RawValue, out var game); - return game as GameEnemy; - } - - private bool IsInBattleOrDuel(DiscordCommandContext context) - { - var battles = _activeBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (battles.TryGetValue(context.User.Id.RawValue, out _)) return true; - var duels = _activeDuels.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (duels.TryGetValue(context.User.Id.RawValue, out _)) return true; - return false; - } - - private bool OnGoingBattleOrDuel(DiscordCommandContext context) - { - var ongoing = _existingBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - return ongoing.TryGetValue(context.Channel.Id.RawValue, out _); - } - - private void AddBattle(DiscordCommandContext context, GameEnemy enemy) - { - var battles = _activeBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - battles.Set(context.User.Id.RawValue, enemy, TimeSpan.FromMinutes(10)); - } - - private void AddDuel(DiscordCommandContext context, CachedMember user) - { - var duels = _activeDuels.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - var existingBattles = - _existingBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - duels.Set(context.User.Id.RawValue, user.Id.RawValue, TimeSpan.FromMinutes(10)); - duels.Set(user.Id.RawValue, context.User.Id.RawValue, TimeSpan.FromMinutes(10)); - existingBattles.Set(context.Channel.Id.RawValue, true, TimeSpan.FromMinutes(10)); - } - - private void StartBattle(DiscordCommandContext context) - { - var existingBattles = - _existingBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - existingBattles.Set(context.Channel.Id.RawValue, true, TimeSpan.FromMinutes(10)); - } - - private void RemoveDuel(DiscordCommandContext context, CachedMember user) - { - var duels = _activeDuels.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - var existingBattles = - _existingBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - duels.Remove(context.User.Id.RawValue); - duels.Remove(user.Id.RawValue); - existingBattles.Remove(context.Channel.Id.RawValue); - } - - private void RemoveBattle(DiscordCommandContext context) - { - var existingBattles = - _existingBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - var battles = _activeBattles.GetOrAdd(context.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - existingBattles.Remove(context.Channel.Id.RawValue); - battles.Remove(context.User.Id.RawValue); - } - - private static string UpdateCombatLog(IEnumerable log) => string.Join("\n", log); - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Highlight/HighlightService.cs b/Hanekawa/Bot/Services/Highlight/HighlightService.cs deleted file mode 100644 index 9b253a3d..00000000 --- a/Hanekawa/Bot/Services/Highlight/HighlightService.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Hanekawa.Database; -using Hanekawa.Shared.Command; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Highlight -{ - public class HighlightService - { - private readonly Hanekawa _client; - private readonly IServiceProvider _provider; - - private readonly ConcurrentDictionary<(ulong, ulong), string[]> _highlights = - new ConcurrentDictionary<(ulong, ulong), string[]>(); - - public HighlightService(Hanekawa client, IServiceProvider provider) - { - _client = client; - _provider = provider; - - using var scope = _provider.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - { - foreach (var x in db.Highlights) - _highlights.TryAdd((x.GuildId, x.UserId), x.Highlights); - } - } - - public async Task Add(CachedMember user, string[] text) - { - var highlights = _highlights.GetOrAdd((user.Guild.Id.RawValue, user.Id.RawValue), text); - var newList = text.Where(x => !highlights.Contains(x)).ToList(); - var returnList = text.Where(x => highlights.Contains(x)).ToArray(); - if (newList.Count == 0) return returnList; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var highlightDb = await db.Highlights.FindAsync(user.Guild.Id.RawValue, user.Id.RawValue); - if (highlightDb == null) - { - await db.Highlights.AddAsync(new Database.Tables.Account.Highlight - { - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Highlights = newList.ToArray() - }); - } - else highlightDb.Highlights = newList.ToArray(); - - await db.SaveChangesAsync(); - _highlights.AddOrUpdate((user.Guild.Id.RawValue, user.Id.RawValue), newList.ToArray(), (tuple, strings) => newList.ToArray()); - return returnList; - } - - public async Task Remove(CachedMember user, string[] text) - { - if(!_highlights.TryGetValue((user.Guild.Id.RawValue, user.Id.RawValue), out var highlights)) return null; - var newList = text.Where(x => highlights.Contains(x)).ToList(); - var returnList = text.Where(x => !highlights.Contains(x)).ToArray(); - if (newList.Count == 0) return returnList; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var highlightDb = await db.Highlights.FindAsync(user.Guild.Id.RawValue, user.Id.RawValue); - - if (highlightDb == null && newList.Count > 0) - { - await db.Highlights.AddAsync(new Database.Tables.Account.Highlight - { - GuildId = user.Guild.Id.RawValue, - UserId = user.Id.RawValue, - Highlights = newList.ToArray() - }); - _highlights.AddOrUpdate((user.Guild.Id.RawValue, user.Id.RawValue), newList.ToArray(), (tuple, strings) => newList.ToArray()); - } - else if (highlightDb != null && newList.Count > 0) - { - highlightDb.Highlights = newList.ToArray(); - _highlights.AddOrUpdate((user.Guild.Id.RawValue, user.Id.RawValue), newList.ToArray(), (tuple, strings) => newList.ToArray()); - } - else if (highlightDb != null && newList.Count == 0) - { - db.Highlights.Remove(highlightDb); - } - - await db.SaveChangesAsync(); - return returnList; - } - } -} diff --git a/Hanekawa/Bot/Services/ImageGen/HungerGameImg.cs b/Hanekawa/Bot/Services/ImageGen/HungerGameImg.cs deleted file mode 100644 index 6d3bc07a..00000000 --- a/Hanekawa/Bot/Services/ImageGen/HungerGameImg.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Extensions; -using Hanekawa.Models.HungerGame; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Drawing.Processing; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; -using Color = SixLabors.ImageSharp.Color; - -namespace Hanekawa.Bot.Services.ImageGen -{ - public partial class ImageGenerator - { - public async Task GenerateSingleImageAsync(HungerGameProfile profile) - { - var stream = new MemoryStream(); - using (var img = new Image(550, 550)) - { - - } - - return stream; - } - - public async Task GenerateEventImageAsync(CachedGuild guild, List profile, int alive) - { - if (profile == null) throw new ArgumentNullException(nameof(profile)); - var result = new MemoryStream(); - using (var img = new Image(550, GetImageHeight(alive, out var iterate))) - { - var width = 0; - var height = 0; - var seat = 0; - var row = 0; - for (var i = 0; i < iterate; i++) - { - var x = profile[i]; - var points = GetBorderPointers(width, height); - var afterHpBar = GetHeathBar(width, height, x.AfterProfile.Health); - var beforeHpBar = GetHeathBar(width, height, x.BeforeProfile.Health); - Image avi; - try - { - avi = await GetAvatarAsync(x.AfterProfile.Avatar, new Size(80, 80), false, false); - } - catch - { - avi = await GetAvatarAsync(guild.GetIconUrl(ImageFormat.Png), new Size(80, 80), false, false); - x.AfterProfile.Avatar = guild.GetIconUrl(ImageFormat.Png); - } - if (x.AfterProfile.Health <= 0 && x.AfterProfile.Alive) x.AfterProfile.Alive = false; - - // Profile picture drawing - if (!x.AfterProfile.Alive) - { - var deathIcon = await _client.GetStreamAsync("https://i.imgur.com/eONxWtN.png"); - var response = deathIcon.ToEditable(); - response.Position = 0; - var death = await Image.LoadAsync(response, new PngDecoder()); - death.Mutate(z => z.Resize(80, 80)); - avi.Mutate(y => y - .BlackWhite() - .DrawImage(death, new Point(0, 0), new GraphicsOptions { Antialias = true })); - } - - // Health bar drawing - img.Mutate(a => a - .DrawImage(avi, new Point(20 + 108 * width, 6 + 111 * height), - new GraphicsOptions {Antialias = true}) - .FillPolygon(new SolidBrush(new Color(new Rgb24(30, 30, 30))), points)); - if (x.BeforeProfile.Alive) - { - img.Mutate(a => a.FillPolygon(new SolidBrush(Color.Red), beforeHpBar)); - if(x.AfterProfile.Alive) img.Mutate(a => a.FillPolygon(new SolidBrush(new Color(new Rgb24(46, 204, 113))), afterHpBar)); - } - - // Health text drawing - var healthTextLocation = GetHealthTextLocation(width, height); - var hp = $" {x.AfterProfile.Health} / 100"; - img.Mutate(a => a.DrawText(hp, _hgTimes, Color.White, healthTextLocation)); - - width++; - row++; - if (row != 5) continue; - height++; - row = 0; - width = 0; - seat++; - } - - await img.SaveAsync(result, new PngEncoder()); - } - - result.Position = 0; - return result; - } - - private static PointF[] GetBorderPointers(int seat, int row) - { - //Size of box - const int w1 = 10; - const int w2 = 110; - const int h1 = 86; - const int h2 = 101; - - var point1 = new PointF(w1 + seat * 108, h1 + row * 111); - var point2 = new PointF(w2 + seat * 108, h1 + row * 111); - - var point3 = new PointF(w2 + seat * 108, h2 + row * 111); - var point4 = new PointF(w1 + seat * 108, h2 + row * 111); - - var result = new[] { point1, point2, point3, point4 }; - return result; - } - - private static PointF[] GetHeathBar(int seat, int row, double health) - { - //Size of box - const int w1 = 10 + 3; - const int w2 = 110 - 3; - const int h1 = 86 + 2; - const int h2 = 101 - 2; - - health = 100 - health; - if (health < 0) health = 1; - if (health >= 100) health = 100; - - var point1 = new PointF(w1 + seat * 108, h1 + row * 111); - var point2 = new PointF((float)(w2 + seat * 108 - health), h1 + row * 111); - - var point3 = new PointF((float)(w2 + seat * 108 - health), h2 + row * 111); - var point4 = new PointF(w1 + seat * 108, h2 + row * 111); - - var result = new[] {point1, point2, point3, point4}; - return result; - } - - private static PointF GetHealthTextLocation(int seat, int row) - { - const int starterWidth = 10; - const int spacerWidth = 108; - const int starterHeight = 85; - const int spacerHeight = 111; - - return new PointF(starterWidth + seat * spacerWidth, starterHeight + row * spacerHeight); - } - - private static int GetImageHeight(int amount, out int iterate) - { - if (amount <= 5) - { - iterate = 5; - return 110; - } - if (amount <= 10) - { - iterate = 10; - return 220; - } - if (amount <= 15) - { - iterate = 15; - return 330; - } - if (amount <= 20) - { - iterate = 20; - return 440; - } - iterate = 25; - return 550; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/ImageGen/ImageGenerator.cs b/Hanekawa/Bot/Services/ImageGen/ImageGenerator.cs deleted file mode 100644 index c23e5ee2..00000000 --- a/Hanekawa/Bot/Services/ImageGen/ImageGenerator.cs +++ /dev/null @@ -1,177 +0,0 @@ -using Disqord; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Extensions; -using Hanekawa.Shared.Interfaces; -using Quartz.Util; -using SixLabors.Fonts; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Drawing.Processing; -using SixLabors.ImageSharp.Formats.Gif; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; -using System; -using System.Net.Http; -using System.Threading.Tasks; -using Hanekawa.Database.Tables.Config; - -namespace Hanekawa.Bot.Services.ImageGen -{ - public partial class ImageGenerator : INService - { - private readonly HttpClient _client; - private readonly ExpService _expService; - - // Fonts - private readonly FontCollection _fonts; - private readonly FontFamily _arial; - private readonly TextGraphicsOptions _leftText = new TextGraphicsOptions - { - GraphicsOptions = new GraphicsOptions - { - Antialias = true - }, - TextOptions = new TextOptions - { - HorizontalAlignment = HorizontalAlignment.Left - } - }; - private readonly TextGraphicsOptions _centerText = new TextGraphicsOptions - { - GraphicsOptions = new GraphicsOptions - { - Antialias = true - }, - TextOptions = new TextOptions - { - HorizontalAlignment = HorizontalAlignment.Center - } - }; - private readonly GraphicsOptions _options = new GraphicsOptions - { - Antialias = true - }; - - // Profile - private readonly Font _profileName; - private readonly Image _profileTemplate; - private readonly Font _profileText; - private readonly Random _random; - - private readonly TextGraphicsOptions _rightText = new TextGraphicsOptions - { - GraphicsOptions = new GraphicsOptions - { - Antialias = true - }, - TextOptions = new TextOptions - { - HorizontalAlignment = HorizontalAlignment.Right - } - }; - private readonly FontFamily _times; - - // Welcome - private readonly Image _welcomeTemplate; - private readonly WelcomeBanner _defWelcomeBanner; - - // Hunger Games - private readonly Font _hgTimes; - - public ImageGenerator(HttpClient client, Random random, ExpService expService) - { - _client = client; - _random = random; - _expService = expService; - - _fonts = new FontCollection(); - _times = _fonts.Install("Data/Fonts/TIMES.TTF"); - _arial = _fonts.Install("Data/Fonts/ARIAL.TTF"); - - _welcomeTemplate = Image.Load("Data/Welcome/Default.png", new PngDecoder {IgnoreMetadata = true }); - _defWelcomeBanner = new WelcomeBanner - { - AvatarSize = 60, - AviPlaceX = 10, - AviPlaceY = 10, - TextSize = 33, - TextPlaceX = 245, - TextPlaceY = 40, - IsNsfw = false - }; - - _profileText = new Font(_arial, 20, FontStyle.Regular); - _profileName = new Font(_arial, 32, FontStyle.Regular); - _profileTemplate = Image.Load("Data/Profile/Template/Template.png", new PngDecoder { IgnoreMetadata = true }); - - _hgTimes = new Font(_times, 15, FontStyle.Regular); - } - - private async Task GetAvatarAsync(CachedMember user, Size size, bool premium) - { - var url = user.GetAvatarUrl(); - var gif = user.AvatarHash != null && user.AvatarHash.StartsWith("a_"); - if (url.IsNullOrWhiteSpace()) - { - var restUser = await user.Guild.GetMemberAsync(user.Id); - gif = restUser.AvatarHash != null && restUser.AvatarHash.StartsWith("a_"); - url = restUser.GetAvatarUrl(); - } - - try - { - return await GetAvatarAsync(url, size, gif, premium); - } - catch - { - var restUser = await user.Guild.GetMemberAsync(user.Id); - gif = restUser.AvatarHash != null && restUser.AvatarHash.StartsWith("a_"); - url = restUser.GetAvatarUrl(); - return await GetAvatarAsync(url, size, gif, premium); - } - } - - private async Task GetAvatarAsync(string imgUrl, Size size, bool isGif, bool premium) - { - try - { - var avatar = await _client.GetStreamAsync(imgUrl); - var response = avatar.ToEditable(); - response.Position = 0; - var radius = (int)Math.Ceiling((size.Width * Math.PI) / (2 * Math.PI)); - if (premium && isGif) - { - using var img = await Image.LoadAsync(response, new GifDecoder()); - using var toReturn = new Image(Configuration.Default, size.Width, size.Height); - for (var i = 0; i < img.Frames.Count; i++) - { - var x = img.Frames.CloneFrame(i); - x.Mutate(z => z.ConvertToAvatar(size, radius)); - toReturn.Frames.InsertFrame(i, x.Frames[0]); - } - toReturn.Frames.RemoveFrame(toReturn.Frames.Count - 1); - return toReturn.Clone(x => x.Resize(size.Width, size.Height)); - } - if (isGif) - { - using var img = await Image.LoadAsync(response, new GifDecoder()); - return img.Clone(x => x.ConvertToAvatar(size, radius)); - } - else - { - using var img = await Image.LoadAsync(response, new PngDecoder()); - return img.Clone(x => x.ConvertToAvatar(size, radius)); - } - } - catch - { - var avatar = await _client.GetStreamAsync("https://i.imgur.com/kI1RXQZ.png"); - var response = avatar.ToEditable(); - response.Position = 0; - var radius = (int)Math.Ceiling((size.Width * Math.PI) / (2 * Math.PI)); - using var img = await Image.LoadAsync(response, new PngDecoder()); - return img.Clone(x => x.ConvertToAvatar(size, radius)); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/ImageGen/ProfileImg.cs b/Hanekawa/Bot/Services/ImageGen/ProfileImg.cs deleted file mode 100644 index 4da8ea46..00000000 --- a/Hanekawa/Bot/Services/ImageGen/ProfileImg.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Account; -using Hanekawa.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Drawing; -using SixLabors.ImageSharp.Drawing.Processing; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; -using Color = SixLabors.ImageSharp.Color; - -namespace Hanekawa.Bot.Services.ImageGen -{ - public partial class ImageGenerator - { - public async Task ProfileBuilder(CachedMember user, DbService db) - { - var stream = new MemoryStream(); - using (var img = new Image(400, 400)) - { - var userData = await db.GetOrCreateUserData(user); - var globalData = await db.GetOrCreateGlobalUserData(user); - var progressBar = CreateProfileProgressBar(userData); - // TODO: Create a inventory for backgrounds - var background = await GetProfileBackground(db); - var avi = await GetAvatarAsync(user, new Size(110, 110), false); - - var serverRank = await GetRankAsync(userData, db); - var globalRank = await GetRankAsync(globalData, db); - var achievePoints = await GetAchievementPoints(user, db); - var color = new Color(new Rgba32(globalData.UserColor)); - - img.Mutate(x => - { - x.DrawImage(background, 1); - x.DrawImage(_profileTemplate, new Point(0, 0), _options); - x.DrawImage(avi, new Point(145, 4), _options); - x.Fill(Color.Gray, new EllipsePolygon(200, 59, 55).GenerateOutline(4)); - if (progressBar.Count >= 2) - x.DrawLines(color, 4, progressBar.ToArray()); - try - { - x.DrawText(_centerText, user.DisplayName.Truncate(25), _profileName, Color.White, new PointF(200, 120)); - } - catch - { - var username = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(user.DisplayName.Truncate(25))); - x.DrawText(_centerText, username, _profileName, Color.White, new PointF(200, 120)); - } - - //Text - x.DrawText(_leftText, "Server", _profileText, Color.White, new PointF(72, 160)); - x.DrawText(_leftText, "Global", _profileText, Color.White, new PointF(270, 160)); - - // Server - x.DrawText(_leftText, "Rank", _profileText, Color.White, new PointF(8, 256)); - x.DrawText(_rightText, $"{serverRank}", _profileText, Color.White, new PointF(194, 256)); - - x.DrawText(_leftText, "Level", _profileText, Color.White, new PointF(8, 184)); - x.DrawText(_rightText, $"{userData.Level}", _profileText, Color.White, new PointF(194, 184)); - - x.DrawText(_leftText, "Exp", _profileText, Color.White, new PointF(8, 208)); - x.DrawText(_rightText, $"{userData.Exp}", _profileText, Color.White, new PointF(194, 208)); - - x.DrawText(_leftText, "Credit", _profileText, Color.White, new PointF(8, 232)); - x.DrawText(_rightText, $"{userData.Credit}", _profileText, Color.White, new PointF(194, 232)); - - x.DrawText(_leftText, "Achievement Points", _profileText, Color.White, new PointF(22, 286)); - x.DrawText(_rightText, $"{achievePoints}", _profileText, Color.White, new PointF(377, 286)); - - // Global - x.DrawText(_leftText, "Rank", _profileText, Color.White, new PointF(206, 256)); - x.DrawText(_rightText, $"{globalRank}", _profileText, Color.White, new PointF(391, 256)); - - x.DrawText(_leftText, "Credit", _profileText, Color.White, new PointF(206, 232)); - x.DrawText(_rightText, $"{globalData.Credit}", _profileText, Color.White, new PointF(391, 232)); - - x.DrawText(_leftText, "Exp", _profileText, Color.White, new PointF(206, 208)); - x.DrawText(_rightText, $"{globalData.Exp}", _profileText, Color.White, new PointF(391, 208)); - - x.DrawText(_leftText, "Level", _profileText, Color.White, new PointF(206, 184)); - x.DrawText(_rightText, $"{globalData.Level}", _profileText, Color.White, new PointF(391, 184)); - }); - - await img.SaveAsync(stream, new PngEncoder()); - } - - return stream; - } - - private async Task GetProfileBackground(DbService db) - { - var backgroundList = await db.Backgrounds.ToListAsync(); - if (backgroundList == null || backgroundList.Count == 0) - { - var files = Directory.GetFiles("Data/Profile/default/"); - var file = files[_random.Next(files.Length)]; - using var img = Image.Load(file); - return img.Clone(x => x.Resize(400, 400)); - } - else - { - var background = await _client.GetStreamAsync(backgroundList[_random.Next(backgroundList.Count)].BackgroundUrl); - var response = background.ToEditable(); - response.Position = 0; - using var img = await Image.LoadAsync(response, new PngDecoder()); - return img.Clone(x => x.Resize(400, 400)); - } - } - - private List CreateProfileProgressBar(Account userData) - { - var perc = userData.Exp / (float) _expService.ExpToNextLevel(userData); - var numb = perc * 100 / 100 * 360 * 2; - var points = new List(); - const double radius = 55; - - for (var i = 0; i < numb; i++) - { - var radians = i * Math.PI / 360; - - var x = 200 + radius * Math.Cos(radians - Math.PI / 2); - var y = 59 + radius * Math.Sin(radians - Math.PI / 2); - points.Add(new PointF((float) x, (float) y)); - } - - return points; - } - - private async Task GetRankAsync(Account userData, DbService db) - { - var total = await db.Accounts.CountAsync(x => x.GuildId == userData.GuildId); - var rank = await db.Accounts.CountAsync(x => - x.TotalExp >= userData.TotalExp && x.GuildId == userData.GuildId); - return $"{rank.FormatNumber()}/{total.FormatNumber()}"; - } - - private async Task GetRankAsync(AccountGlobal userData, DbService db) - { - var total = await db.AccountGlobals.CountAsync(); - var rank = await db.AccountGlobals.CountAsync(x => x.TotalExp >= userData.TotalExp); - return $"{rank.FormatNumber()}/{total.FormatNumber()}"; - } - - private async Task GetAchievementPoints(CachedMember user, DbService db) - { - var points = await db.AchievementUnlocks.CountAsync(x => x.UserId == user.Id.RawValue); - return $"{points * 10}"; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/ImageGen/RankImg.cs b/Hanekawa/Bot/Services/ImageGen/RankImg.cs deleted file mode 100644 index 798052b5..00000000 --- a/Hanekawa/Bot/Services/ImageGen/RankImg.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.IO; -using System.Threading.Tasks; -using Disqord; - -namespace Hanekawa.Bot.Services.ImageGen -{ - public partial class ImageGenerator - { - public Task RankBuilder(CachedMember user) - { - // TODO: Create rank picture - var stream = new MemoryStream(); - - return Task.FromResult(stream); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/ImageGen/ShipGameImg.cs b/Hanekawa/Bot/Services/ImageGen/ShipGameImg.cs deleted file mode 100644 index 7679ada1..00000000 --- a/Hanekawa/Bot/Services/ImageGen/ShipGameImg.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.IO; -using System.Threading.Tasks; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.Processing; - -namespace Hanekawa.Bot.Services.ImageGen -{ - public partial class ImageGenerator - { - public async Task ShipGameBuilder(string pOneAviUrl, string pTwoAviUrl) - { - var stream = new MemoryStream(); - using (var img = Image.Load("Data/Game/background.png")) - { - // var border = Image.Load(GetBorder()); - // This will be in the future - var aviOne = await GetAvatarAsync(pOneAviUrl, new Size(126, 126), false, false); - var aviTwo = await GetAvatarAsync(pTwoAviUrl, new Size(126, 126), false, false); - img.Mutate(x => x - .DrawImage(aviOne, new Point(3, 92), new GraphicsOptions {Antialias = true}) - .DrawImage(aviTwo, new Point(223, 92), new GraphicsOptions {Antialias = true}) - .DrawImage(Image.Load("Data/Game/Border/Red-border.png"), new Point(0, 0), - new GraphicsOptions {Antialias = true})); - await img.SaveAsync(stream, new PngEncoder()); - } - - return stream; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/ImageGen/WelcomeImg.cs b/Hanekawa/Bot/Services/ImageGen/WelcomeImg.cs deleted file mode 100644 index 95229831..00000000 --- a/Hanekawa/Bot/Services/ImageGen/WelcomeImg.cs +++ /dev/null @@ -1,171 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions; -using Humanizer; -using Microsoft.EntityFrameworkCore; -using SixLabors.Fonts; -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Drawing.Processing; -using SixLabors.ImageSharp.Formats.Gif; -using SixLabors.ImageSharp.Formats.Png; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; -using Color = SixLabors.ImageSharp.Color; - -namespace Hanekawa.Bot.Services.ImageGen -{ - public partial class ImageGenerator - { - public async Task> WelcomeBuilder(CachedMember user, DbService db, bool premium) - { - var stream = new MemoryStream(); - bool isGif; - var (img, welcomeBanner) = await GetBanner(user.Guild.Id.RawValue, db, premium); - using (img) - { - var avatar = await GetAvatarAsync(user, new Size(welcomeBanner.AvatarSize, welcomeBanner.AvatarSize), premium); - var username = user.DisplayName.Truncate(15); - if (premium && img.Frames.Count > 1) - { - await AnimateBanner(img, avatar, user.DisplayName, welcomeBanner.AviPlaceX, welcomeBanner.AviPlaceY, welcomeBanner.TextSize, - welcomeBanner.TextPlaceX, welcomeBanner.TextPlaceY).SaveAsync(stream, new GifEncoder()); - isGif = true; - } - else - { - // Text placement: new Point(245, 40) - img.Mutate(x => x.DrawImage(avatar, new Point(welcomeBanner.AviPlaceX, welcomeBanner.AviPlaceY), _options)); - try - { - img.Mutate( - x => x.DrawText(_centerText, username, new Font(_times, welcomeBanner.TextSize, FontStyle.Regular), Color.White, - new Point(welcomeBanner.TextPlaceX, welcomeBanner.TextPlaceY))); - } - catch - { - username = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(username)); - img.Mutate( - x => x.DrawText(_centerText, username, new Font(_times, welcomeBanner.TextSize, FontStyle.Regular), Color.White, - new Point(welcomeBanner.TextPlaceX, welcomeBanner.TextPlaceY))); - } - - await img.SaveAsync(stream, new PngEncoder()); - isGif = false; - } - } - - return new Tuple(stream, isGif); - } - - public async Task WelcomeBuilder(CachedMember user, string url, int aviSize, int aviX, int aviY, int textSize, int textX, int textY, bool premium) - { - var stream = new MemoryStream(); - using (var img = await GetBanner(url, premium)) - { - var avatar = await GetAvatarAsync(user, new Size(aviSize, aviSize), premium); - var username = user.DisplayName.Truncate(15); - if (premium && (img.Frames.Count > 1 || avatar.Frames.Count > 1)) - { - await AnimateBanner(img, avatar, user.DisplayName, aviX, aviY, textSize, textX, textY).SaveAsync(stream, new GifEncoder()); - } - else - { - img.Mutate(x => x.DrawImage(avatar, new Point(aviX, aviY), _options)); - try - { - img.Mutate( - x => x.DrawText(_centerText, username, new Font(_times, textSize, FontStyle.Regular), Color.White, - new Point(textX, textY))); - } - catch - { - username = Encoding.ASCII.GetString(Encoding.ASCII.GetBytes(username)); - img.Mutate( - x => x.DrawText(_centerText, username, new Font(_times, textSize, FontStyle.Regular), Color.White, - new Point(textX, textY))); - } - - await img.SaveAsync(stream, new PngEncoder()); - } - } - - return stream; - } - - private Image AnimateBanner(Image banner, Image avatar, string name, int aviX, int aviY, int textSize, int textX, int textY) - { - var color = new Rgba32(255, 255, 255, 1f); - var aviIterate = 0; - using var gif = new Image(Configuration.Default, banner.Width, banner.Height); - for (var i = 0; i < banner.Frames.Count; i++) - { - using var img = banner.Frames.CloneFrame(i); - img.Mutate(x => x.DrawImage(avatar.Frames.CloneFrame(aviIterate), new Point(aviX, aviY), 1)); - img.Mutate(x => x.DrawText(_centerText, name, new Font(_times, textSize, FontStyle.Regular), color, new Point(textX, textY))); - gif.Frames.InsertFrame(i, img.Frames[0]); - if (avatar.Frames.Count > aviIterate + 1) aviIterate++; - } - gif.Frames.RemoveFrame(gif.Frames.Count - 1); - gif.Metadata.GetGifMetadata().RepeatCount = 0; - return gif.Clone(); - } - - private async Task> GetBanner(ulong guildId, DbService db, bool premium) - { - var list = await db.WelcomeBanners.Where(x => x.GuildId == guildId).ToListAsync(); - if (list.Count == 0) return new Tuple(_welcomeTemplate, _defWelcomeBanner); - var backgroundRaw = list[_random.Next(list.Count)]; - var background = await _client.GetStreamAsync(backgroundRaw.Url); - var response = background.ToEditable(); - response.Position = 0; - var file = response.GetKnownFileType(); - int width; - int height; - Console.WriteLine(file.ToString()); - if (premium && file == FileType.Gif) - { - using var img = await Image.LoadAsync(response, new GifDecoder()); - width = img.Width; - height = img.Height; - return new Tuple(img.Clone(x => x.Resize(width, height)), backgroundRaw); - } - else - { - using var img = await Image.LoadAsync(response, new PngDecoder()); - width = img.Width; - height = img.Height; - return new Tuple(img.Clone(x => x.Resize(width, height)), backgroundRaw); - } - } - - private async Task GetBanner(string url, bool premium) - { - var background = await _client.GetStreamAsync(url); - var response = background.ToEditable(); - response.Position = 0; - var file = response.GetKnownFileType(); - int width; - int height; - if (premium && file == FileType.Gif) - { - using var img = await Image.LoadAsync(response, new GifDecoder()); - width = img.Width; - height = img.Height; - return img.Clone(x => x.Resize(width, height)); - } - else - { - using var img = await Image.LoadAsync(response, new PngDecoder()); - width = img.Width; - height = img.Height; - return img.Clone(x => x.Resize(width, height)); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/InternalLogService.cs b/Hanekawa/Bot/Services/InternalLogService.cs deleted file mode 100644 index 58df8ddf..00000000 --- a/Hanekawa/Bot/Services/InternalLogService.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Bot; -using Disqord.Logging; -using Hanekawa.Exceptions; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Interfaces; -using Humanizer; -using NLog; -using Qmmands; -using ILogger = Disqord.Logging.ILogger; - -namespace Hanekawa.Bot.Services -{ - public class InternalLogService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly Logger _logger; - - public InternalLogService(Hanekawa client) - { - _client = client; - _logger = LogManager.GetCurrentClassLogger(); - - _client.Logger.Logged += DisqordLogger; - _client.CommandExecutionFailed += CommandErrorLog; - _client.CommandExecuted += CommandExecuted; - } - - private void DisqordLogger(object sender, LogEventArgs e) => _logger.Log(LogSevToNLogLevel(e.Severity), e.Exception, e.Message); - //public void LogAction(LogLevel l, Exception e, string m) => _logger.Log(LogLvlToNLogLvl(l), e, m); - - //public void LogAction(LogLevel l, string m) => _logger.Log(LogLvlToNLogLvl(l), m); - - private Task CommandExecuted(CommandExecutedEventArgs e) - { - _logger.Log(LogLevel.Info, $"Executed Command {e.Context.Command.Name}"); - return Task.CompletedTask; - } - - private Task CommandErrorLog(CommandExecutionFailedEventArgs e) - { - _logger.Log(LogLevel.Error, e.Result.Exception, $"{e.Result.Reason} - {e.Result.CommandExecutionStep}"); - _ = Task.Run(async () => - { - if (!(e.Context is DiscordCommandContext context)) return; - Command command; - Module module = null; - var response = new StringBuilder(); - switch (e.Result as IResult) - { - case ChecksFailedResult err: - command = err.Command; - module = err.Module; - response.AppendLine("The following check(s) failed:"); - foreach (var (check, result) in err.FailedChecks) response.AppendLine($"[{check}]: `{result.Reason}`"); - break; - case TypeParseFailedResult err: - command = err.Parameter.Command; - response.AppendLine(err.Reason); - break; - case ArgumentParseFailedResult err: - command = err.Command; - response.AppendLine($"The syntax of the command `{command.FullAliases[0]}` was wrong."); - break; - case OverloadsFailedResult err: - command = err.FailedOverloads.First().Key; - response.AppendLine($"I can't find any valid overload for the command `{command.Name}`."); - foreach (var overload in err.FailedOverloads) response.AppendLine($" -> `{overload.Value.Reason}`"); - break; - case ParameterChecksFailedResult err: - command = err.Parameter.Command; - module = err.Parameter.Command.Module; - response.AppendLine("The following parameter check(s) failed:"); - foreach (var (check, error) in err.FailedChecks) - response.AppendLine($"[`{check.Parameter.Name}`]: `{error}`"); - break; - case ExecutionFailedResult err: - switch (err.Exception) - { - case HttpRequestException _: - response.AppendLine("I am missing the required permissions to perform this action"); - break; - case HanaCommandException exception: - response.AppendLine(exception.CommandErrorMessage); - break; - default: - response.AppendLine("Something went wrong..."); - break; - } - break; - case CommandNotFoundResult _: - var list = new List>(); - var commands = _client.GetAllCommands(); - foreach (var x in commands) - for (var i = 0; i < x.Aliases.Count; i++) - { - var alias = x.Aliases.ElementAt(i); - alias.FuzzyMatch(e.Context.Alias, out var score); - list.Add(new Tuple(x, score)); - } - - var reCmd = list.OrderByDescending(x => x.Item2).FirstOrDefault(); - if (reCmd == null) return; - response.AppendLine( - $"Did you mean **{reCmd.Item1.Name}** ? (command: {_client.CurrentUser.Mention} {reCmd.Item1.FullAliases.FirstOrDefault()})"); - break; - default: - response.AppendLine("Something went wrong..."); - break; - } - - if (response.Length != 0) await context.Channel.ReplyAsync(response.ToString(), Color.Red); - var msg = new StringBuilder(); - var args = new StringBuilder(); - foreach (var x in context.Arguments) - { - args.Append($"{x} "); - } - msg.AppendLine($"Error in guild: {context.Guild.Name} (size: {context.Guild.MemberCount}) - {context.Guild.Id.RawValue}"); - msg.AppendLine($"Invoked by: {context.User} ({context.User.Id.RawValue})"); - msg.AppendLine($"Command failed: {e.Result.Command.Name}"); - msg.AppendLine($"Command Format: {e.Result.Command.Name} {args} {e.Context.RawArguments}"); - msg.AppendLine($"Reason: {e.Result.Reason}"); - msg.AppendLine($"Response: {response}"); - msg.AppendLine(e.Result.Exception.Message); - msg.AppendLine(e.Result.Exception.InnerException == null - ? $"```{e.Result.Exception.StackTrace}```" - : $"```{e.Result.Exception.InnerException.StackTrace}```"); - await _client.GetGuild(431617676859932704).GetTextChannel(523165903219720232).SendMessageAsync(msg.ToString().Truncate(1900)); - }); - return Task.CompletedTask; - } - - private static LogLevel LogSevToNLogLevel(LogSeverity log) => - log switch - { - LogSeverity.Critical => LogLevel.Fatal, - LogSeverity.Error => LogLevel.Error, - LogSeverity.Warning => LogLevel.Warn, - LogSeverity.Information => LogLevel.Info, - LogSeverity.Trace => LogLevel.Trace, - LogSeverity.Debug => LogLevel.Debug, - _ => LogLevel.Off - }; - } - - public class DiscordLogger : ILogger, INService, IRequired - { - private readonly Logger _logger; - - public DiscordLogger() => _logger = LogManager.GetCurrentClassLogger(); - - public void Dispose() { } - - public void Log(object sender, LogEventArgs e) => _logger.Log(SevToLogLevel(e.Severity), e.Exception, e.Message); - - public event EventHandler Logged; - - private static LogLevel SevToLogLevel(LogSeverity log) => - log switch - { - LogSeverity.Critical => LogLevel.Fatal, - LogSeverity.Error => LogLevel.Error, - LogSeverity.Warning => LogLevel.Warn, - LogSeverity.Information => LogLevel.Info, - LogSeverity.Trace => LogLevel.Trace, - LogSeverity.Debug => LogLevel.Debug, - _ => LogLevel.Off - }; - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/BanLogging.cs b/Hanekawa/Bot/Services/Logging/BanLogging.cs deleted file mode 100644 index 81a416f1..00000000 --- a/Hanekawa/Bot/Services/Logging/BanLogging.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Disqord.Rest.AuditLogs; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Moderation; -using Hanekawa.Shared; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - private Task UserUnbanned(MemberUnbannedEventArgs e) - { - _ = Task.Run(async () => - { - var guild = e.Guild; - var user = e.User; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(guild); - if (!cfg.LogBan.HasValue) return; - var channel = guild.GetTextChannel(cfg.LogBan.Value); - if (channel == null) return; - var caseId = await db.CreateCaseId(user, guild, DateTime.UtcNow, ModAction.Unban); - var embed = new LocalEmbedBuilder - { - Color = Color.Green, - Author = new LocalEmbedAuthorBuilder {Name = $"User Unbanned | Case ID: {caseId.Id} | {user}"}, - Footer = new LocalEmbedFooterBuilder {Text = $"User ID: {user.Id.RawValue}", IconUrl = user.GetAvatarUrl() }, - Timestamp = DateTimeOffset.UtcNow, - Fields = - { - new LocalEmbedFieldBuilder {Name = "User", Value = $"{user.Mention}", IsInline = true}, - new LocalEmbedFieldBuilder {Name = "Moderator", Value = "N/A", IsInline = true}, - new LocalEmbedFieldBuilder {Name = "Reason", Value = "N/A", IsInline = true} - } - }; - var msg = await channel.SendMessageAsync(null, false, embed.Build()); - caseId.MessageId = msg.Id.RawValue; - await db.SaveChangesAsync(); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(Log Service) Error in {guild.Id.RawValue} for UnBan Log - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task UserBanned(MemberBannedEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.User; - var guild = e.Guild; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(guild); - if (!cfg.LogBan.HasValue) return; - var channel = guild.GetTextChannel(cfg.LogBan.Value); - if (channel == null) return; - - var caseId = await db.CreateCaseId(user, guild, DateTime.UtcNow, ModAction.Ban); - - CachedMember mod; - if (_cache.BanCache.TryGetValue(guild.Id.RawValue, out var cache)) - { - if (cache.TryGetValue(user.Id.RawValue, out var result)) - { - var modId = (ulong) result; - mod = guild.GetMember(modId); - if (mod != null) - { - caseId.ModId = mod.Id.RawValue; - } - } - else mod = await CheckAuditLog(guild, user.Id, caseId); - } - else mod = await CheckAuditLog(guild, user.Id, caseId); - - var embed = new LocalEmbedBuilder - { - Color = Color.Red, - Author = new LocalEmbedAuthorBuilder {Name = $"User Banned | Case ID: {caseId.Id} | {user}"}, - Fields = - { - new LocalEmbedFieldBuilder {Name = "User", Value = user.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Moderator", Value = mod?.Mention ?? "N/A", IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Reason", Value = "N/A", IsInline = false} - }, - Footer = new LocalEmbedFooterBuilder {Text = $"User ID: {user.Id.RawValue}", IconUrl = user.GetAvatarUrl() }, - Timestamp = DateTimeOffset.UtcNow - }; - if (user is CachedMember member) - embed.AddField("Time In Server", (DateTimeOffset.UtcNow - member.JoinedAt).Humanize(5)); - - var msg = await channel.SendMessageAsync(null, false, embed.Build()); - caseId.MessageId = msg.Id.RawValue; - await db.SaveChangesAsync(); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(Log Service) Error in {guild.Id.RawValue} for Ban Log - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private static async Task CheckAuditLog(CachedGuild guild, Snowflake userId, ModLog caseId) - { - CachedMember mod = null; - - await Task.Delay(TimeSpan.FromSeconds(2)); - var audits = await guild.GetAuditLogsAsync(); - var audit = audits.FirstOrDefault(x => x.TargetId.HasValue && x.TargetId.Value == userId); - if (audit != null) - { - var temp = guild.GetMember(audit.ResponsibleUserId); - if (!temp.IsBot) mod = temp; - - var reasonSplit = audit.Reason.Replace("(", " ").Replace(")", " ").Split(" "); - var modId = FetchId(reasonSplit); - if (modId.HasValue) - { - temp = guild.GetMember(modId.Value); - if (temp != null && temp.Permissions.Contains(Permission.BanMembers) && !temp.IsBot) mod = temp; - } - } - - caseId.ModId = mod?.Id.RawValue; - return mod; - } - - private static Snowflake? FetchId(IEnumerable value) - { - foreach (var x in value) - { - if (Snowflake.TryParse(x, out var result)) return result; - } - - return null; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/JoinLogging.cs b/Hanekawa/Bot/Services/Logging/JoinLogging.cs deleted file mode 100644 index 272c2d23..00000000 --- a/Hanekawa/Bot/Services/Logging/JoinLogging.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Disqord.Rest; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Quartz.Util; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - private Task UserLeft(MemberLeftEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.User; - var guild = e.Guild; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(guild); - if (!cfg.LogJoin.HasValue) return; - var channel = guild.GetTextChannel(cfg.LogJoin.Value); - if (channel == null) return; - - var embed = new LocalEmbedBuilder - { - Description = $"📤 {user.Mention} has left ( *{user.Id.RawValue}* )", - Color = Color.Red, - Footer = new LocalEmbedFooterBuilder {Text = $"Username: {user}"}, - Timestamp = DateTimeOffset.UtcNow - }; - var gusr = guild.GetMember(user.Id); - if (gusr != null) - { - var roles = new StringBuilder(); - foreach (var role in gusr.Roles) roles.Append($"{role.Value.Name}, "); - embed.AddField("Time in server", (DateTimeOffset.UtcNow - gusr.JoinedAt).Humanize()); - embed.AddField("Roles", roles.ToString().Truncate(1000)); - } - - await channel.SendMessageAsync(null, false, embed.Build()); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {guild.Id.RawValue} for Join Log - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task UserJoined(MemberJoinedEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.Member; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogJoin.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogJoin.Value); - if (channel == null) return; - try - { - var inviteeInfo = await GetInvite(e); - var embed = new LocalEmbedBuilder - { - Description = $"📥 {user.Mention} has joined ( *{user.Id.RawValue}* )\n" + - $"Account created: {user.CreatedAt.Humanize()}", - Color = Color.Green, - Footer = new LocalEmbedFooterBuilder {Text = $"Username: {user}"}, - Timestamp = DateTimeOffset.UtcNow - }; - if (inviteeInfo != null && - !inviteeInfo.Item2.IsNullOrWhiteSpace()) - { - var msg = new StringBuilder(); - - msg.AppendLine($"{inviteeInfo.Item2}"); - msg.AppendLine(inviteeInfo.Item1 != null - ? $"By: {inviteeInfo.Item1}" - : "By: User couldn't be found"); - if(!msg.ToString().IsNullOrWhiteSpace()) embed.AddField("Invite", msg.ToString().Truncate(1000)); - } - await channel.SendMessageAsync(null, false, embed.Build()); - } - catch (Exception exception) - { - try - { - var embed = new LocalEmbedBuilder - { - Description = $"📥 {user.Mention} has joined ( *{user.Id.RawValue}* )\n" + - $"Account created: {user.CreatedAt.Humanize()}", - Color = Color.Green, - Footer = new LocalEmbedFooterBuilder { Text = $"Username: {user}" }, - Timestamp = DateTimeOffset.UtcNow - }; - await channel.SendMessageAsync(null, false, embed.Build()); - } - catch (Exception e1) - { - _log.Log(NLog.LogLevel.Error, e1, - $"(Log Service) Error in {user.Guild.Id.RawValue} for Join Log - {e1.Message}"); - } - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {user.Guild.Id.RawValue} for Join Log - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private async Task> GetInvite(MemberJoinedEventArgs e) - { - Tuple inviteeInfo = null; - var restInvites = await e.Member.Guild.GetInvitesAsync(); - if (!_invites.TryGetValue(e.Member.Guild.Id.RawValue, out var invites)) - { - await UpdateInvites(e.Member, restInvites); - } - else - { - var tempInvites = new ConcurrentDictionary>(); - for (var i = 0; i < restInvites.Count; i++) - { - var x = restInvites[i]; - tempInvites.TryAdd(x.Code, new Tuple(x.Metadata.Inviter.Id.RawValue, x.Metadata.Uses)); - } - var change = invites.Except(tempInvites).ToList(); - var (code, tuple) = change.FirstOrDefault(); - if (code != null) - { - var invitee = await e.Client.GetOrFetchUserAsync(tuple.Item1); - if (invitee != null) - { - inviteeInfo = new Tuple(invitee, $"discord.gg/{code}"); - } - - await UpdateInvites(e.Member, restInvites); - } - } - - return inviteeInfo; - } - - private async Task UpdateInvites(CachedMember user, IReadOnlyList restInvites = null) - { - if (restInvites == null) restInvites = await user.Guild.GetInvitesAsync(); - var invites = new ConcurrentDictionary>(); - for (var i = 0; i < restInvites.Count; i++) - { - var x = restInvites[i]; - invites.TryAdd(x.Code, new Tuple(x.Metadata.Inviter.Id.RawValue, x.Metadata.Uses)); - } - - _invites.AddOrUpdate(user.Guild.Id.RawValue, invites, (id, set) => invites); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/LogService.cs b/Hanekawa/Bot/Services/Logging/LogService.cs deleted file mode 100644 index 37b2f835..00000000 --- a/Hanekawa/Bot/Services/Logging/LogService.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading.Tasks; -using Hanekawa.Bot.Services.Caching; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly Logger _log; - private readonly IServiceProvider _provider; - private readonly ColourService _colourService; - private readonly CacheService _cache; - - private readonly ConcurrentDictionary>> _invites = new(); - - public LogService(Hanekawa client, IServiceProvider provider, ColourService colourService, CacheService cache) - { - _client = client; - _log = LogManager.GetCurrentClassLogger(); - _provider = provider; - _colourService = colourService; - _cache = cache; - - _client.MemberBanned += UserBanned; - _client.MemberUnbanned += UserUnbanned; - - _client.MemberJoined += UserJoined; - _client.MemberLeft += UserLeft; - - _client.MessageDeleted += MessageDeleted; - _client.MessageUpdated += MessageUpdated; - _client.MessagesBulkDeleted += MessagesBulkDeleted; - - _client.ReactionAdded += ReactionAddLog; - _client.ReactionRemoved += ReactionRemovedLog; - - _client.MemberUpdated += GuildMemberUpdated; - _client.UserUpdated += UserUpdated; - - _client.VoiceStateUpdated += VoiceLog; - _client.InviteCreated += InviteCreated; - _client.InviteDeleted += InviteDeleted; - } - - private Task InviteDeleted(Disqord.Events.InviteDeletedEventArgs e) - { - _ = Task.Run(async () => - { - if (!e.GuildId.HasValue) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(e.GuildId.Value.RawValue); - if (!cfg.LogJoin.HasValue) return; - var invites = _invites.GetOrAdd(e.GuildId.Value.RawValue, new ConcurrentDictionary>()); - invites.Remove(e.Code, out _); - _invites.AddOrUpdate(e.GuildId.Value.RawValue, new ConcurrentDictionary>(), - (arg1, tuples) => invites); - }); - return Task.CompletedTask; - } - - private Task InviteCreated(Disqord.Events.InviteCreatedEventArgs e) - { - _ = Task.Run(async () => - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(e.Guild); - if (!cfg.LogJoin.HasValue) return; - var invites = _invites.GetOrAdd(e.Guild.Id.RawValue, new ConcurrentDictionary>()); - invites.TryAdd(e.Code, new Tuple(e.Inviter.Id.RawValue, 0)); - _invites.AddOrUpdate(e.Guild.Id.RawValue, new ConcurrentDictionary>(), - (arg1, tuples) => invites); - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/MessageLogging.cs b/Hanekawa/Bot/Services/Logging/MessageLogging.cs deleted file mode 100644 index 156942db..00000000 --- a/Hanekawa/Bot/Services/Logging/MessageLogging.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions.Embed; -using Humanizer; -using Microsoft.Extensions.DependencyInjection; -using Quartz.Util; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - private Task MessageUpdated(MessageUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - var ch = e.Channel; - var before = e.OldMessage; - var after = e.NewMessage; - if (!(after.Author is CachedMember user)) return; - if (user.IsBot) return; - if (!(ch is ITextChannel chx)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogMsg.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogMsg.Value); - if (channel == null) return; - if (before.HasValue) - { - if (before.Value.Content == null) return; - if (before.Value.Content == after.Content) return; - } - - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder { Name = "Message Updated" }, - Color = _colourService.Get(user.Guild.Id.RawValue), - Timestamp = after.EditedAt ?? after.CreatedAt, - Description = $"{user.Mention} updated a message in {chx.Mention}", - Footer = new LocalEmbedFooterBuilder - { - Text = $"User: {user.Id.RawValue} | {after.Id.RawValue}", - IconUrl = user.GetAvatarUrl() - } - }; - embed.AddField("Updated Message", after.Content.Truncate(980)); - embed.AddField("Old Message", - before.HasValue ? before.Value.Content.Truncate(980) : "Unknown - Message not in cache"); - await channel.ReplyAsync(embed); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {user.Guild.Id.RawValue} for Message Updated - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task MessageDeleted(MessageDeletedEventArgs e) - { - _ = Task.Run(async () => - { - var ch = e.Channel; - var msg = e.Message; - if (!(ch is CachedTextChannel chx)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(chx.Guild); - if (!cfg.LogMsg.HasValue) return; - var channel = chx.Guild.GetTextChannel(cfg.LogMsg.Value); - if (channel == null) return; - if (!msg.HasValue) return; - if (msg.Value.Author.IsBot) return; - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder { Name = "Message Deleted" }, - Color = _colourService.Get(chx.Guild.Id.RawValue), - Timestamp = msg.Value.CreatedAt, - Description = $"{msg.Value.Author.Mention} deleted a message in {chx.Name}", - Footer = new LocalEmbedFooterBuilder - { - Text = $"User: {msg.Value.Author.Id.RawValue} | Message ID: {msg.Id.RawValue}", - IconUrl = msg.Value.Author.GetAvatarUrl() - } - }; - if (!msg.Value.Content.IsNullOrWhiteSpace()) - embed.AddField("Content", msg.Value.Content.Truncate(1499)); - - if (msg.Value.Attachments.Count > 0 && !chx.IsNsfw) - { - var file = msg.Value.Attachments.FirstOrDefault(); - if (file != null) - embed.AddField(x => - { - x.Name = "File"; - x.IsInline = false; - x.Value = file.ProxyUrl; - }); - } - - await channel.SendMessageAsync(null, false, embed.Build()); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {chx.Guild.Id.RawValue} for Message Deleted - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task MessagesBulkDeleted(MessagesBulkDeletedEventArgs e) - { - _ = Task.Run(async () => - { - var ch = e.Channel; - var messages = e.Messages; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(ch.Guild); - if (!cfg.LogMsg.HasValue) return; - var logChannel = ch.Guild.GetTextChannel(cfg.LogMsg.Value); - if (logChannel == null) return; - - var messageContent = new List(); - var content = new StringBuilder(); - foreach (var x in messages) - { - if(!x.HasValue) continue; - var user = x.Value.Author; - if (content.Length + x.Value.Content.Length >= 1950) - { - messageContent.Add(content.ToString()); - content.Clear(); - } - - content.AppendLine($"{user}: {x.Value.Content}"); - } - - if (content.Length > 0) messageContent.Add(content.ToString()); - - for (var i = 0; i < messageContent.Count; i++) - { - var embed = new LocalEmbedBuilder - { - Color = _colourService.Get(ch.Guild.Id.RawValue), - Title = $"Bulk delete in {ch.Name}", - Description = messageContent[i] - }; - await logChannel.ReplyAsync(embed); - await Task.Delay(1000); - } - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {ch.Guild.Id.RawValue} for Bulk Message Deleted - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/MuteLogging.cs b/Hanekawa/Bot/Services/Logging/MuteLogging.cs deleted file mode 100644 index 8cfbcd44..00000000 --- a/Hanekawa/Bot/Services/Logging/MuteLogging.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Shared; -using Humanizer; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - public async Task Mute(CachedMember user, CachedMember staff, string reason, DbService db) - { - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogBan.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogBan.Value); - if (channel == null) return; - var caseId = await db.CreateCaseId(user, user.Guild, DateTime.UtcNow, ModAction.Mute); - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder { Name = $"Case ID: {caseId.Id} - User Muted | {user}" }, - Color = Color.Red, - Timestamp = DateTimeOffset.UtcNow, - Fields = - { - new LocalEmbedFieldBuilder {Name = "User", Value = user.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Moderator", Value = staff.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Reason", Value = reason, IsInline = false} - }, - Footer = new LocalEmbedFooterBuilder { Text = $"Username: {user} ({user.Id.RawValue})", IconUrl = user.GetAvatarUrl() } - }; - var msg = await channel.SendMessageAsync(null, false, embed.Build()); - caseId.MessageId = msg.Id.RawValue; - await db.SaveChangesAsync(); - } - - public async Task Mute(CachedMember user, CachedMember staff, string reason, TimeSpan duration, - DbService db) - { - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogBan.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogBan.Value); - if (channel == null) return; - var caseId = await db.CreateCaseId(user, user.Guild, DateTime.UtcNow, ModAction.Mute); - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder { Name = $"Case ID: {caseId.Id} - User Muted | {user}" }, - Color = Color.Red, - Timestamp = DateTimeOffset.UtcNow, - Fields = - { - new LocalEmbedFieldBuilder {Name = "User", Value = user.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Moderator", Value = staff.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Reason", Value = reason, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Duration", Value = $"{duration.Humanize(2)}", IsInline = false} - }, - Footer = new LocalEmbedFooterBuilder { Text = $"Username: {user} ({user.Id.RawValue})", IconUrl = user.GetAvatarUrl() } - }; - var msg = await channel.SendMessageAsync(null, false, embed.Build()); - caseId.MessageId = msg.Id.RawValue; - await db.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/ReactionLogging.cs b/Hanekawa/Bot/Services/Logging/ReactionLogging.cs deleted file mode 100644 index 6addbe1a..00000000 --- a/Hanekawa/Bot/Services/Logging/ReactionLogging.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Rest; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Microsoft.Extensions.DependencyInjection; -using Quartz.Util; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - private Task ReactionAddLog(Disqord.Events.ReactionAddedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Channel is CachedTextChannel channel)) return; - if (!e.User.HasValue) await e.User.FetchAsync(); - if (e.User.Value.IsBot) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var log = await db.GetOrCreateLoggingConfigAsync(channel.Guild); - if (!log.LogReaction.HasValue) return; - if (log.ReactionWebhook.IsNullOrWhiteSpace()) return; - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder - {IconUrl = e.User.Value.GetAvatarUrl(), Name = e.User.Value.Name}, - Color = _colourService.Get(channel.Guild.Id.RawValue), - Description = $"{e.User.Value.Name} added {e.Emoji} to a message in {channel.Mention}", - Timestamp = DateTimeOffset.UtcNow, - Footer = new LocalEmbedFooterBuilder - {Text = $"Channel: {channel.Id.RawValue} - Message: {e.Message.Id.RawValue}"} - }.Build(); - try - { - var embeds = new List { embed }; - await RestWebhookClient.FromUrl(log.ReactionWebhook).ExecuteAsync(null, false, embeds, _client.CurrentUser.Name, _client.CurrentUser.GetAvatarUrl(), true); - } - catch - { - var logChannel = channel.Guild.GetTextChannel(log.LogReaction.Value); - if (logChannel == null) - { - log.ReactionWebhook = null; - log.LogReaction = null; - await db.SaveChangesAsync(); - return; - } - var webhooks = await channel.GetWebhooksAsync(); - var check = webhooks.FirstOrDefault(x => x.Owner.Id == channel.Guild.CurrentMember.Id); - if (check == null) - { - log.ReactionWebhook = null; - log.LogReaction = null; - await db.SaveChangesAsync(); - return; - } - - await logChannel.SendMessageAsync(null, false, embed); - } - }); - return Task.CompletedTask; - } - - private Task ReactionRemovedLog(Disqord.Events.ReactionRemovedEventArgs e) - { - _ = Task.Run(async () => - { - if (!(e.Channel is CachedTextChannel channel)) return; - if (!e.User.HasValue) await e.User.FetchAsync(); - if (e.User.Value.IsBot) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var log = await db.GetOrCreateLoggingConfigAsync(channel.Guild); - if (!log.LogReaction.HasValue) return; - if (log.ReactionWebhook.IsNullOrWhiteSpace()) return; - var embed = new LocalEmbedBuilder - { - Author = new LocalEmbedAuthorBuilder - { IconUrl = e.User.Value.GetAvatarUrl(), Name = e.User.Value.Name }, - Color = _colourService.Get(channel.Guild.Id.RawValue), - Description = $"{e.User.Value.Name} removed {e.Emoji} from a message in {channel.Mention}", - Timestamp = DateTimeOffset.UtcNow, - Footer = new LocalEmbedFooterBuilder - { Text = $"Channel: {channel.Id.RawValue} - Message: {e.Message.Id.RawValue}" } - }.Build(); - try - { - var embeds = new List { embed }; - await RestWebhookClient.FromUrl(log.ReactionWebhook).ExecuteAsync(null, false, embeds, _client.CurrentUser.Name, _client.CurrentUser.GetAvatarUrl(), true); - } - catch - { - var logChannel = channel.Guild.GetTextChannel(log.LogReaction.Value); - if (logChannel == null) - { - log.ReactionWebhook = null; - log.LogReaction = null; - await db.SaveChangesAsync(); - return; - } - var webhooks = await channel.GetWebhooksAsync(); - var check = webhooks.FirstOrDefault(x => x.Owner.Id == channel.Guild.CurrentMember.Id); - if (check == null) - { - log.ReactionWebhook = null; - log.LogReaction = null; - await db.SaveChangesAsync(); - return; - } - - await logChannel.SendMessageAsync(null, false, embed); - } - }); - return Task.CompletedTask; - } - } -} diff --git a/Hanekawa/Bot/Services/Logging/UserLogging.cs b/Hanekawa/Bot/Services/Logging/UserLogging.cs deleted file mode 100644 index 640e1f69..00000000 --- a/Hanekawa/Bot/Services/Logging/UserLogging.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Extensions.Embed; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - private Task UserUpdated(UserUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - var before = e.OldUser; - var after = e.NewUser; - if (!(before is CachedMember user)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogAvi.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogAvi.Value); - if (channel is null) return; - - var embed = new LocalEmbedBuilder {Color = _colourService.Get(user.Guild.Id.RawValue), Description = ""}; - if (before.Name != after.Name) - { - embed.Title = "Username Change"; - embed.Description = $"{before} || {before.Id.RawValue}"; - embed.AddField(x => - { - x.Name = "New Name"; - x.Value = $"{after.Name}"; - x.IsInline = true; - }); - embed.AddField(x => - { - x.Name = "Old Name"; - x.Value = $"{before.Name}"; - x.IsInline = true; - }); - } - else if (before.GetAvatarUrl() != after.GetAvatarUrl()) - { - embed.Title = "Avatar Change"; - embed.Description = $"{before} | {before.Id.RawValue}"; - embed.ThumbnailUrl = before.GetAvatarUrl(); - embed.ImageUrl = after.GetAvatarUrl(); - } - else - { - return; - } - - await channel.ReplyAsync(embed); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {user.Guild.Id.RawValue} for User Updated - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task GuildMemberUpdated(MemberUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - var before = e.OldMember; - var after = e.NewMember; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(before.Guild); - if (!cfg.LogAvi.HasValue) return; - var channel = before.Guild.GetTextChannel(cfg.LogAvi.Value); - if (channel == null) return; - - var embed = new LocalEmbedBuilder - { - Color = _colourService.Get(before.Guild.Id.RawValue), - Description = "", - Footer = new LocalEmbedFooterBuilder {Text = $"Username: {after} ({after.Id.RawValue})", IconUrl = after.GetAvatarUrl()} - }; - if (before.Nick != after.Nick) - { - embed.Author = new LocalEmbedAuthorBuilder {Name = "Nickname Change"}; - embed.AddField("New Nick", after.Nick ?? after.Name); - embed.AddField("Old Nick", before.Nick ?? before.Name); - } - else if (before.Roles.SequenceEqual(after.Roles)) - { - if (before.Roles.Count < after.Roles.Count) - { - var roleDiffer = after.Roles - .Where(x => !before.Roles.Contains(x)).Select(x => x.Value.Name); - embed.WithAuthor(x => x.WithName("User Role Added")) - .WithDescription(string.Join(", ", roleDiffer)); - } - else if (before.Roles.Count > after.Roles.Count) - { - var roleDiffer = before.Roles - .Where(x => !after.Roles.Contains(x)).Select(x => x.Value.Name); - embed.WithAuthor(x => x.WithName("User Role Removed")) - .WithDescription(string.Join(", ", roleDiffer)); - } - else - { - return; - } - } - else - { - return; - } - - await channel.ReplyAsync(embed); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {before.Guild.Id.RawValue} for Guild Member Log - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/VoiceLogging.cs b/Hanekawa/Bot/Services/Logging/VoiceLogging.cs deleted file mode 100644 index 1346dc48..00000000 --- a/Hanekawa/Bot/Services/Logging/VoiceLogging.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - private Task VoiceLog(VoiceStateUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.Member; - var before = e.OldVoiceState; - var after = e.NewVoiceState; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogVoice.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogVoice.Value); - if (channel == null) return; - - var embed = new LocalEmbedBuilder - { - Color = _colourService.Get(user.Guild.Id.RawValue), - Footer = new LocalEmbedFooterBuilder {Text = $"Username: {user} ({user.Id.RawValue})", IconUrl = user.GetAvatarUrl()} - }; - // User muted, deafend or streaming - if (before != null && after != null && before.ChannelId == after.ChannelId) - { - if (before.IsDeafened && !after.IsDeafened) - { - // User undeafend - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Server Undeafend" }; - embed.Description = $"{user} got server Undeafend in {user.VoiceChannel.Name}"; - } - else if (!before.IsDeafened && after.IsDeafened) - { - // User deafend - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Server Deafend" }; - embed.Description = $"{user} got server deafend in {user.VoiceChannel.Name}"; - } - else if (before.IsMuted && !after.IsMuted) - { - // User unmuted - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Server Unmuted" }; - embed.Description = $"{user} Unmuted in {user.VoiceChannel.Name}"; - } - else if (!before.IsMuted && after.IsMuted) - { - // User muted - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Server Muted" }; - embed.Description = $"{user} muted in {user.VoiceChannel.Name}"; - } - // Self deafend - else if (before.IsSelfDeafened && !after.IsSelfDeafened) - { - // User Self undeafend - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Self Undeafened" }; - embed.Description = $"{user} Undeafened in {user.VoiceChannel.Name}"; - } - else if (!before.IsSelfDeafened && after.IsSelfDeafened) - { - // User Self deafend - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Self Deafened" }; - embed.Description = $"{user} deafened in {user.VoiceChannel.Name}"; - } - else if (before.IsSelfMuted && !after.IsSelfMuted) - { - // User Self unmuted - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Self Unmuted" }; - embed.Description = $"{user} Unmuted in {user.VoiceChannel.Name}"; - } - else if (!before.IsSelfMuted && after.IsSelfMuted) - { - // User Self muted - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Self Muted" }; - embed.Description = $"{user} muted in {user.VoiceChannel.Name}"; - } - else if (!before.IsStreaming && after.IsStreaming) - { - // User Started (game) Streaming - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Started Streaming(game)" }; - embed.Description = $"{user} started streaming in {user.VoiceChannel.Name}"; - } - else if (before.IsStreaming && !after.IsStreaming) - { - // User Stopped (game) Streaming - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Stopped Streaming(game)" }; - embed.Description = $"{user} stopped streaming in {user.VoiceChannel.Name}"; - } - else if (!before.IsVideoStreaming && after.IsVideoStreaming) - { - // User Started video (cam) streaming - embed.Author = new LocalEmbedAuthorBuilder { Name = "User Started Streaming(cam)" }; - embed.Description = $"{user} started streaming in {user.VoiceChannel.Name}"; - } - else if (before.IsVideoStreaming && !after.IsVideoStreaming) - { - // User Stopped video (cam) Streaming - embed.Author = new LocalEmbedAuthorBuilder {Name = "User Stopped Streaming(cam)"}; - embed.Description = $"{user} stopped streaming in {user.VoiceChannel.Name}"; - } - else return; - } - else if (before == null && after != null) - { - embed.Author = new LocalEmbedAuthorBuilder { Name = "Voice Channel Joined" }; - embed.AddField("New Channel", user.Guild.GetVoiceChannel(e.NewVoiceState.ChannelId.RawValue).Name); - } - else if (before != null && after == null) - { - embed.Author = new LocalEmbedAuthorBuilder { Name = "Voice Channel Left" }; - embed.AddField("Old Channel", user.Guild.GetVoiceChannel(before.ChannelId.RawValue).Name); - } - else if (before != null && before.ChannelId != after.ChannelId) - { - embed.Author = new LocalEmbedAuthorBuilder {Name = "Voice Channel Change"}; - embed.AddField("Old Channel", user.Guild.GetVoiceChannel(before.ChannelId).Name); - embed.AddField("New Channel", user.Guild.GetVoiceChannel(after.ChannelId).Name); - } - else return; - await channel.SendMessageAsync(null, false, embed.Build()); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Log Service) Error in {user.Guild.Id.RawValue} for Voice Log - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Logging/WarnLogging.cs b/Hanekawa/Bot/Services/Logging/WarnLogging.cs deleted file mode 100644 index 319c2717..00000000 --- a/Hanekawa/Bot/Services/Logging/WarnLogging.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Humanizer; - -namespace Hanekawa.Bot.Services.Logging -{ - public partial class LogService - { - public async Task MuteWarn(CachedMember user, CachedMember staff, string reason, TimeSpan duration, - DbService db) - { - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogWarn.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogWarn.Value); - if (channel == null) return; - - var embed = new LocalEmbedBuilder - { - Color = Color.Red, - Timestamp = DateTimeOffset.UtcNow, - Author = new LocalEmbedAuthorBuilder {Name = "User Mute Warned"}, - Footer = new LocalEmbedFooterBuilder {Text = $"Username: {user} ({user.Id.RawValue})"}, - Fields = - { - new LocalEmbedFieldBuilder {Name = "User", Value = user.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Moderator", Value = staff.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Reason", Value = reason, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Duration", Value = $"{duration.Humanize()}", IsInline = false} - } - }; - await channel.SendMessageAsync(null, false, embed.Build()); - } - - public async Task Warn(CachedMember user, CachedMember staff, string reason, DbService db) - { - var cfg = await db.GetOrCreateLoggingConfigAsync(user.Guild); - if (!cfg.LogWarn.HasValue) return; - var channel = user.Guild.GetTextChannel(cfg.LogWarn.Value); - if (channel == null) return; - - var embed = new LocalEmbedBuilder - { - Color = Color.Red, - Timestamp = DateTimeOffset.UtcNow, - Author = new LocalEmbedAuthorBuilder {Name = "User Warned"}, - Footer = new LocalEmbedFooterBuilder {Text = $"Username: {user} ({user.Id.RawValue})"}, - Fields = - { - new LocalEmbedFieldBuilder {Name = "User", Value = user.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Moderator", Value = staff.Mention, IsInline = false}, - new LocalEmbedFieldBuilder {Name = "Reason", Value = reason, IsInline = false} - } - }; - await channel.SendMessageAsync(null, false, embed.Build()); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Mvp/MvpService.cs b/Hanekawa/Bot/Services/Mvp/MvpService.cs deleted file mode 100644 index 293f9957..00000000 --- a/Hanekawa/Bot/Services/Mvp/MvpService.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions; -using Hanekawa.Extensions.Embed; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; -using NLog; -using Quartz; - -namespace Hanekawa.Bot.Services.Mvp -{ - public class MvpService : INService, IRequired, IJob - { - private readonly Hanekawa _client; - private readonly NLog.Logger _log; - private readonly IServiceProvider _service; - - public MvpService(Hanekawa client, IServiceProvider service) - { - _client = client; - _log = LogManager.GetCurrentClassLogger(); - _service = service; - - _client.RoleDeleted += MvpRoleCheckDeletion; - } - - private Task MvpRoleCheckDeletion(RoleDeletedEventArgs e) - { - _ = Task.Run(async () => - { - using var scope = _service.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var mvpConfig = await db.MvpConfigs.FindAsync(e.Role.Guild); - if (mvpConfig?.RoleId == null) return; - if (e.Role.Id.RawValue != mvpConfig.RoleId.Value) return; - mvpConfig.RoleId = null; - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, "(MVP Service) Removed MVP role as it was deleted."); - }); - return Task.CompletedTask; - } - - public Task Execute(IJobExecutionContext context) - { - _ = MvpReward(); - return Task.CompletedTask; - } - - private async Task MvpReward() - { - using var scope = _service.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var premium = await db.GuildConfigs.Where(x => x.Premium).ToListAsync(); - - for (var i = 0; i < premium.Count; i++) - { - var x = premium[i]; - await Reward(x, db); - } - } - - public async Task Reward(GuildConfig x, DbService db, bool bypass = false) - { - var mvp = new List(); - var oldMvp = new List(); - - var mvpConfig = await db.MvpConfigs.FindAsync(x.GuildId); - if (mvpConfig == null) return; - if (mvpConfig.Disabled) return; - if (DateTime.UtcNow.DayOfWeek != mvpConfig.Day && !bypass) return; - - var guild = _client.GetGuild(x.GuildId); - if (guild == null) return; - try - { - if (mvpConfig.RoleId != null) - { - var role = guild.GetRole(mvpConfig.RoleId.Value); - if (role != null) - { - var toAdd = guild.Members.Where(e => e.Value.Roles.ContainsKey(role.Id)).ToList(); - if (toAdd.Count > 0) - { - for (var j = 0; j < toAdd.Count; j++) - { - try - { - await toAdd[j].Value.TryRemoveRoleAsync(role); - oldMvp.Add(toAdd[j].Value); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(MVP Service) Couldn't remove role from {toAdd[j].Key}"); - } - } - } - - var users = await db.Accounts.Where(e => e.GuildId == mvpConfig.GuildId && e.Active && !e.MvpOptOut) - .OrderByDescending(e => e.MvpCount).Take(mvpConfig.Count * 2).ToListAsync(); - for (var j = 0; j < mvpConfig.Count; j++) - { - if (users.Count < mvpConfig.Count && j >= users.Count) continue; - var e = users[j]; - try - { - var user = await guild.GetOrFetchMemberAsync(e.UserId) as CachedMember; - if (user == null) - { - j--; - continue; - } - await user.TryAddRoleAsync(role); - mvp.Add(user); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, $"(MVP Service) Couldn't add role to {e.UserId}"); - } - } - - _log.Log(LogLevel.Info, - $"(MVP Service) Rewarded {mvpConfig.Count} users with MVP role in {guild.Id.RawValue}"); - } - else - { - mvpConfig.RoleId = null; - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, - $"(MVP Service) Reset MVP role as it was null in {guild.Id.RawValue}"); - } - } - try - { - await db.Database.ExecuteSqlRawAsync("UPDATE Accounts " + - "SET MvpCount = 0 " + - $"WHERE GuildId = {x.GuildId}"); - } - catch (Exception e) - { - await db.Accounts.ForEachAsync(z => z.MvpCount = 0); - _log.Log(NLog.LogLevel.Error, e, $"(MVP Service) Failed to execute raw SQL in {x.GuildId}"); - } - await db.SaveChangesAsync(); - _log.Log(LogLevel.Info, $"(MVP Service) Reset every ones MVP counter to 0 in {x.GuildId}"); - - var guildConfig = await db.GetOrCreateGuildConfigAsync(guild); - if (guildConfig.MvpChannel.HasValue) - { - try - { - var channel = guild.GetTextChannel(guildConfig.MvpChannel.Value); - if (channel == null) - { - _log.Log(LogLevel.Error, "(MVP Service) Couldn't find announcement channel"); - return; - } - - var stringBuilder = new StringBuilder(); - for (var j = 0; j < mvp.Count; j++) - { - CachedMember o = null; - CachedMember n = null; - n = mvp[j]; - if (j < oldMvp.Count) - { - o = oldMvp[j]; - } - stringBuilder.AppendLine($"{o?.Mention ?? "User Left"} => {n.Mention}"); - } - - await channel.SendMessageAsync(null, false, new LocalEmbedBuilder().Create( - "New Weekly MVP!\n" + - $"{stringBuilder}", Color.Green).Build()); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, - $"(MVP Service) Couldn't send message for guild {guildConfig.GuildId} in channel {guildConfig.MvpChannel.Value}"); - } - } - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(MVP Service) Error when assigning MVP rewards\n{e.Message}"); - } - } - } -} diff --git a/Hanekawa/Bot/Services/Utility/SelfAssignService.cs b/Hanekawa/Bot/Services/Utility/SelfAssignService.cs deleted file mode 100644 index 2653c175..00000000 --- a/Hanekawa/Bot/Services/Utility/SelfAssignService.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config; -using Hanekawa.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Utility -{ - public class SelfAssignService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly IServiceProvider _provider; - private readonly SemaphoreSlim _lock; - - public SelfAssignService(Hanekawa client, IServiceProvider provider) - { - _client = client; - _provider = provider; - _lock = new SemaphoreSlim(1, 1); - - _client.ReactionAdded += ReactionAdded; - _client.ReactionRemoved += ReactionRemoved; - } - - private Task ReactionAdded(ReactionAddedEventArgs e) - { - _ = Task.Run(async () => - { - if (!e.User.HasValue) return; - if (e.User.Value.IsBot) return; - if (!(e.User.Value is CachedMember user)) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateChannelConfigAsync(user.Guild); - if (!cfg.SelfAssignableChannel.HasValue) return; - if (cfg.SelfAssignableMessages.Length == 0) return; - if (e.Channel.Id.RawValue != cfg.SelfAssignableChannel.Value) return; - if (!cfg.SelfAssignableMessages.Contains(e.Message.Id.RawValue)) return; - - var reaction = await db.SelfAssignAbleRoles.FirstOrDefaultAsync(x => - x.GuildId == user.Guild.Id.RawValue && x.EmoteMessageFormat == e.Emoji.MessageFormat); - if (reaction == null) return; - var role = user.Guild.GetRole(reaction.RoleId); - if (role == null) return; - await _lock.WaitAsync(); - try - { - if (reaction.Exclusive) - { - var roles = await db.SelfAssignAbleRoles.Where(x => x.GuildId == user.Guild.Id.RawValue && x.Exclusive) - .ToListAsync(); - foreach (var x in roles) - { - var exclusiveRole = user.Guild.GetRole(x.RoleId); - if (exclusiveRole == null) continue; - if (user.Roles.Values.Contains(exclusiveRole)) await user.TryRemoveRoleAsync(exclusiveRole); - } - } - if (!user.Roles.ContainsKey(role.Id)) await user.GrantRoleAsync(role.Id); - } - finally - { - _lock.Release(); - } - }); - return Task.CompletedTask; - } - - private Task ReactionRemoved(ReactionRemovedEventArgs e) - { - _ = Task.Run(async () => - { - if (!e.User.HasValue) return; - if (e.User.Value.IsBot) return; - if (!(e.User.Value is CachedMember user)) return; - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateChannelConfigAsync(user.Guild.Id.RawValue); - if (!cfg.SelfAssignableChannel.HasValue) return; - if (cfg.SelfAssignableMessages.Length == 0) return; - if (e.Channel.Id != cfg.SelfAssignableChannel.Value) return; - if (cfg.SelfAssignableMessages.Contains(e.Message.Id.RawValue)) return; - - var reaction = await db.SelfAssignAbleRoles.FirstOrDefaultAsync(x => - x.GuildId == user.Guild.Id.RawValue && x.EmoteMessageFormat == e.Emoji.MessageFormat); - - if (reaction == null) return; - var role = user.Guild.GetRole(reaction.RoleId); - if (role == null) return; - await _lock.WaitAsync(); - try - { - if (user.Roles.ContainsKey(role.Id)) await user.RevokeRoleAsync(role.Id); - } - finally - { - _lock.Release(); - } - }); - return Task.CompletedTask; - } - - public async Task> PostAsync(HanekawaCommandContext context, CachedTextChannel channel, DbService db) - { - var roles = await db.SelfAssignAbleRoles.Where(x => x.GuildId == context.Guild.Id.RawValue) - .OrderByDescending(x => x.Exclusive).ToListAsync(); - if (roles.Count == 0) return null; - var messages = new List(); - var react = new List(); - var reactExt = new List(); - var str = new StringBuilder(); - var strEx = new StringBuilder(); - var counter = 0; - for (var i = 0; i < roles.Count; i++) - { - var x = roles[i]; - var role = context.Guild.GetRole(x.RoleId); - if (role == null) continue; - if (!x.Exclusive) counter = 0; - var msg = LocalCustomEmoji.TryParse(x.EmoteMessageFormat, out var result) - ? $"{result}{role.Mention}" - : $"{role.Mention}"; - if (x.Exclusive) - { - if(result != null) reactExt.Add(result); - if (counter.IsDivisible(5)) str.AppendLine($"{msg}"); - else str.Append($" {msg}"); - } - else - { - if (result != null) react.Add(result); - if (counter.IsDivisible(5)) strEx.AppendLine($"{msg}"); - else strEx.Append($" {msg}"); - } - } - - if (str.Length > 0) - { - var embed = new LocalEmbedBuilder - { - Title = "Self-assignable roles", - Description = str.ToString(), - Color = context.ServiceProvider.GetRequiredService().Get(context.Guild.Id.RawValue) - }; - var rctMsg = await channel.SendMessageAsync(null, false, embed.Build(), LocalMentions.None); - - if(react.Count > 0) - foreach (var x in react) - await rctMsg.AddReactionAsync(x); - messages.Add(rctMsg.Id.RawValue); - } - - if (strEx.Length <= 0) return messages; - { - var embed = new LocalEmbedBuilder - { - Title = "Self-assignable roles", - Description = strEx.ToString(), - Color = context.ServiceProvider.GetRequiredService().Get(context.Guild.Id.RawValue) - }; - var rctExtMsg = await channel.SendMessageAsync(null, false, embed.Build(), LocalMentions.None); - - if(reactExt.Count > 0) - foreach (var x in reactExt) - await rctExtMsg.AddReactionAsync(x); - messages.Add(rctExtMsg.Id.RawValue); - } - return messages; - } - - public async Task UpdatePostAsync(HanekawaCommandContext context) - { - - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Utility/VoiceRoleService.cs b/Hanekawa/Bot/Services/Utility/VoiceRoleService.cs deleted file mode 100644 index 7f6100fa..00000000 --- a/Hanekawa/Bot/Services/Utility/VoiceRoleService.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord.Events; -using Hanekawa.Database; -using Hanekawa.Shared.Interfaces; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Bot.Services.Utility -{ - public class VoiceRoleService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly IServiceProvider _provider; - - public VoiceRoleService(Hanekawa client, IServiceProvider provider) - { - _client = client; - _provider = provider; - - _client.VoiceStateUpdated += VoiceRoleAssignOrRemove; - } - - private Task VoiceRoleAssignOrRemove(VoiceStateUpdatedEventArgs e) - { - _ = Task.Run(async () => - { - if (e.NewVoiceState == null) - { - await DisconnectedAsync(e); - return; - } - - if (e.OldVoiceState == null) - { - await JoinedAsync(e); - return; - } - - if (e.OldVoiceState.ChannelId != e.NewVoiceState.ChannelId) - { - await ChangedChannelAsync(e); - } - }); - return Task.CompletedTask; - } - - private async Task DisconnectedAsync(VoiceStateUpdatedEventArgs e) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var check = await db.VoiceRoles.FindAsync(e.Member.Guild.Id.RawValue, e.OldVoiceState.ChannelId.RawValue); - if (check == null) return; - await e.Member.RevokeRoleAsync(e.Member.Guild.GetRole(check.RoleId).Id); - } - - private async Task JoinedAsync(VoiceStateUpdatedEventArgs e) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var check = await db.VoiceRoles.FindAsync(e.Member.Guild.Id.RawValue, e.NewVoiceState.ChannelId.RawValue); - if (check == null) return; - await e.Member.GrantRoleAsync(e.Member.Guild.GetRole(check.RoleId).Id); - } - - private async Task ChangedChannelAsync(VoiceStateUpdatedEventArgs e) - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var checkOld = await db.VoiceRoles.FindAsync(e.Member.Guild.Id.RawValue, e.OldVoiceState.ChannelId.RawValue); - var checkNew = - await db.VoiceRoles.FindAsync(e.Member.Guild.Id.RawValue, e.NewVoiceState.ChannelId.RawValue); - if (checkOld != null && checkNew != null) - { - if (checkOld.RoleId == checkNew.RoleId) return; - await e.Member.RevokeRoleAsync(e.Member.Guild.GetRole(checkOld.RoleId).Id); - await e.Member.GrantRoleAsync(e.Member.Guild.GetRole(checkNew.RoleId).Id); - return; - } - - if (checkOld != null) - { - await e.Member.RevokeRoleAsync(e.Member.Guild.GetRole(checkOld.RoleId).Id); - return; - } - - if (checkNew != null) - { - await e.Member.GrantRoleAsync(e.Member.Guild.GetRole(checkNew.RoleId).Id); - return; - } - } - } -} diff --git a/Hanekawa/Bot/Services/Welcome/Cooldown.cs b/Hanekawa/Bot/Services/Welcome/Cooldown.cs deleted file mode 100644 index ca0575ba..00000000 --- a/Hanekawa/Bot/Services/Welcome/Cooldown.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Concurrent; -using Disqord; -using Hanekawa.Database.Tables.Config.Guild; -using Microsoft.Extensions.Caching.Memory; - -namespace Hanekawa.Bot.Services.Welcome -{ - public partial class WelcomeService - { - private readonly ConcurrentDictionary _cooldown - = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary _ratelimit - = new ConcurrentDictionary(); - - private readonly ConcurrentDictionary _rewardCd = - new ConcurrentDictionary(); - - private bool OnCooldown(CachedMember user) - { - var users = _cooldown.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (users.TryGetValue(user.Id.RawValue, out _)) return true; - users.Set(user.Id.RawValue, 0, TimeSpan.FromMinutes(10)); - return false; - } - - private bool IsRatelimited(CachedMember user, WelcomeConfig cfg) - { - var users = _ratelimit.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (users.Count + 1 >= cfg.Limit) return true; - users.Set(user.Id.RawValue, 0, TimeSpan.FromSeconds(5)); - return false; - } - - private bool IsRewardCd(CachedMember user) - { - var users = _rewardCd.GetOrAdd(user.Guild.Id.RawValue, new MemoryCache(new MemoryCacheOptions())); - if (users.TryGetValue(user.Id.RawValue, out _)) return true; - users.Set(user.Id.RawValue, 0, TimeSpan.FromMinutes(1)); - return false; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/Services/Welcome/WelcomeService.cs b/Hanekawa/Bot/Services/Welcome/WelcomeService.cs deleted file mode 100644 index 95005d0b..00000000 --- a/Hanekawa/Bot/Services/Welcome/WelcomeService.cs +++ /dev/null @@ -1,219 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Events; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Bot.Services.ImageGen; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Config.Guild; -using Hanekawa.Shared.Interfaces; -using Hanekawa.Utility; -using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.DependencyInjection; -using NLog; - -namespace Hanekawa.Bot.Services.Welcome -{ - public partial class WelcomeService : INService, IRequired - { - private readonly Hanekawa _client; - private readonly ExpService _exp; - private readonly ImageGenerator _img; - private readonly Logger _log; - private readonly IServiceProvider _provider; - - public WelcomeService(Hanekawa client, ImageGenerator img, InternalLogService log, ExpService exp, IServiceProvider provider) - { - _client = client; - _img = img; - _log = LogManager.GetCurrentClassLogger(); - _exp = exp; - _provider = provider; - - _client.MemberJoined += WelcomeUser; - _client.MemberLeft += DeleteBanner; - _client.LeftGuild += LeftGuild; - } - - private Task DeleteBanner(MemberLeftEventArgs e) - { - _ = Task.Run(async () => - { - try - { - if(!_cooldown.TryGetValue(e.Guild.Id.RawValue, out var cooldown)) return; - if (!cooldown.TryGetValue(e.User.Id.RawValue, out var result)) return; - if (!(result is ValueTuple cache)) return; - var channel = e.Guild.GetTextChannel(cache.Item1); - var msg = channel?.GetMessage(cache.Item2); - if (msg == null && channel != null) - { - var message = await channel.GetMessageAsync(cache.Item2); - if (message == null) return; - await message.DeleteAsync(); - cooldown.Set(e.User.Id.RawValue, 0); - if (cache.Item3.Status == TaskStatus.Running) cache.Item3.Dispose(); - return; - } - - if (msg == null) return; - await msg.DeleteAsync(); - cooldown.Set(e.User.Id.RawValue, 0); - if (cache.Item3.Status == TaskStatus.Running) cache.Item3.Dispose(); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Welcome Service) Error in {e.Guild.Id.RawValue} for User Left (Banner Cleanup) - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private Task WelcomeUser(MemberJoinedEventArgs e) - { - _ = Task.Run(async () => - { - var user = e.Member; - if (user.IsBot) return; - if (user.CreatedAt >= DateTimeOffset.UtcNow.AddMinutes(10)) return; - if (OnCooldown(user)) return; - try - { - using var scope = _provider.CreateScope(); - await using var db = scope.ServiceProvider.GetRequiredService(); - var cfg = await db.GetOrCreateWelcomeConfigAsync(user.Guild); - if (IsRatelimited(user, cfg)) return; - if (!cfg.Channel.HasValue) return; - var msg = MessageUtil.FormatMessage(cfg.Message, user, user.Guild); - IMessage message; - var channel = user.Guild.GetTextChannel(cfg.Channel.Value); - if (channel == null) return; - if (cfg.Banner) - { - var guildCfg = await db.GetOrCreateGuildConfigAsync(user.Guild); - var (stream, isGif) = await _img.WelcomeBuilder(user, db, guildCfg.Premium); - stream.Position = 0; - message = isGif - ? await channel.SendMessageAsync(new LocalAttachment(stream, "Welcome.gif"), msg, false, - null, LocalMentions.None) - : await channel.SendMessageAsync(new LocalAttachment(stream, "Welcome.png"), msg, false, - null, LocalMentions.None); - } - else - { - if (msg == null) return; - message = await channel.SendMessageAsync(msg, false, null, LocalMentions.None); - } - - var del = DeleteWelcomeAsync(message, cfg); - var exp = WelcomeRewardAsync(_client, channel, cfg, db); - if (message != null && _cooldown.TryGetValue(user.Guild.Id.RawValue, out var userCooldown)) - userCooldown.Set(user.Id.RawValue, - new ValueTuple(channel.Id.RawValue, message.Id.RawValue, del)); - await Task.WhenAny(del, exp); - _log.Log(LogLevel.Info,$"(Welcome Service) User joined {user.Guild.Id.RawValue}"); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Welcome Service) Error in {user.Guild.Id.RawValue} for User Joined - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - - private async Task WelcomeRewardAsync(Hanekawa bot, CachedTextChannel channel, WelcomeConfig cfg, DbService db) - { - if (!cfg.Reward.HasValue) return; - try - { - var users = new ConcurrentQueue(); - var s = new Stopwatch(); - s.Start(); - while (s.Elapsed <= TimeSpan.FromMinutes(1)) - { - var response = await bot.GetInteractivity().WaitForMessageAsync( - x => x.Message.Content.Contains("welcome", StringComparison.OrdinalIgnoreCase) && - x.Message.Guild.Id.RawValue == cfg.GuildId && - x.Message.Channel.Id.RawValue == channel.Id.RawValue && - !x.Message.Author.IsBot, - TimeSpan.FromMinutes(1)); - _ = Task.Run(() => - { - var res = response; - try - { - if (res == null) return; - if (!(res.Message.Author is CachedMember user)) return; - if (IsRewardCd(user)) return; - if (user.JoinedAt.AddHours(2) >= DateTimeOffset.UtcNow) return; - if (users.Contains(user)) return; - users.Enqueue(user); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, e.Message); - } - }); - } - - s.Stop(); - await Task.Delay(TimeSpan.FromSeconds(5)); - while (users.TryDequeue(out var user)) - { - var userData = await db.GetOrCreateUserData(user); - await _exp.AddExpAsync(user, userData, cfg.Reward.Value, 0, db); - } - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, e.Message); - } - } - - private async Task DeleteWelcomeAsync(IMessage msg, WelcomeConfig cfg) - { - try - { - if (!cfg.TimeToDelete.HasValue) return; - await Task.Delay(cfg.TimeToDelete.Value); - await msg.DeleteAsync(); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Welcome Service) Couldn't delete banner in {cfg.GuildId}"); - } - } - - private Task LeftGuild(LeftGuildEventArgs e) - { - _ = Task.Run(async () => - { - var guild = e.Guild; - try - { - using (var scope = _provider.CreateScope()) - await using (var db = scope.ServiceProvider.GetRequiredService()) - { - var banners = db.WelcomeBanners.Where(x => x.GuildId == guild.Id.RawValue); - db.WelcomeBanners.RemoveRange(banners); - await db.SaveChangesAsync(); - } - _log.Log(LogLevel.Info, $"(Welcome Service) Cleaned up banners in {guild.Id.RawValue} as bot left server"); - } - catch (Exception exception) - { - _log.Log(NLog.LogLevel.Error, exception, - $"(Welcome Service) Error in {guild.Id.RawValue} for Bot Left Guild - {exception.Message}"); - } - }); - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/TypeReaders/ColourTypeParser.cs b/Hanekawa/Bot/TypeReaders/ColourTypeParser.cs deleted file mode 100644 index f4569caf..00000000 --- a/Hanekawa/Bot/TypeReaders/ColourTypeParser.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Globalization; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Shared.Command; -using Qmmands; - -namespace Hanekawa.Bot.TypeReaders -{ - public class ColourTypeParser : TypeParser - { - public override ValueTask> ParseAsync(Parameter parameter, string value, CommandContext context) - { - if(Enum.TryParse(typeof(HanaColor), value, true, out var enumResult)) - { - if (enumResult is HanaColor color) - { - switch (color) - { - case HanaColor.Default: - return TypeParserResult.Successful(HanaBaseColor.Default()); - case HanaColor.Green: - return TypeParserResult.Successful(HanaBaseColor.Green()); - case HanaColor.Red: - return TypeParserResult.Successful(HanaBaseColor.Red()); - case HanaColor.Blue: - return TypeParserResult.Successful(HanaBaseColor.Blue()); - case HanaColor.Purple: - return TypeParserResult.Successful(HanaBaseColor.Purple()); - case HanaColor.Pink: - return TypeParserResult.Successful(HanaBaseColor.Pink()); - case HanaColor.Yellow: - return TypeParserResult.Successful(HanaBaseColor.Yellow()); - case HanaColor.Black: - return TypeParserResult.Successful(HanaBaseColor.Black()); - case HanaColor.White: - return TypeParserResult.Successful(HanaBaseColor.White()); - case HanaColor.Brown: - return TypeParserResult.Successful(HanaBaseColor.Brown()); - case HanaColor.Orange: - return TypeParserResult.Successful(HanaBaseColor.Orange()); - case HanaColor.Aqua: - return TypeParserResult.Successful(HanaBaseColor.Aqua()); - case HanaColor.Maroon: - return TypeParserResult.Successful(HanaBaseColor.Maroon()); - case HanaColor.Olive: - return TypeParserResult.Successful(HanaBaseColor.Olive()); - case HanaColor.Gray: - return TypeParserResult.Successful(HanaBaseColor.Gray()); - case HanaColor.Silver: - return TypeParserResult.Successful(HanaBaseColor.Silver()); - case HanaColor.Fuchsia: - return TypeParserResult.Successful(HanaBaseColor.Fuchsia()); - case HanaColor.Navy: - return TypeParserResult.Successful(HanaBaseColor.Navy()); - case HanaColor.Teal: - return TypeParserResult.Successful(HanaBaseColor.Teal()); - case HanaColor.Lime: - return TypeParserResult.Successful(HanaBaseColor.Lime()); - } - } - } - if (value.Length > 2) - { - var s = value.AsSpan(); - var flag = false; - if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && s.Length == 8) - { - flag = true; - s = s.Slice(2); - } - else if (value[0] == '#' && value.Length == 7) - { - flag = true; - s = s.Slice(1); - } - - if (flag && uint.TryParse(s, NumberStyles.HexNumber, null, out var result)) - return TypeParserResult.Successful((int)result); - } - return TypeParserResult.Unsuccessful("Invalid color name or hex value."); - } - } -} diff --git a/Hanekawa/Bot/TypeReaders/EmoteTypeReader.cs b/Hanekawa/Bot/TypeReaders/EmoteTypeReader.cs deleted file mode 100644 index 28bd2c3d..00000000 --- a/Hanekawa/Bot/TypeReaders/EmoteTypeReader.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Threading.Tasks; -using Hanekawa.Shared.Command; -using Qmmands; - -namespace Hanekawa.Bot.TypeReaders -{ - /* - public class EmoteTypeReader : HanekawaTypeParser - { - public override ValueTask> ParseAsync(Parameter parameter, string value, - DiscordCommandContext context, IServiceProvider provider) => - Emote.TryParse(value, out var emote) - ? TypeParserResult.Successful(emote) - : TypeParserResult.Unsuccessful("Failed to parse into a emote"); - } - */ -} \ No newline at end of file diff --git a/Hanekawa/Bot/TypeReaders/EnumTypeParser.cs b/Hanekawa/Bot/TypeReaders/EnumTypeParser.cs deleted file mode 100644 index 6220d40d..00000000 --- a/Hanekawa/Bot/TypeReaders/EnumTypeParser.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Threading.Tasks; -using Qmmands; - -namespace Hanekawa.Bot.TypeReaders -{ - public class EnumTypeParser : TypeParser - { - public override ValueTask> ParseAsync(Parameter parameter, string value, CommandContext context) => throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/Hanekawa/Bot/TypeReaders/RangeTypeParser.cs b/Hanekawa/Bot/TypeReaders/RangeTypeParser.cs deleted file mode 100644 index 22f9a351..00000000 --- a/Hanekawa/Bot/TypeReaders/RangeTypeParser.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.Threading.Tasks; -using Qmmands; - -namespace Hanekawa.Bot.TypeReaders -{ - public class RangeTypeParser : TypeParser - { - public override ValueTask> ParseAsync(Parameter parameter, string value, CommandContext context) - { - var result = value.Split('-'); - int minValue = int.MaxValue; - int maxValue = 0; - foreach (var x in result) - { - if (!int.TryParse(x, out var val)) return TypeParserResult.Unsuccessful("Failed to parse range"); - - if (val > maxValue) maxValue = val; - if (val < minValue) minValue = val; - } - - return TypeParserResult.Successful(new Models.Range(minValue, maxValue)); - } - } -} diff --git a/Hanekawa/Bot/TypeReaders/TimeSpanTypeParser.cs b/Hanekawa/Bot/TypeReaders/TimeSpanTypeParser.cs deleted file mode 100644 index 8475186e..00000000 --- a/Hanekawa/Bot/TypeReaders/TimeSpanTypeParser.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Globalization; -using System.Threading.Tasks; -using Qmmands; - -namespace Hanekawa.Bot.TypeReaders -{ - public class TimeSpanTypeParser : TypeParser - { - private static readonly string[] Formats = - { - "%d'd'%h'h'%m'm'%s's'", //4d3h2m1s - "%d'd'%h'h'%m'm'", //4d3h2m - "%d'd'%h'h'%s's'", //4d3h 1s - "%d'd'%h'h'", //4d3h - "%d'd'%m'm'%s's'", //4d 2m1s - "%d'd'%m'm'", //4d 2m - "%d'd'%s's'", //4d 1s - "%d'd'", //4d - "%h'h'%m'm'%s's'", // 3h2m1s - "%h'h'%m'm'", // 3h2m - "%h'h'%s's'", // 3h 1s - "%h'h'", // 3h - "%m'm'%s's'", // 2m1s - "%m'm'", // 2m - "%s's'" // 1s - }; - - public override ValueTask> ParseAsync(Parameter parameter, string value, - CommandContext context) - { - if (TimeSpan.TryParseExact(value.ToLowerInvariant(), Formats, CultureInfo.InvariantCulture, - out var timespan)) return TypeParserResult.Successful(timespan); - - return !int.TryParse(value, out var minutes) - ? TypeParserResult.Unsuccessful("Failed to parse timespan") - : minutes <= 0 - ? TypeParserResult.Unsuccessful("Failed to parse timespan") - : TypeParserResult.Successful(new TimeSpan(0, minutes, 0)); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Controllers/AdvertController.cs b/Hanekawa/Controllers/AdvertController.cs deleted file mode 100644 index 24759448..00000000 --- a/Hanekawa/Controllers/AdvertController.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Disqord; -using Hanekawa.Bot.Services; -using Hanekawa.Bot.Services.Economy; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Database; -using Hanekawa.Database.Extensions; -using Hanekawa.Database.Tables.Advertise; -using Hanekawa.Database.Tables.Giveaway; -using Hanekawa.Extensions; -using Hanekawa.Models; -using Hanekawa.Shared; -using Hanekawa.Shared.Command; -using Hanekawa.Utility; -using Humanizer; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using NLog; -using Quartz.Util; - -namespace Hanekawa.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class AdvertController : ControllerBase - { - private readonly DbService _db; - private readonly Bot.Hanekawa _client; - private readonly ExpService _exp; - private readonly NLog.Logger _log; - private readonly ColourService _colour; - private readonly CurrencyService _currency; - - public AdvertController(DbService db, Bot.Hanekawa client, ExpService exp, ColourService colour, CurrencyService currency) - { - _db = db; - _client = client; - _exp = exp; - _log = LogManager.GetCurrentClassLogger(); - _colour = colour; - _currency = currency; - } - - [HttpPost("dbl")] - public async Task Dsl([FromBody] DslWebhook model) - { - try - { - // Check if header has right agent - if (!Request.Headers.TryGetValue("User-Agent", out var agent)) return BadRequest(); - if (!agent.Contains("DBL")) return BadRequest(); // If not send bad request, only accepting DBL user agents - // Check if user has a authorization in the header, else return forbidden - // we only accept requests with an authorization in the header - if (!Request.Headers.TryGetValue("Authorization", out var authCode)) return Unauthorized("No authorization header"); - var guildId = Convert.ToUInt64(model.Guild); - var cfg = await _db.DblAuths.FindAsync(guildId); // Get the key from database - // If there's no config, the guild doesn't have it enabled - if (cfg == null) return BadRequest(); - // Make sure the key is correct - if (cfg.AuthKey.ToString() != authCode.ToString()) return Unauthorized("Invalid key"); - - var guild = _client.GetGuild(guildId); // Get guild and check if bot is in guild, could be kicked - if (guild == null) return BadRequest("Invalid guild"); - // Get user data and reward from config - var userId = Convert.ToUInt64(model.User); - var userData = await _db.GetOrCreateUserData(guildId, userId); - var user = await guild.GetOrFetchMemberAsync(userId) as CachedMember; - if (cfg.SpecialCredit > 0) userData.CreditSpecial += cfg.SpecialCredit; // Manually add as AddExp doesn't do special credit, maybe add later? - if (user != null) - { - await _exp.AddExpAsync(user, userData, cfg.ExpGain, cfg.CreditGain, _db); - if (cfg.RoleIdReward.HasValue && !user.Roles.ContainsKey(cfg.RoleIdReward.Value)) // Reward a role if its in the config and the user doesn't already have it - await user.GrantRoleAsync(cfg.RoleIdReward.Value); - } - else - { - if (cfg.ExpGain > 0) userData.Exp += cfg.ExpGain; - if (cfg.ExpGain > 0) userData.TotalExp += cfg.ExpGain; - if (cfg.CreditGain > 0) userData.Credit += cfg.CreditGain; - } - // Add a log entry for the vote to keep track of votes - await _db.VoteLogs.AddAsync(new VoteLog - { - GuildId = guildId, - UserId = userId, - Type = model.Type, - Time = DateTimeOffset.UtcNow - }); - - var logCfg = await _db.GetOrCreateLoggingConfigAsync(guild); - if (logCfg.LogAvi.HasValue) - { - var name = $"{user}"; - if (name.IsNullOrWhiteSpace()) name = $"{userId}"; - await guild.GetTextChannel(logCfg.LogAvi.Value).SendMessageAsync(null, false, new LocalEmbedBuilder - { - Title = "Top.gg Vote!", - Color = _colour.Get(guild.Id.RawValue), - Description = $"{name} just voted for the server!", - Footer = new LocalEmbedFooterBuilder{ IconUrl = user?.GetAvatarUrl(), Text = $"Username: {name} ({userId})"} - }.Build()); - } - _log.Log(LogLevel.Info, $"(Advert Endpoint) Rewarded {userId} in {guild.Id.RawValue} for voting on the server!"); - - var giveaways = await _db.Giveaways - .Where(x => x.GuildId == guildId && x.Type == GiveawayType.Vote && x.Active).ToListAsync(); - var sb = new StringBuilder(); - if (giveaways.Count > 0 && user != null) - { - sb.AppendLine("Your entry has been registered toward the following giveaways:"); - var length = sb.Length; - for (var i = 0; i < giveaways.Count; i++) - { - var x = giveaways[i]; - if(!x.Active) continue; - if(x.CloseAtOffset.HasValue && x.CloseAtOffset.Value <= DateTimeOffset.UtcNow) continue; - if (x.ServerAgeRequirement.HasValue && - user.JoinedAt.Add(x.ServerAgeRequirement.Value) > DateTimeOffset.UtcNow) - { - sb.AppendLine( - $"You don't qualify for {x.Name} giveaway, your account has to be in the server for at least {x.ServerAgeRequirement.Value.Humanize()}"); - continue; - } - - if (userData.Level < x.LevelRequirement) - { - sb.AppendLine( - $"You don't qualify for {x.Name} giveaway, you need to be at least of level{x.LevelRequirement} to enter."); - continue; - } - - await _db.GiveawayParticipants.AddAsync(new GiveawayParticipant - { - Id = Guid.NewGuid(), - GuildId = guildId, - UserId = userId, - GiveawayId = x.Id, - Giveaway = x, - Entry = DateTimeOffset.UtcNow - }); - sb.AppendLine($"{x.Name}"); - } - - if (sb.Length == length) sb.Clear(); - } - - await _db.SaveChangesAsync(); - if (cfg.Message.IsNullOrWhiteSpace() && user == null) return Accepted(); // Check if there's a message to be sent, else we good - try - { - var str = new StringBuilder(); - var currencyCfg = await _db.GetOrCreateCurrencyConfigAsync(guildId); - if (cfg.ExpGain > 0) str.AppendLine($"{cfg.ExpGain} Exp"); - if (cfg.CreditGain > 0) str.AppendLine($"{currencyCfg.CurrencyName}: {_currency.ToCurrency(currencyCfg, cfg.CreditGain)}"); - if (cfg.SpecialCredit > 0) str.AppendLine($"{currencyCfg.SpecialCurrencyName}: {_currency.ToCurrency(currencyCfg, cfg.SpecialCredit, true)}"); - if (user.DmChannel != null) // determine if dm channel is already created, else create it and send message - await user.DmChannel.SendMessageAsync( - $"{MessageUtil.FormatMessage(cfg.Message, user, user.Guild)}\n" + - "You've been rewarded:\n" + - $"{str}\n{sb}", false, - null, - LocalMentions.None); - else - { - var channel = await user.CreateDmChannelAsync(); - await channel.SendMessageAsync($"{MessageUtil.FormatMessage(cfg.Message, user, user.Guild)}\n" + - "You've been rewarded:\n" + - $"{str}\n{sb}", false, - null, - LocalMentions.None); - } - } - catch - { - // Ignore, the user likely has closed DMs - } - return Accepted(); - } - catch (Exception e) - { - _log.Log(NLog.LogLevel.Error, e, $"(Advert Endpoint) Error in awarding user for voting - {e.Message}"); - return StatusCode(500); - } - } - } -} \ No newline at end of file diff --git a/Hanekawa/Controllers/BanController.cs b/Hanekawa/Controllers/BanController.cs deleted file mode 100644 index a0ec6d84..00000000 --- a/Hanekawa/Controllers/BanController.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Threading.Tasks; -using Hanekawa.Database; -using Hanekawa.Models.Api; -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; - -namespace Hanekawa.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class BanController : ControllerBase - { - private readonly Bot.Hanekawa _bot; - private readonly DbService _db; - - public BanController(Bot.Hanekawa bot, DbService db) - { - _bot = bot; - _db = db; - } - - [HttpGet("{rawId}/{userId}")] - public async Task GetBanCaseAsync([FromRoute] string rawId, [FromRoute]string userId) - { - if (!ulong.TryParse(rawId, out var guildId)) return null; - var guild = _bot.GetGuild(guildId); - if (guild == null) return null; - if (!ulong.TryParse(userId, out var id)) return null; - var modCase = await _db.ModLogs.FirstOrDefaultAsync(x => x.Action == "Ban" && x.GuildId == guildId && x.UserId == id); - return new BanCase(modCase); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Controllers/CommandsController.cs b/Hanekawa/Controllers/CommandsController.cs deleted file mode 100644 index dc5da49a..00000000 --- a/Hanekawa/Controllers/CommandsController.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Disqord; -using Disqord.Bot; -using Hanekawa.Bot.Preconditions; -using Microsoft.AspNetCore.Mvc; -using Qmmands; -using Command = Hanekawa.Models.Api.Command; -using Module = Hanekawa.Models.Api.Module; - -namespace Hanekawa.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class CommandsController : ControllerBase - { - private readonly Bot.Hanekawa _bot; - public CommandsController(Bot.Hanekawa bot) => _bot = bot; - - [HttpGet] - public List GetCommands() - { - var toReturn = new List(); - var modules = _bot.GetAllModules().OrderBy(x => x.Name); - foreach (var x in modules) - { - if(x.Name == "Owner") continue; - var commands = new Dictionary(); - foreach (var c in x.Commands) - { - if (commands.TryGetValue(c.Name, out var command)) - { - command.Example.Add($"{c.FullAliases.FirstOrDefault()} {ExampleParamBuilder(c)}"); - } - else - { - commands.TryAdd(c.Name, new Command - { - Name = c.Name, - Commands = c.FullAliases.ToList(), - Description = c.Description, - Example = new List - {$"{c.FullAliases.FirstOrDefault()} {ExampleParamBuilder(c)}"}, - Premium = PremiumCheck(c), - Permissions = PermBuilder(c) - }); - } - } - toReturn.Add(new Module - { - Name = x.Name, - Description = x.Description, - Commands = commands.Select(z => z.Value).ToList() - }); - } - - return toReturn; - } - - private static bool PremiumCheck(Qmmands.Command cmd) - { - var premium = cmd.Checks.FirstOrDefault(x => x is RequirePremium) - ?? cmd.Module.Checks.FirstOrDefault(x => x is RequirePremium); - return premium != null; - } - - private static List PermBuilder(Qmmands.Command cmd) - { - var str = new List(); - foreach (var x in cmd.Module.Checks) - { - if (x is RequireMemberGuildPermissionsAttribute perm) - { - str.Add(perm.Permissions.FirstOrDefault().ToString()); - } - } - foreach (var x in cmd.Checks) - { - if (x is RequireMemberGuildPermissionsAttribute perm) - { - str.Add(perm.Permissions.FirstOrDefault().ToString()); - } - } - - return str; - } - - private string ExampleParamBuilder(Qmmands.Command command) - { - var output = new StringBuilder(); - if (!command.Parameters.Any()) return output.ToString(); - foreach (var x in command.Parameters) - { - var name = PermTypeBuilder(x); - if (x.IsOptional) - output.Append($"{name} "); - else if (x.IsRemainder) - output.Append($"{name} "); - else if (x.IsMultiple) - output.Append($"{name} "); - else - output.Append($"{name} "); - } - - return output.ToString(); - } - - private static string PermTypeBuilder(Parameter parameter) => - parameter.Type == typeof(CachedMember) ? "@bob#0000" : - parameter.Type == typeof(CachedRole) ? "role" : - parameter.Type == typeof(CachedTextChannel) ? "#General" : - parameter.Type == typeof(CachedVoiceChannel) ? "VoiceChannel" : - parameter.Type == typeof(CachedCategoryChannel) ? "Category" : - parameter.Type == typeof(TimeSpan?) ? "1h2m" : - parameter.Type == typeof(TimeSpan) ? "1h2m" : - parameter.Type == typeof(int) ? "5" : - parameter.Type == typeof(string) ? "Example text" : - parameter.Type == typeof(ulong) ? "431610594290827267" : parameter.Name; - } -} \ No newline at end of file diff --git a/Hanekawa/Controllers/LeaderboardController.cs b/Hanekawa/Controllers/LeaderboardController.cs deleted file mode 100644 index 7bd2598f..00000000 --- a/Hanekawa/Controllers/LeaderboardController.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Linq; -using Microsoft.AspNetCore.Mvc; -using System.Threading.Tasks; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Database; -using Hanekawa.Models.Api; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; - -namespace Hanekawa.Controllers -{ - [Route("api/[controller]")] - [ApiController] - public class LeaderboardController : ControllerBase - { - private readonly Bot.Hanekawa _bot; - private readonly IServiceProvider _provider; - private readonly DbService _db; - - public LeaderboardController(Bot.Hanekawa bot, IServiceProvider provider, DbService db) - { - _bot = bot; - _provider = provider; - _db = db; - } - - [HttpGet("{rawId}")] - public async Task GetLeaderboardAsync([FromRoute] string rawId) - { - if (!ulong.TryParse(rawId, out var id)) return null; - var guild = _bot.GetGuild(id); - if (guild == null) return null; - var toReturn = new Leaderboard {Users = new ()}; - var users = await _db.Accounts.Where(x => x.GuildId == id && x.Active) - .OrderByDescending(x => x.TotalExp - x.Decay).Take(100).ToListAsync(); - var exp = _provider.GetRequiredService(); - foreach (var x in users) - { - var user = guild.GetMember(x.UserId); - if (user != null) - { - toReturn.Users.Add(new LeaderboardUser - { - UserId = x.UserId, - ExpToLevel = exp.ExpToNextLevel(x.Level), - Experience = x.Exp, - Level = x.Level, - TotalExp = x.TotalExp - }); - } - } - return toReturn; - } - - [HttpGet("{rawId}/weekly")] - public async Task GetWeeklyLeaderboardAsync([FromRoute] string rawId) - { - if (!ulong.TryParse(rawId, out var id)) return null; - var guild = _bot.GetGuild(id); - if (guild == null) return null; - var toReturn = new LeaderboardWeekly {Users = new()}; - var users = await _db.Accounts.Where(x => x.GuildId == id && x.Active) - .OrderByDescending(x => x.MvpCount).Take(100).ToListAsync(); - foreach (var x in users) - { - toReturn.Users.Add(new LeaderboardWeeklyUser - { - UserId = x.UserId, - Points = x.MvpCount - }); - } - return toReturn; - } - - [HttpGet("{rawId}/richest")] - public async Task GetRichestLeaderboardAsync([FromRoute] string rawId) - { - if (!ulong.TryParse(rawId, out var id)) return null; - var guild = _bot.GetGuild(id); - if (guild == null) return null; - var toReturn = new LeaderboardWeekly {Users = new()}; - var users = await _db.Accounts.Where(x => x.GuildId == id && x.Active) - .OrderByDescending(x => x.Credit).Take(100).ToListAsync(); - foreach (var x in users) - { - toReturn.Users.Add(new LeaderboardWeeklyUser - { - UserId = x.UserId, - Points = x.Credit - }); - } - return toReturn; - } - } -} diff --git a/Hanekawa/Data/Fonts/ARIALBD.TTF b/Hanekawa/Data/Fonts/ARIALBD.TTF deleted file mode 100644 index a6037e68..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALBD.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIALBI.TTF b/Hanekawa/Data/Fonts/ARIALBI.TTF deleted file mode 100644 index 6a1fa0fa..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALBI.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIALI.TTF b/Hanekawa/Data/Fonts/ARIALI.TTF deleted file mode 100644 index 38019978..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALI.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIALN.TTF b/Hanekawa/Data/Fonts/ARIALN.TTF deleted file mode 100644 index 94907a3d..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALN.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIALNB.TTF b/Hanekawa/Data/Fonts/ARIALNB.TTF deleted file mode 100644 index 62437f02..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALNB.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIALNBI.TTF b/Hanekawa/Data/Fonts/ARIALNBI.TTF deleted file mode 100644 index d3f019a3..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALNBI.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIALNI.TTF b/Hanekawa/Data/Fonts/ARIALNI.TTF deleted file mode 100644 index 4acd4685..00000000 Binary files a/Hanekawa/Data/Fonts/ARIALNI.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/ARIBLK.TTF b/Hanekawa/Data/Fonts/ARIBLK.TTF deleted file mode 100644 index e7ae345a..00000000 Binary files a/Hanekawa/Data/Fonts/ARIBLK.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/TIMESBD.TTF b/Hanekawa/Data/Fonts/TIMESBD.TTF deleted file mode 100644 index 43259eb7..00000000 Binary files a/Hanekawa/Data/Fonts/TIMESBD.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/TIMESBI.TTF b/Hanekawa/Data/Fonts/TIMESBI.TTF deleted file mode 100644 index c0b27d20..00000000 Binary files a/Hanekawa/Data/Fonts/TIMESBI.TTF and /dev/null differ diff --git a/Hanekawa/Data/Fonts/TIMESI.TTF b/Hanekawa/Data/Fonts/TIMESI.TTF deleted file mode 100644 index 4bcad692..00000000 Binary files a/Hanekawa/Data/Fonts/TIMESI.TTF and /dev/null differ diff --git a/Hanekawa/Data/Game/Border/Red-border.png b/Hanekawa/Data/Game/Border/Red-border.png deleted file mode 100644 index cbbccbd6..00000000 Binary files a/Hanekawa/Data/Game/Border/Red-border.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/BattleshipReClass.png b/Hanekawa/Data/Game/Enemy/BattleshipReClass.png deleted file mode 100644 index 56b133b0..00000000 Binary files a/Hanekawa/Data/Game/Enemy/BattleshipReClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/BattleshipRuClass.png b/Hanekawa/Data/Game/Enemy/BattleshipRuClass.png deleted file mode 100644 index 2ef2e3aa..00000000 Binary files a/Hanekawa/Data/Game/Enemy/BattleshipRuClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/BattleshipTaClass.png b/Hanekawa/Data/Game/Enemy/BattleshipTaClass.png deleted file mode 100644 index f2233104..00000000 Binary files a/Hanekawa/Data/Game/Enemy/BattleshipTaClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/DestroyerHaClass.png b/Hanekawa/Data/Game/Enemy/DestroyerHaClass.png deleted file mode 100644 index c0a8a498..00000000 Binary files a/Hanekawa/Data/Game/Enemy/DestroyerHaClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/DestroyerIClass.png b/Hanekawa/Data/Game/Enemy/DestroyerIClass.png deleted file mode 100644 index 7a3f81a8..00000000 Binary files a/Hanekawa/Data/Game/Enemy/DestroyerIClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/DestroyerNiClass.png b/Hanekawa/Data/Game/Enemy/DestroyerNiClass.png deleted file mode 100644 index e405b864..00000000 Binary files a/Hanekawa/Data/Game/Enemy/DestroyerNiClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/DestroyerRoClass.png b/Hanekawa/Data/Game/Enemy/DestroyerRoClass.png deleted file mode 100644 index dd4aae5d..00000000 Binary files a/Hanekawa/Data/Game/Enemy/DestroyerRoClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/HeavyCruiserNeClass.png b/Hanekawa/Data/Game/Enemy/HeavyCruiserNeClass.png deleted file mode 100644 index b9c2865b..00000000 Binary files a/Hanekawa/Data/Game/Enemy/HeavyCruiserNeClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/HeavyCruiserRiClass.png b/Hanekawa/Data/Game/Enemy/HeavyCruiserRiClass.png deleted file mode 100644 index dd0aba16..00000000 Binary files a/Hanekawa/Data/Game/Enemy/HeavyCruiserRiClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/LightCarrierNuClass.png b/Hanekawa/Data/Game/Enemy/LightCarrierNuClass.png deleted file mode 100644 index ea4e49e1..00000000 Binary files a/Hanekawa/Data/Game/Enemy/LightCarrierNuClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/LightCruiserHeClass.png b/Hanekawa/Data/Game/Enemy/LightCruiserHeClass.png deleted file mode 100644 index d02435b1..00000000 Binary files a/Hanekawa/Data/Game/Enemy/LightCruiserHeClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/LightCruiserHoClass.png b/Hanekawa/Data/Game/Enemy/LightCruiserHoClass.png deleted file mode 100644 index 2f3d31a6..00000000 Binary files a/Hanekawa/Data/Game/Enemy/LightCruiserHoClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/LightCruiserToClass.png b/Hanekawa/Data/Game/Enemy/LightCruiserToClass.png deleted file mode 100644 index 7dd3a61a..00000000 Binary files a/Hanekawa/Data/Game/Enemy/LightCruiserToClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/LightCruiserTsuClass.png b/Hanekawa/Data/Game/Enemy/LightCruiserTsuClass.png deleted file mode 100644 index 98feea0b..00000000 Binary files a/Hanekawa/Data/Game/Enemy/LightCruiserTsuClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/StandardCarrierWoClass.png b/Hanekawa/Data/Game/Enemy/StandardCarrierWoClass.png deleted file mode 100644 index 3c13e42e..00000000 Binary files a/Hanekawa/Data/Game/Enemy/StandardCarrierWoClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/SubmarineKaClass.png b/Hanekawa/Data/Game/Enemy/SubmarineKaClass.png deleted file mode 100644 index c0522e36..00000000 Binary files a/Hanekawa/Data/Game/Enemy/SubmarineKaClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/SubmarineSoClass.png b/Hanekawa/Data/Game/Enemy/SubmarineSoClass.png deleted file mode 100644 index 93dccb16..00000000 Binary files a/Hanekawa/Data/Game/Enemy/SubmarineSoClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/SubmarineYoClass.png b/Hanekawa/Data/Game/Enemy/SubmarineYoClass.png deleted file mode 100644 index 6cb4e84e..00000000 Binary files a/Hanekawa/Data/Game/Enemy/SubmarineYoClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/TorpedoCruiserChiClass.png b/Hanekawa/Data/Game/Enemy/TorpedoCruiserChiClass.png deleted file mode 100644 index b986428e..00000000 Binary files a/Hanekawa/Data/Game/Enemy/TorpedoCruiserChiClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/Enemy/TransportShipWaClass.png b/Hanekawa/Data/Game/Enemy/TransportShipWaClass.png deleted file mode 100644 index 898b1e4d..00000000 Binary files a/Hanekawa/Data/Game/Enemy/TransportShipWaClass.png and /dev/null differ diff --git a/Hanekawa/Data/Game/background.png b/Hanekawa/Data/Game/background.png deleted file mode 100644 index 8b6bb085..00000000 Binary files a/Hanekawa/Data/Game/background.png and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/1.jpg b/Hanekawa/Data/Profile/Default/1.jpg deleted file mode 100644 index f08c8329..00000000 Binary files a/Hanekawa/Data/Profile/Default/1.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/10.jpg b/Hanekawa/Data/Profile/Default/10.jpg deleted file mode 100644 index 571a7043..00000000 Binary files a/Hanekawa/Data/Profile/Default/10.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/11.jpg b/Hanekawa/Data/Profile/Default/11.jpg deleted file mode 100644 index 45fc321b..00000000 Binary files a/Hanekawa/Data/Profile/Default/11.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/12.jpg b/Hanekawa/Data/Profile/Default/12.jpg deleted file mode 100644 index b6a05c7d..00000000 Binary files a/Hanekawa/Data/Profile/Default/12.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/13.jpg b/Hanekawa/Data/Profile/Default/13.jpg deleted file mode 100644 index e2f09a2e..00000000 Binary files a/Hanekawa/Data/Profile/Default/13.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/2.jpg b/Hanekawa/Data/Profile/Default/2.jpg deleted file mode 100644 index fc2e1486..00000000 Binary files a/Hanekawa/Data/Profile/Default/2.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/3.jpg b/Hanekawa/Data/Profile/Default/3.jpg deleted file mode 100644 index fcd081b4..00000000 Binary files a/Hanekawa/Data/Profile/Default/3.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/4.jpg b/Hanekawa/Data/Profile/Default/4.jpg deleted file mode 100644 index 8bf34c19..00000000 Binary files a/Hanekawa/Data/Profile/Default/4.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/5.jpg b/Hanekawa/Data/Profile/Default/5.jpg deleted file mode 100644 index 15ac8a38..00000000 Binary files a/Hanekawa/Data/Profile/Default/5.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/6.jpg b/Hanekawa/Data/Profile/Default/6.jpg deleted file mode 100644 index 96759f74..00000000 Binary files a/Hanekawa/Data/Profile/Default/6.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/7.jpg b/Hanekawa/Data/Profile/Default/7.jpg deleted file mode 100644 index 296f0aa1..00000000 Binary files a/Hanekawa/Data/Profile/Default/7.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/8.jpg b/Hanekawa/Data/Profile/Default/8.jpg deleted file mode 100644 index 27b73a84..00000000 Binary files a/Hanekawa/Data/Profile/Default/8.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Default/9.jpg b/Hanekawa/Data/Profile/Default/9.jpg deleted file mode 100644 index 201ed6f8..00000000 Binary files a/Hanekawa/Data/Profile/Default/9.jpg and /dev/null differ diff --git a/Hanekawa/Data/Profile/Template/AchievementCircle.png b/Hanekawa/Data/Profile/Template/AchievementCircle.png deleted file mode 100644 index d44e0dae..00000000 Binary files a/Hanekawa/Data/Profile/Template/AchievementCircle.png and /dev/null differ diff --git a/Hanekawa/Data/Profile/Template/Circle.png b/Hanekawa/Data/Profile/Template/Circle.png deleted file mode 100644 index aa3cf46f..00000000 Binary files a/Hanekawa/Data/Profile/Template/Circle.png and /dev/null differ diff --git a/Hanekawa/Data/Welcome/WelcomeTemplate.psd b/Hanekawa/Data/Welcome/WelcomeTemplate.psd deleted file mode 100644 index 02354b75..00000000 Binary files a/Hanekawa/Data/Welcome/WelcomeTemplate.psd and /dev/null differ diff --git a/Hanekawa/Dockerfile b/Hanekawa/Dockerfile deleted file mode 100644 index 61c89d6e..00000000 --- a/Hanekawa/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base -WORKDIR /app -EXPOSE 61038 - -ENV token="" -ENV connectionString="" - -FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build -WORKDIR /src -COPY ["nuget.config", ""] -COPY ["Hanekawa/Hanekawa.csproj", "Hanekawa/"] -COPY ["Hanekawa.Database/Hanekawa.Database.csproj", "Hanekawa.Database/"] -COPY ["Hanekawa.Shared/Hanekawa.Shared.csproj", "Hanekawa.Shared/"] -COPY ["Hanekawa.HungerGames/Hanekawa.HungerGames.csproj", "Hanekawa.HungerGames/"] -RUN dotnet restore "Hanekawa/Hanekawa.csproj" -COPY . . -WORKDIR "/src/Hanekawa" -RUN dotnet build "Hanekawa.csproj" -c Release -o /app/build - -FROM build AS publish -RUN dotnet publish "Hanekawa.csproj" -c Release -o /app/publish - -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . -ENTRYPOINT ["dotnet", "Hanekawa.dll"] \ No newline at end of file diff --git a/Hanekawa/Entities/AffixType.cs b/Hanekawa/Entities/AffixType.cs new file mode 100644 index 00000000..6667b617 --- /dev/null +++ b/Hanekawa/Entities/AffixType.cs @@ -0,0 +1,7 @@ +namespace Hanekawa.Entities; + +public enum AffixType +{ + Prefix = 1, + Suffix = 2 +} \ No newline at end of file diff --git a/Hanekawa/Entities/Club/Club.cs b/Hanekawa/Entities/Club/Club.cs new file mode 100644 index 00000000..454d870f --- /dev/null +++ b/Hanekawa/Entities/Club/Club.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using Hanekawa.Entities.Users; + +namespace Hanekawa.Entities.Club; + +public class Club +{ + public ulong GuildId { get; set; } + public string Name { get; set; } = null!; + public string Description { get; set; } = null!; + public ulong OwnerId { get; set; } + public DateTimeOffset CreatedAt { get; set; } + + // Navigation properties + public virtual ICollection Members { get; set; } = new List(); +} \ No newline at end of file diff --git a/Hanekawa/Entities/Club/ClubMember.cs b/Hanekawa/Entities/Club/ClubMember.cs new file mode 100644 index 00000000..f3cce918 --- /dev/null +++ b/Hanekawa/Entities/Club/ClubMember.cs @@ -0,0 +1,16 @@ +using System; +using Hanekawa.Entities.Users; + +namespace Hanekawa.Entities.Club; + +public class ClubMember +{ + public ulong GuildId { get; set; } + public string ClubName { get; set; } = null!; + public ulong UserId { get; set; } + public DateTimeOffset JoinedAt { get; set; } + + // Navigation properties + public virtual Club Club { get; set; } = null!; + public virtual GuildUser User { get; set; } = null!; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/AdminConfig.cs b/Hanekawa/Entities/Configs/AdminConfig.cs new file mode 100644 index 00000000..550a2d29 --- /dev/null +++ b/Hanekawa/Entities/Configs/AdminConfig.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class AdminConfig : IConfig +{ + [Key] + public ulong GuildId { get; init; } + public int MaxWarnings { get; set; } + + [JsonIgnore] + public GuildConfig? GuildConfig { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/BoostConfig.cs b/Hanekawa/Entities/Configs/BoostConfig.cs new file mode 100644 index 00000000..0c98ec47 --- /dev/null +++ b/Hanekawa/Entities/Configs/BoostConfig.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class BoostConfig : IConfig +{ + [Key] + public ulong GuildId { get; init; } + public int Experience { get; set; } + public int Currency { get; set; } + public decimal ExperienceMultiplier { get; set; } + public decimal CurrencyMultiplier { get; set; } + + public bool ReoccurringRewards { get; set; } + + public bool Enabled { get; set; } + public DateTimeOffset Created { get; set; } = DateTimeOffset.UtcNow; + public DateTimeOffset Updated { get; set; } = DateTimeOffset.UtcNow; + + [JsonIgnore] + public GuildConfig? GuildConfig { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/CurrencyConfig.cs b/Hanekawa/Entities/Configs/CurrencyConfig.cs new file mode 100644 index 00000000..76740188 --- /dev/null +++ b/Hanekawa/Entities/Configs/CurrencyConfig.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class CurrencyConfig : IConfig +{ + [Key] + public ulong GuildId { get; init; } + public string CurrencyName { get; set; } = "Hanekawa Coins"; + public string CurrencySymbol { get; set; } = "$"; + public AffixType SymbolAffix { get; set; } = AffixType.Prefix; + public bool IsEmote { get; set; } = false; + + [JsonIgnore] + public GuildConfig? GuildConfig { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/DropConfig.cs b/Hanekawa/Entities/Configs/DropConfig.cs new file mode 100644 index 00000000..fe685c21 --- /dev/null +++ b/Hanekawa/Entities/Configs/DropConfig.cs @@ -0,0 +1,28 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class DropConfig : IConfig +{ + /// + [Key] + public ulong GuildId { get; init; } + /// + /// Emote used in string format. Either UTF or discord format + /// + public string Emote { get; set; } = string.Empty; + /// + /// Experience reward to user claiming. Default = 100 + /// + public int ExpReward { get; set; } = 100; + /// + /// List of blacklisted channels or categories + /// + public ulong[] Blacklist { get; set; } = []; + + [JsonIgnore] + public GuildConfig GuildConfig { get; set; } = null!; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/GreetConfig.cs b/Hanekawa/Entities/Configs/GreetConfig.cs new file mode 100644 index 00000000..a2622851 --- /dev/null +++ b/Hanekawa/Entities/Configs/GreetConfig.cs @@ -0,0 +1,26 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class GreetConfig : IConfig +{ + public GreetConfig() { } + + public GreetConfig(ulong guildId) => GuildId = guildId; + + [Key] + public ulong GuildId { get; init; } + public string Message { get; set; } = string.Empty; + public ulong? Channel { get; set; } + + public bool ImageEnabled { get; set; } = false; + + public bool DmEnabled { get; set; } = false; + public string DmMessage { get; set; } = string.Empty; + + [JsonIgnore] + public GuildConfig? GuildConfig { get; set; } + public List Images { get; set; } = []; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/GreetImage.cs b/Hanekawa/Entities/Configs/GreetImage.cs new file mode 100644 index 00000000..c272a2d9 --- /dev/null +++ b/Hanekawa/Entities/Configs/GreetImage.cs @@ -0,0 +1,28 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class GreetImage : IConfig +{ + [Key] + public int Id { get; set; } + public ulong GuildId { get; set; } + public string ImageUrl { get; set; } = null!; + public ulong Uploader { get; set; } + + public int AvatarSize { get; set; } = 128; + public int AvatarX { get; set; } = 0; + public int AvatarY { get; set; } = 0; + + public float UsernameSize { get; set; } = 32; + public int UsernameX { get; set; } = 0; + public int UsernameY { get; set; } = 0; + + public DateTimeOffset CreatedAt { get; set; } + + [JsonIgnore] + public GreetConfig? GreetConfig { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/GuildConfig.cs b/Hanekawa/Entities/Configs/GuildConfig.cs new file mode 100644 index 00000000..6c2e9b80 --- /dev/null +++ b/Hanekawa/Entities/Configs/GuildConfig.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.DataAnnotations; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class GuildConfig : IConfig +{ + [Key] + public ulong GuildId { get; init; } + public string Prefix { get; set; } = "h."; + public string Language { get; set; } = "en-US"; + + public DateTimeOffset? MarkedForDeletion { get; set; } = null; + + public DateTimeOffset Created { get; set; } = DateTimeOffset.UtcNow; + + public GreetConfig? GreetConfig { get; set; } = new(); + public LevelConfig? LevelConfig { get; set; } = new(); + public LogConfig? LogConfig { get; set; } = new(); + public AdminConfig? AdminConfig { get; set; } = new(); + public DropConfig? DropConfig { get; set; } = new(); + public CurrencyConfig? CurrencyConfig { get; set; } = new(); + public BoostConfig? BoostConfig { get; set; } = new(); +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/LevelConfig.cs b/Hanekawa/Entities/Configs/LevelConfig.cs new file mode 100644 index 00000000..c4cb771b --- /dev/null +++ b/Hanekawa/Entities/Configs/LevelConfig.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Entities.Levels; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class LevelConfig : IConfig +{ + [Key] + public ulong GuildId { get; init; } + public bool LevelEnabled { get; set; } = false; + public bool DecayEnabled { get; set; } = false; + + public int Multiplier { get; set; } = 1; + public DateTimeOffset MultiplierEnd { get; set; } = DateTimeOffset.MinValue; + + + [JsonIgnore] + public GuildConfig? GuildConfig { get; set; } + public List Rewards { get; set; } = []; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Configs/LogConfig.cs b/Hanekawa/Entities/Configs/LogConfig.cs new file mode 100644 index 00000000..094b6cb1 --- /dev/null +++ b/Hanekawa/Entities/Configs/LogConfig.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Configs; + +public class LogConfig : IConfig +{ + [Key] + public ulong GuildId { get; init; } + public ulong? JoinLeaveLogChannelId { get; set; } + public ulong? MessageLogChannelId { get; set; } + public ulong? ModLogChannelId { get; set; } + public ulong? VoiceLogChannelId { get; set; } + + [JsonIgnore] + public GuildConfig GuildConfig { get; set; } = null!; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/Attachment.cs b/Hanekawa/Entities/Discord/Attachment.cs new file mode 100644 index 00000000..b6eaf1a9 --- /dev/null +++ b/Hanekawa/Entities/Discord/Attachment.cs @@ -0,0 +1,7 @@ +namespace Hanekawa.Entities.Discord; + +public class Attachment +{ + public MemoryStream? Stream { get; set; } + public string FileName { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/DiscordMember.cs b/Hanekawa/Entities/Discord/DiscordMember.cs new file mode 100644 index 00000000..360f105f --- /dev/null +++ b/Hanekawa/Entities/Discord/DiscordMember.cs @@ -0,0 +1,19 @@ +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Discord; + +public class DiscordMember : IMemberEntity +{ + public ulong Id { get; set; } + public ulong GuildId { get; set; } + public Guild Guild { get; set; } = null!; + public ulong[] RoleIds { get; set; } = []; + public string? Nickname { get; set; } = string.Empty; + public string Username { get; set; } = string.Empty; + public string Mention => $"<@{Username}>"; + public string DisplayName => Nickname ?? Username; + public string AvatarUrl { get; set; } = string.Empty; + public bool IsBot { get; set; } + + public string? VoiceSessionId { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/Embed.cs b/Hanekawa/Entities/Discord/Embed.cs new file mode 100644 index 00000000..d8bf5800 --- /dev/null +++ b/Hanekawa/Entities/Discord/Embed.cs @@ -0,0 +1,50 @@ +namespace Hanekawa.Entities.Discord; + +/// +/// Discord embed +/// +public class Embed +{ + /// + /// Header tuple, First value = Avatar Url, Second value = Content value, Third value = Uri + /// + public EmbedHeader? Header { get; set; } = null; + + /// + /// Title of embed + /// + public string? Title { get; set; } = null; + + /// + /// Major content of embed + /// + public string? Content { get; set; } = null; + /// + /// Color of embed + /// + public int Color { get; set; } = 0; + /// + /// Timestamp put with the footer if provided + /// + public DateTimeOffset Timestamp { get; set; } = DateTimeOffset.UtcNow; + + /// + /// Fields of tuple. First value = title, second value = content + /// + public List Fields { get; set; } = []; + + /// + /// Icon of the embed + /// + public string? Icon { get; set; } = null; + + /// + /// Attachment of the embed + /// + public string? Attachment { get; set; } = null; + + /// + /// Footer tuple.First value = Avatar url. Second value = text + /// + public EmbedFooter? Footer { get; set; } = null; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/EmbedField.cs b/Hanekawa/Entities/Discord/EmbedField.cs new file mode 100644 index 00000000..5c739970 --- /dev/null +++ b/Hanekawa/Entities/Discord/EmbedField.cs @@ -0,0 +1,3 @@ +namespace Hanekawa.Entities.Discord; + +public record EmbedField(string Name, string Value, bool IsInline); \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/EmbedFooter.cs b/Hanekawa/Entities/Discord/EmbedFooter.cs new file mode 100644 index 00000000..ffe5bd17 --- /dev/null +++ b/Hanekawa/Entities/Discord/EmbedFooter.cs @@ -0,0 +1,3 @@ +namespace Hanekawa.Entities.Discord; + +public record EmbedFooter(string IconUrl, string Text); \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/EmbedHeader.cs b/Hanekawa/Entities/Discord/EmbedHeader.cs new file mode 100644 index 00000000..e239159a --- /dev/null +++ b/Hanekawa/Entities/Discord/EmbedHeader.cs @@ -0,0 +1,3 @@ +namespace Hanekawa.Entities.Discord; + +public record EmbedHeader(string Name, string IconUrl, string Url); \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/Emote.cs b/Hanekawa/Entities/Discord/Emote.cs new file mode 100644 index 00000000..434684fa --- /dev/null +++ b/Hanekawa/Entities/Discord/Emote.cs @@ -0,0 +1,11 @@ +namespace Hanekawa.Entities.Discord; + +public class Emote +{ + public required ulong Id { get; set; } + public required string Name { get; set; } = null!; + public required string Format { get; set; } = null!; + public required bool IsAvailable { get; set; } = false; + public required bool IsAnimated { get; set; } = false; + public required bool IsManaged { get; set; } = true; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/Guild.cs b/Hanekawa/Entities/Discord/Guild.cs new file mode 100644 index 00000000..15d798b2 --- /dev/null +++ b/Hanekawa/Entities/Discord/Guild.cs @@ -0,0 +1,11 @@ +namespace Hanekawa.Entities.Discord; + +public class Guild : SimpleGuild +{ + public string? Description { get; set; } + public int MemberCount { get; set; } + public int EmoteCount { get; set; } + public int? BoostCount { get; set; } + public int BoostTier { get; set; } + public Emote[] Emotes = []; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/RestMessage.cs b/Hanekawa/Entities/Discord/RestMessage.cs new file mode 100644 index 00000000..befd2755 --- /dev/null +++ b/Hanekawa/Entities/Discord/RestMessage.cs @@ -0,0 +1,21 @@ +using System; + +namespace Hanekawa.Entities.Discord; + +public class RestMessage +{ + public ulong Id { get; set; } + public ulong ChannelId { get; set; } + + public string? Content { get; set; } = null; + public Embed? Embed { get; set; } = null; + public string? Attachment { get; set; } = null; + public DateTimeOffset CreatedAt { get; set; } + public DateTimeOffset? ModifiedAt { get; set; } = null; + + public ulong AuthorId { get; set; } + public bool IsBot { get; set; } = false; + + public ulong? GuildId { get; set; } = null; + public ulong? CategoryId { get; set; } = null; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/SimpleGuild.cs b/Hanekawa/Entities/Discord/SimpleGuild.cs new file mode 100644 index 00000000..005c6634 --- /dev/null +++ b/Hanekawa/Entities/Discord/SimpleGuild.cs @@ -0,0 +1,10 @@ +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Discord; + +public class SimpleGuild : IGuildEntity +{ + public ulong GuildId { get; set; } + public string Name { get; set; } = null!; + public string IconUrl { get; set; } = null!; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Discord/TextChannel.cs b/Hanekawa/Entities/Discord/TextChannel.cs new file mode 100644 index 00000000..54383368 --- /dev/null +++ b/Hanekawa/Entities/Discord/TextChannel.cs @@ -0,0 +1,13 @@ +namespace Hanekawa.Entities.Discord; + +public class TextChannel +{ + public TextChannel() => Mention = $"<#{Id}>"; + + public ulong Id { get; init; } + public ulong? Category { get; init; } = null; + public string Name { get; init; } = null!; + public string Mention { get; init; } + public ulong? GuildId { get; init; } = null; + public bool IsNsfw { get; init; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/GuildModerationLog.cs b/Hanekawa/Entities/GuildModerationLog.cs new file mode 100644 index 00000000..db9782da --- /dev/null +++ b/Hanekawa/Entities/GuildModerationLog.cs @@ -0,0 +1,38 @@ +using System; + +namespace Hanekawa.Entities; + +/// +/// Log for ban / mute / kick / etc +/// +public class GuildModerationLog +{ + /// + /// Incremental ID tied to the guild + /// + public int Id { get; set; } + /// + /// Guild ID + /// + public ulong GuildId { get; set; } + /// + /// ID of user affected + /// + public ulong UserId { get; set; } + /// + /// Log message ID + /// + public ulong MessageId { get; set; } + /// + /// ID of moderator executing the action. Will not be a bot ID, 0 = Auto moderator + /// + public ulong? ModeratorId { get; set; } + /// + /// Reason for action + /// + public string Reason { get; set; } = "No reason provided"; + /// + /// Date of action + /// + public DateTimeOffset CreatedAt { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Internals/Log.cs b/Hanekawa/Entities/Internals/Log.cs new file mode 100644 index 00000000..cc5b90eb --- /dev/null +++ b/Hanekawa/Entities/Internals/Log.cs @@ -0,0 +1,12 @@ +namespace Hanekawa.Entities.Internals; + +public class Log +{ + public int Id { get; set; } + public string TimeStamp { get; set; } = string.Empty; + public string Level { get; set; } = string.Empty; + public string Message { get; set; } = string.Empty; + public string Logger { get; set; } = string.Empty; + public string CallSite { get; set; } = string.Empty; + public string Exception { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Levels/LevelRequirement.cs b/Hanekawa/Entities/Levels/LevelRequirement.cs new file mode 100644 index 00000000..b5d16655 --- /dev/null +++ b/Hanekawa/Entities/Levels/LevelRequirement.cs @@ -0,0 +1,13 @@ +namespace Hanekawa.Entities.Levels; + +public class LevelRequirement +{ + /// + /// Level + /// + public int Level { get; set; } + /// + /// Requirement to hit this level + /// + public int Experience { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Levels/LevelReward.cs b/Hanekawa/Entities/Levels/LevelReward.cs new file mode 100644 index 00000000..117aad7f --- /dev/null +++ b/Hanekawa/Entities/Levels/LevelReward.cs @@ -0,0 +1,19 @@ +using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; +using Hanekawa.Entities.Configs; + +namespace Hanekawa.Entities.Levels; + +public class LevelReward +{ + [Key] + public int Level { get; set; } + + public ulong? RoleId { get; set; } = null; + public int? Money { get; set; } = null; + + public ulong GuildId { get; set; } + + [JsonIgnore] + public LevelConfig? LevelConfig { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Message.cs b/Hanekawa/Entities/Message.cs new file mode 100644 index 00000000..0e8c84ea --- /dev/null +++ b/Hanekawa/Entities/Message.cs @@ -0,0 +1,33 @@ +using Hanekawa.Entities.Discord; + +namespace Hanekawa.Entities; + +public class Message +{ + public Message() + { + } + public Message(string content) + { + Content = content; + } + + public Message(string content, bool allowMentions = false, bool ephemeral = true) + { + Content = content; + AllowMentions = allowMentions; + Emphemeral = ephemeral; + } + + public Message(Embed embed, bool allowMentions = false, bool ephemeral = true) + { + Embed = embed; + AllowMentions = allowMentions; + Emphemeral = ephemeral; + } + + public string Content { get; set; } = null!; + public Embed Embed { get; set; } = null!; + public bool AllowMentions { get; set; } = false; + public bool Emphemeral { get; set; } = true; +} \ No newline at end of file diff --git a/Hanekawa/Entities/MeterName.cs b/Hanekawa/Entities/MeterName.cs new file mode 100644 index 00000000..e67650b4 --- /dev/null +++ b/Hanekawa/Entities/MeterName.cs @@ -0,0 +1,7 @@ +namespace Hanekawa.Entities; + +public class MeterName +{ + public const string DiscordCommands = "Hanekawa.Discord.Commands"; + public const string DiscordServices = "Hanekawa.Discord.Services"; +} \ No newline at end of file diff --git a/Hanekawa/Entities/Pagination.cs b/Hanekawa/Entities/Pagination.cs new file mode 100644 index 00000000..9d7f0445 --- /dev/null +++ b/Hanekawa/Entities/Pagination.cs @@ -0,0 +1,7 @@ +namespace Hanekawa.Entities; + +public class Pagination(T[] items) +{ + public T[] Items { get; set; } = items; + public int Size { get; set; } = items.Length; +} \ No newline at end of file diff --git a/Hanekawa/Entities/ProviderSource.cs b/Hanekawa/Entities/ProviderSource.cs new file mode 100644 index 00000000..c4482c1b --- /dev/null +++ b/Hanekawa/Entities/ProviderSource.cs @@ -0,0 +1,6 @@ +namespace Hanekawa.Entities; + +public enum ProviderSource +{ + Discord = 0, +} \ No newline at end of file diff --git a/Hanekawa/Entities/Response.cs b/Hanekawa/Entities/Response.cs new file mode 100644 index 00000000..f79456e7 --- /dev/null +++ b/Hanekawa/Entities/Response.cs @@ -0,0 +1,20 @@ +namespace Hanekawa.Entities; + +public class Response where T : notnull +{ + public Response(T value) + { + Value = value; + IsSuccess = true; + } + + public Response(T value, bool isSuccess) + { + IsSuccess = isSuccess; + Value = value; + } + + public T Value { get; set; } + + public bool IsSuccess { get; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Settings/Images/ImageSettings.cs b/Hanekawa/Entities/Settings/Images/ImageSettings.cs new file mode 100644 index 00000000..7ec30d1e --- /dev/null +++ b/Hanekawa/Entities/Settings/Images/ImageSettings.cs @@ -0,0 +1,97 @@ +using System.Text.Json.Serialization; + +namespace Hanekawa.Entities.Settings.Images; + +public class ImageSettings +{ + [JsonPropertyName("Profile")] + public ProfileSettings Profile { get; set; } = new(); + public RankSettings Rank { get; set; } = new(); +} + +public class RankSettings : ImageSize +{ + [JsonPropertyName("Avatar")] + public AvatarSettings Avatar { get; set; } = new(); + + [JsonPropertyName("Font")] + public string Font { get; set; } = string.Empty; + + [JsonPropertyName("Texts")] + public TextSettings[] Texts { get; set; } = []; +} + +public class ProfileSettings : ImageSize +{ + [JsonPropertyName("Avatar")] + public AvatarSettings Avatar { get; set; } = new(); + + [JsonPropertyName("Font")] + public string Font { get; set; } = string.Empty; + + [JsonPropertyName("Texts")] + public TextSettings[] Texts { get; set; } = []; +} + +public class AvatarSettings : ImagePosition +{ + [JsonPropertyName("Size")] + public int Size { get; set; } = 0; +} + +public class TextSettings +{ + [JsonPropertyName("TextType")] + public string TextType { get; set; } = string.Empty; + + [JsonPropertyName("Text")] + public string Text { get; set; } = string.Empty; + + [JsonPropertyName("TextPosition")] + public ImagePosition TextPosition { get; set; } = new(); + + [JsonPropertyName("Headline")] + public bool Headline { get; set; } = false; + + [JsonPropertyName("SourceType")] + public string SourceType { get; set; } = string.Empty; + + [JsonPropertyName("SourceField")] + public string SourceField { get; set; } = string.Empty; + + [JsonPropertyName("Position")] + public ImagePosition[] Position { get; set; } = []; + + [JsonPropertyName("Size")] + public int Size { get; set; } = 0; +} + +public abstract class ImageSize +{ + /// + /// Gets or sets the width of the image. + /// + [JsonPropertyName("Width")] + public int Width { get; set; } + + /// + /// Gets or sets the height of the image. + /// + [JsonPropertyName("Height")] + public int Height { get; set; } +} + +public class ImagePosition +{ + /// + /// Gets or sets the X coordinate of the image. + /// + [JsonPropertyName("X")] + public int X { get; set; } + + /// + /// Gets or sets the Y coordinate of the image. + /// + [JsonPropertyName("Y")] + public int Y { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Users/GuildUser.cs b/Hanekawa/Entities/Users/GuildUser.cs new file mode 100644 index 00000000..48a9a23d --- /dev/null +++ b/Hanekawa/Entities/Users/GuildUser.cs @@ -0,0 +1,38 @@ +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Users; + +public class GuildUser : IMemberEntity, ICached +{ + public GuildUser() + { + User = new User(); + } + + public GuildUser(ulong guildId, ulong userId) + { + GuildId = guildId; + Id = userId; + User = new User { Id = userId }; + } + + public ulong GuildId { get; set; } + public ulong Id { get; set; } + + public bool Inactive { get; set; } = false; + + public int Level { get; set; } = 1; + public long Experience { get; set; } = 0; + public long NextLevelExperience { get; set; } = 100; + public long CurrentLevelExperience { get; set; } = 0; + + public long Currency { get; set; } = 0; + + public DateTimeOffset DailyClaimed { get; set; } = DateTimeOffset.MinValue; + public int DailyStreak { get; set; } = 0; + + public TimeSpan TotalVoiceTime { get; set; } = TimeSpan.Zero; + public DateTimeOffset LastSeen { get; set; } = DateTimeOffset.MinValue; + + public User User { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Entities/Users/User.cs b/Hanekawa/Entities/Users/User.cs new file mode 100644 index 00000000..496fbb78 --- /dev/null +++ b/Hanekawa/Entities/Users/User.cs @@ -0,0 +1,54 @@ +using System.ComponentModel.DataAnnotations; +using Hanekawa.Interfaces; + +namespace Hanekawa.Entities.Users; + +public class User : IEntity +{ + public ulong Id { get; set; } + public DateTimeOffset? PremiumExpiration { get; set; } + public List GuildUsers { get; set; } = []; + public List Inventory { get; set; } = []; +} + +public class Equipment : IEntity +{ + public ulong Id { get; set; } + + public Guid BackgroundId { get; set; } + public Inventory Background { get; set; } = null!; +} + +public class Inventory +{ + public ulong UserId { get; set; } + public User User { get; set; } = null!; + public Guid ItemId { get; set; } + public Item Item { get; set; } = null!; + public int Amount { get; set; } +} + +public static class InventoryExtensions +{ + public static ICollection ToList(this ICollection inventory) + { + return new List(inventory); + } +} + +public class Item +{ + public Guid Id { get; set; } + public string Name { get; set; } = null!; + public string Description { get; set; } = null!; + public Guid TypeId { get; set; } + public ItemType Type { get; set; } = null!; + public int? Price { get; set; } +} + +public class ItemType +{ + public Guid Id { get; set; } + public string Name { get; set; } = null!; + public ICollection Items { get; set; } = new List(); +} \ No newline at end of file diff --git a/Hanekawa/Entities/Users/Warning.cs b/Hanekawa/Entities/Users/Warning.cs new file mode 100644 index 00000000..1c6c08a0 --- /dev/null +++ b/Hanekawa/Entities/Users/Warning.cs @@ -0,0 +1,20 @@ +using System; + +namespace Hanekawa.Entities.Users; + +public class Warning +{ + public Guid Id { get; set; } + public ulong GuildId { get; set; } + public ulong UserId { get; set; } + public ulong ModeratorId { get; set; } + public string Reason { get; set; } = "No reason provided."; + public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow; + public bool Valid { get; set; } = true; + + public override string ToString() + { + return + $" Id: {Id}, GuildId: {GuildId}, UserId: {UserId}, ModeratorId: {ModeratorId}, Reason: {Reason}, CreatedAt: {CreatedAt}, Valid: {Valid}"; + } +} \ No newline at end of file diff --git a/Hanekawa/Exceptions/HanaCommandException.cs b/Hanekawa/Exceptions/HanaCommandException.cs index f73278b9..29f05856 100644 --- a/Hanekawa/Exceptions/HanaCommandException.cs +++ b/Hanekawa/Exceptions/HanaCommandException.cs @@ -1,12 +1,11 @@ using System; -namespace Hanekawa.Exceptions +namespace Hanekawa.Exceptions; + +public class HanaCommandException : Exception { - public class HanaCommandException : Exception - { - public string CommandErrorMessage { get; set; } - public HanaCommandException(string message) => CommandErrorMessage = message; + public string CommandErrorMessage { get; set; } + public HanaCommandException(string message) => CommandErrorMessage = message; - public override string ToString() => $"Hana Command Exception: {Message}"; - } + public override string ToString() => $"Hana Command Exception: {Message}"; } \ No newline at end of file diff --git a/Hanekawa/Extensions/ArrayExtensions.cs b/Hanekawa/Extensions/ArrayExtensions.cs new file mode 100644 index 00000000..193bf7d0 --- /dev/null +++ b/Hanekawa/Extensions/ArrayExtensions.cs @@ -0,0 +1,21 @@ +using System.Runtime.InteropServices; + +namespace Hanekawa.Extensions; + +public static class ArrayExtensions +{ + public static void Remove(this T[] collection, T entity) + { + var tempList = new List(collection); + tempList.Remove(entity); + var span = CollectionsMarshal.AsSpan(tempList); + collection = span.ToArray(); + } + + public static void Add(this T[] collection, T entity) + { + var tempList = new List(collection) { entity }; + var span = CollectionsMarshal.AsSpan(tempList); + collection = span.ToArray(); + } +} \ No newline at end of file diff --git a/Hanekawa/Extensions/ChannelExtensions.cs b/Hanekawa/Extensions/ChannelExtensions.cs deleted file mode 100644 index 2e74fd8a..00000000 --- a/Hanekawa/Extensions/ChannelExtensions.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Threading.Tasks; -using Disqord; - -namespace Hanekawa.Extensions -{ - public static class ChannelExtensions - { - public static async Task TryApplyPermissionOverwriteAsync(this CachedTextChannel channel, LocalOverwrite perms) - { - if (!channel.Guild.CurrentMember.Permissions.ManageChannels) return false; - await channel.AddOrModifyOverwriteAsync(perms); - return true; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/Embed/EmbedExtension.cs b/Hanekawa/Extensions/Embed/EmbedExtension.cs deleted file mode 100644 index 252f8e9b..00000000 --- a/Hanekawa/Extensions/Embed/EmbedExtension.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Threading.Tasks; -using Disqord; -using Disqord.Rest; -using Quartz.Util; - -#nullable enable warnings -namespace Hanekawa.Extensions.Embed -{ - public static class EmbedExtension - { - // Reply from channel - public static Task ReplyAsync(this IMessageChannel channel, string content, Color colour) => - channel.SendEmbedAsync(new LocalEmbedBuilder().Create(content, colour)); - - public static Task ReplyAsync(this IMessageChannel channel, LocalEmbedBuilder embed) => - channel.SendEmbedAsync(embed); - - // Creates default embed - used here - public static LocalEmbedBuilder Create(this LocalEmbedBuilder embed, string content, Color colour) - { - embed.Color = colour; - embed.Description = content; - return embed; - } - - public static LocalEmbedBuilder ToEmbedBuilder(this LocalEmbed embed) - { - var newEmbed = new LocalEmbedBuilder - { - Description = embed.Description, - Color = embed.Color, - Title = embed.Title, - Timestamp = embed.Timestamp, - Url = embed.Url - }; - - if (embed.Author.Name != null) - newEmbed.Author = new LocalEmbedAuthorBuilder - {IconUrl = embed.Author.IconUrl, Name = embed.Author.Name, Url = embed.Author.Url}; - if (embed.Footer.Text != null) - newEmbed.Footer = new LocalEmbedFooterBuilder - {IconUrl = embed.Footer.IconUrl, Text = embed.Footer.IconUrl}; - - if (embed.ImageUrl != null) newEmbed.ImageUrl = embed.ImageUrl; - if (embed.ThumbnailUrl != null) newEmbed.ThumbnailUrl = embed.ThumbnailUrl; - foreach (var x in embed.Fields) newEmbed.AddField(x.Name, x.Value, x.IsInline); - - return newEmbed; - } - - public static LocalEmbedBuilder ToEmbedBuilder(this Disqord.Embed embed) - { - var newEmbed = new LocalEmbedBuilder - { - Description = embed.Description, - Color = embed.Color, - Title = embed.Title, - Timestamp = embed.Timestamp, - Url = embed.Url - }; - - if (!embed.Author.Name.IsNullOrWhiteSpace()) - newEmbed.Author = new LocalEmbedAuthorBuilder - { IconUrl = embed.Author.IconUrl, Name = embed.Author.Name, Url = embed.Author.Url }; - if (!embed.Footer.Text.IsNullOrWhiteSpace()) - newEmbed.Footer = new LocalEmbedFooterBuilder - { IconUrl = embed.Footer.IconUrl, Text = embed.Footer.Text }; - try - { - if (embed.Image.Url != null) newEmbed.ImageUrl = embed.Image.Url; - if (embed.Thumbnail.Url != null) newEmbed.ThumbnailUrl = embed.Thumbnail.Url; - } - catch (Exception e) - { - Console.WriteLine(e); - } - foreach (var x in embed.Fields) newEmbed.AddField(x.Name, x.Value, x.IsInline); - - return newEmbed; - } - - private static Task SendEmbedAsync(this IMessageChannel channel, LocalEmbedBuilder embed) => - channel.SendMessageAsync(null, false, embed.Build()); - - private static Task SendEmbedAsync(this IMessageChannel channel, LocalEmbedBuilder embed, - string content) => - channel.SendMessageAsync(content, false, embed.Build()); - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/ImageExtension.cs b/Hanekawa/Extensions/ImageExtension.cs deleted file mode 100644 index 592259e3..00000000 --- a/Hanekawa/Extensions/ImageExtension.cs +++ /dev/null @@ -1,52 +0,0 @@ -using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Drawing; -using SixLabors.ImageSharp.Drawing.Processing; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Processing; - -namespace Hanekawa.Extensions -{ - public static class ImageExtension - { - public static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext processingContext, Size size, float cornerRadius) => - processingContext.Resize(new ResizeOptions - { - Size = size, - Mode = ResizeMode.Crop - }).ApplyRoundedCorners(cornerRadius); - - private 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, - AlphaCompositionMode = PixelAlphaCompositionMode.DestOut - }); - - foreach (var c in corners) - { - ctx = ctx.Fill(Color.Red, c); - } - return ctx; - } - - private static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius) - { - var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius); - - var cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius)); - - var rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1; - var bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1; - - 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); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/MessageExtension.cs b/Hanekawa/Extensions/MessageExtension.cs deleted file mode 100644 index 0342b755..00000000 --- a/Hanekawa/Extensions/MessageExtension.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Disqord; -using Disqord.Rest; - -namespace Hanekawa.Extensions -{ - public static class MessageExtension - { - public static async Task> FilterMessagesAsync(this ICachedMessageChannel channel, int amount = 100, - CachedMember filterBy = null) - { - var messages = await channel.GetMessagesAsync(amount); - return messages.ToList().FilterMessages(filterBy); - } - - public static List FilterMessages(this List msgs, CachedMember filterBy = null) - { - var result = new List(); - for (var i = 0; i < msgs.Count; i++) - { - var x = msgs[i]; - // Checks if message can be deleted - // Messages that's older then 14 days or 2 weeks can't be bulk deleted - if (x.CreatedAt.AddDays(14) >= DateTimeOffset.UtcNow) - { - // If we're filtering, don't add if its not from the filtered user. - if (filterBy != null && x.Author.Id.RawValue != filterBy.Id.RawValue) continue; - result.Add(x.Id.RawValue); - } - } - - return result; - } - - public static async Task TryDeleteMessagesAsync(this ICachedMessageChannel channel, - IEnumerable messageIds) - { - if (!(channel is CachedTextChannel gChannel)) return true; - var currentUser = gChannel.Guild.CurrentMember; - if (!currentUser.Permissions.ManageMessages) return false; - await gChannel.DeleteMessagesAsync(messageIds); - return true; - } - - public static async Task TryDeleteMessageAsync(this ICachedMessageChannel channel, Snowflake messageId) - { - if (!(channel is CachedTextChannel gChannel)) return true; - var currentUser = gChannel.Guild.CurrentMember; - if (!currentUser.Permissions.ManageMessages) return false; - if (messageId.CreatedAt.AddDays(14) <= DateTimeOffset.UtcNow) return false; - await channel.DeleteMessageAsync(messageId); - return true; - } - - public static async Task TryDeleteMessagesAsync(this CachedMessage msg) - { - if (!(msg.Channel is CachedTextChannel chn)) return false; - if (!chn.Guild.CurrentMember.Permissions.ManageMessages) return false; - if (msg.CreatedAt.AddDays(14) <= DateTimeOffset.UtcNow) return false; - await msg.DeleteAsync(); - return true; - } - - public static async Task TryDeleteMessageAsync(this CachedMessage msg) - { - if (!(msg.Channel is CachedTextChannel chn)) return false; - if (!chn.Guild.CurrentMember.Permissions.ManageMessages) return false; - try - { - await msg.DeleteAsync(); - } - catch { /* Ignore ? */ } - return true; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/NumberExtension.cs b/Hanekawa/Extensions/NumberExtension.cs deleted file mode 100644 index 946bbf3b..00000000 --- a/Hanekawa/Extensions/NumberExtension.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; - -namespace Hanekawa.Extensions -{ - public static class NumberExtension - { - private static readonly string[] SizeSuffixes = - {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; - - public static string SizeSuffix(this long value, int decimalPlaces = 1) - { - if (decimalPlaces < 0) throw new ArgumentOutOfRangeException(nameof(decimalPlaces)); - if (value < 0) return "-" + SizeSuffix(-value); - if (value == 0) return string.Format("{0:n" + decimalPlaces + "} bytes", 0); - - var mag = (int) Math.Log(value, 1024); - - var adjustedSize = (decimal) value / (1L << (mag * 10)); - - if (Math.Round(adjustedSize, decimalPlaces) >= 1000) - { - mag += 1; - adjustedSize /= 1024; - } - - return string.Format("{0:n" + decimalPlaces + "} {1}", - adjustedSize, - SizeSuffixes[mag]); - } - - public static bool IsDivisible(this int x, int n) - => x != 0 && (n % x) == 0; - - public static string FormatNumber(this uint num) - => num >= 100000 ? FormatNumber(num / 1000) + "K" : - num >= 10000 ? (num / 1000D).ToString("0.#") + "K" : num.ToString("#,0"); - - public static string FormatNumber(this int num) - => num >= 100000 ? FormatNumber(num / 1000) + "K" : - num >= 10000 ? (num / 1000D).ToString("0.#") + "K" : num.ToString("#,0"); - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/NumberExtensions.cs b/Hanekawa/Extensions/NumberExtensions.cs new file mode 100644 index 00000000..316feae5 --- /dev/null +++ b/Hanekawa/Extensions/NumberExtensions.cs @@ -0,0 +1,13 @@ +namespace Hanekawa.Extensions; + +public static class NumberExtensions +{ + public static string Humanize(this int number) + => number switch + { + < 1000 => number.ToString("G"), + < 1000000 => $"{(number / 1000):G}K", + < 1000000000 => $"{number / 1000000:G}M", + _ => $"{number / 1000000000:G}B" + }; +} \ No newline at end of file diff --git a/Hanekawa/Extensions/PaginationBuilderExtension.cs b/Hanekawa/Extensions/PaginationBuilderExtension.cs new file mode 100644 index 00000000..7f3a22b7 --- /dev/null +++ b/Hanekawa/Extensions/PaginationBuilderExtension.cs @@ -0,0 +1,59 @@ +using System.Runtime.InteropServices; +using System.Text; +using Hanekawa.Entities; + +namespace Hanekawa.Extensions; + +public static class PaginationBuilderExtension +{ + public static Span BuildPage(this IList list) + { + var pages = new List(list.Count / 5 + 1); + for (var i = 0; i < list.Count;) + { + var sb = new StringBuilder(); + for (var j = 0; j < 5; j++) + { + if(i >= list.Count) break; + var x = list[i]; + if(x is null) continue; + sb.AppendLine(x.ToString()); + i++; + } + pages.Add(sb.ToString()); + } + + return CollectionsMarshal.AsSpan(pages); + } + + public static Span BuildPage(this ReadOnlySpan list) + { + var pages = new string[list.Length / 5 + 1]; + //var pages = new List(list.Length / 5 + 1); + for (var i = 0; i < list.Length;) + { + var sb = new StringBuilder(); + for (var j = 0; j < 5; j++) + { + if(i >= list.Length) break; + var x = list[i]; + if(x is null) continue; + sb.AppendLine(x.ToString()); + i++; + } + pages.Append(sb.ToString()); + } + return pages; + } + + public static T[] Paginate (this Span list) where T : Message, new() + { + var pages = new T[list.Length / 5 + 1]; + for (var i = 0; i < list.Length; i++) + { + var x = list[i]; + pages[i] = new T { Content = x }; + } + return pages; + } +} \ No newline at end of file diff --git a/Hanekawa/Extensions/QuartzExtension.cs b/Hanekawa/Extensions/QuartzExtension.cs deleted file mode 100644 index 987f561e..00000000 --- a/Hanekawa/Extensions/QuartzExtension.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Linq; -using Hanekawa.Utility; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; -using Quartz; -using Quartz.Impl; -using Quartz.Spi; - -namespace Hanekawa.Extensions -{ - public static class QuartzExtension - { - public static void UseQuartz(this IServiceCollection services, params Type[] jobs) - { - services.AddSingleton(); - services.Add(jobs.Select(jobType => new ServiceDescriptor(jobType, jobType, ServiceLifetime.Singleton))); - - services.AddSingleton(provider => - { - var schedulerFactory = new StdSchedulerFactory(); - var scheduler = schedulerFactory.GetScheduler().Result; - scheduler.JobFactory = provider.GetService(); - scheduler.Start(); - return scheduler; - }); - } - - public static void StartSimpleJob(IScheduler scheduler, TimeSpan runInterval) - where TJob : IJob - { - var jobName = typeof(TJob).FullName; - - var job = JobBuilder.Create() - .WithIdentity(jobName) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity($"{jobName}.trigger") - .StartAt(new DateTimeOffset(DateTime.Now.AddSeconds(10))) - .WithSimpleSchedule(scheduleBuilder => - scheduleBuilder - .WithInterval(runInterval) - .RepeatForever()) - .Build(); - - scheduler.ScheduleJob(job, trigger); - } - - public static void StartCronJob(IScheduler scheduler, string cron) - where TJob : IJob - { - var jobName = typeof(TJob).FullName; - - var job = JobBuilder.Create() - .WithIdentity(jobName) - .Build(); - - var trigger = TriggerBuilder.Create() - .WithIdentity($"{jobName}.trigger") - .WithSchedule(CronScheduleBuilder.CronSchedule(cron)) - .Build(); - - scheduler.ScheduleJob(job, trigger); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/RoleExtension.cs b/Hanekawa/Extensions/RoleExtension.cs deleted file mode 100644 index aafd8d24..00000000 --- a/Hanekawa/Extensions/RoleExtension.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Disqord; - -namespace Hanekawa.Extensions -{ - public static class RoleExtension - { - public static async Task TryAddRoleAsync(this CachedMember user, CachedRole role) - { - var currentUser = user.Guild.CurrentMember; - if (role == null) return false; - if (!currentUser.Permissions.ManageRoles || !currentUser.HierarchyCheck(role)) return false; - await user.GrantRoleAsync(role.Id.RawValue); - return true; - - } - - public static async Task TryAddRolesAsync(this CachedMember user, IEnumerable roles) - { - var currentUser = user.Guild.CurrentMember; - - if (!currentUser.Permissions.ManageRoles) return false; - foreach (var x in roles) - { - if (x == null) continue; - if (currentUser.HierarchyCheck(x)) - await user.GrantRoleAsync(x.Id.RawValue); - } - return true; - } - - public static async Task TryRemoveRoleAsync(this CachedMember user, CachedRole role) - { - var currentUser = user.Guild.CurrentMember; - if (role == null) return false; - if (!currentUser.Permissions.ManageRoles || !currentUser.HierarchyCheck(role)) return false; - await user.RevokeRoleAsync(role.Id.RawValue); - return true; - - } - - public static async Task TryRemoveRolesAsync(this CachedMember user, IEnumerable roles) - { - var currentUser = user.Guild.CurrentMember; - if (!currentUser.Permissions.ManageRoles) return false; - foreach (var x in roles) - { - if (x == null) continue; - if (currentUser.HierarchyCheck(x)) - await user.RevokeRoleAsync(x.Id.RawValue); - } - return true; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/RoslynExtensions.cs b/Hanekawa/Extensions/RoslynExtensions.cs deleted file mode 100644 index c990b38d..00000000 --- a/Hanekawa/Extensions/RoslynExtensions.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Disqord; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Scripting; - -namespace Hanekawa.Extensions -{ - public static class RoslynExtensions - { - private const char BackTick = '`'; - private const char NewLine = '\n'; - - public static ScriptOptions RoslynScriptOptions { get; } - - public static IReadOnlyDictionary ParameterExampleStrings { get; } = new Dictionary - { - [typeof(CachedMember)] = "<@111123736660324352>", - [typeof(IMessage)] = "827809315679240202", - [typeof(LocalCustomEmoji)] = "<:naicu:469925413162975242>", - [typeof(CachedTextChannel)] = "#general", - [typeof(CachedRole)] = "@Admins" - }; - - private static readonly string UsingBlock; - - static RoslynExtensions() - { - var rawUsings = new[] { - "Disqord.Bot", - "Microsoft.Extensions.DependencyInjection", - "System", - "System.Collections.Generic", - "System.Linq", - "System.Text", - "System.Threading.Tasks", - "Qmmands" - }; - UsingBlock = string.Concat(rawUsings.Select(str => $"using {str}; ")); - - var assemblies = AppDomain.CurrentDomain.GetAssemblies() - .Where(x => !x.IsDynamic && !string.IsNullOrWhiteSpace(x.Location)); - - var namespaces = Assembly.GetEntryAssembly()?.GetTypes() - .Where(x => !string.IsNullOrWhiteSpace(x.Namespace)).Select(x => x.Namespace).Distinct(); - - RoslynScriptOptions = ScriptOptions.Default - .WithReferences(assemblies.Select(assembly => MetadataReference.CreateFromFile(assembly.Location))) - .AddImports(namespaces); - } - - public static string GetCode(this string rawCode) - { - static string GetCode(string inCode) - { - if (inCode[0] != BackTick) - { - return inCode; - } - - if (inCode[1] != BackTick) - { - return inCode.Substring(1, inCode.Length - 2); - } - - var startIndex = inCode.IndexOf(NewLine); - if (startIndex == -1) - { - throw new ArgumentException("Format your code blocks properly >:["); - } - - return inCode.Substring(startIndex + 1, inCode.Length - startIndex - 5); - } - - var code = GetCode(rawCode); - return string.Concat(UsingBlock, code); - } - } -} diff --git a/Hanekawa/Extensions/StreamExtensions.cs b/Hanekawa/Extensions/StreamExtensions.cs deleted file mode 100644 index 92771c78..00000000 --- a/Hanekawa/Extensions/StreamExtensions.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Buffers; -using System.Collections.Generic; -using System.IO; -using Hanekawa.Exceptions; - -namespace Hanekawa.Extensions -{ - public static class StreamExtensions - { - public static MemoryStream ToEditable(this Stream stream, double? MBLimit = null) - { - var toReturn = new MemoryStream(); - if (MBLimit == null) - { - stream.CopyTo(toReturn); - toReturn.Flush(); - stream.Dispose(); - } - else - { - var bufferSize = Buffer(stream); - var buffer = ArrayPool.Shared.Rent(bufferSize); - int read; - while ((read = stream.Read(buffer, 0, buffer.Length)) != 0) - { - toReturn.Write(buffer, 0, read); - if (MBLimit != null && (toReturn.Length / 1024f) / 1024f > MBLimit) - throw new HanaCommandException($"File size is above the limit ({MBLimit} MB)"); - } - toReturn.Flush(); - stream.Dispose(); - } - return toReturn; - } - - private static int Buffer(Stream stream) - { - var bufferSize = 81920; - - if (stream.CanSeek) - { - var length = stream.Length; - var position = stream.Position; - if (length <= position) bufferSize = 1; - else - { - var remaining = length - position; - if (remaining > 0) bufferSize = (int)Math.Min(bufferSize, remaining); - } - } - - return bufferSize; - } - - private static readonly Dictionary KnownFileHeaders = new Dictionary - { - { FileType.Jpeg, new byte[]{ 0xFF, 0xD8 }}, // JPEG - { FileType.Gif, new byte[]{ 0x47, 0x49, 0x46 }}, // GIF - { FileType.Png, new byte[]{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }}, // PNG - }; - - public static FileType GetKnownFileType(this MemoryStream stream) - { - ReadOnlySpan data = stream.ToArray().AsSpan(); - foreach (var check in KnownFileHeaders) - { - if (data.Length >= check.Value.Length) - { - var slice = data.Slice(0, check.Value.Length); - if (slice.SequenceEqual(check.Value)) - { - return check.Key; - } - } - } - - return FileType.Unknown; - } - } - public enum FileType - { - Unknown, - Jpeg, - Bmp, - Gif, - Png, - Pdf - } -} diff --git a/Hanekawa/Extensions/StringExtension.cs b/Hanekawa/Extensions/StringExtension.cs deleted file mode 100644 index ab3d24eb..00000000 --- a/Hanekawa/Extensions/StringExtension.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; - -namespace Hanekawa.Extensions -{ - public static class StringExtension - { - private static readonly Regex FilterRegex = - new Regex(@"(?:discord(?:\.gg|.me|app\.com\/invite)\/(([\w]{16}|(?:[\w]+-?){3})))", - RegexOptions.Compiled | RegexOptions.IgnoreCase); - - public static string SanitizeEveryone(this string str) => - str.Replace("@everyone", "@everyοne").Replace("@here", "@һere"); - - public static bool IsPictureUrl(this string str) - { - var isGif = str.EndsWith(".gif"); - var isPng = str.EndsWith(".png"); - var isJpeg = str.EndsWith(".jpeg"); - var isJpg = str.EndsWith(".jpg"); - - if (isGif) return true; - if (isPng) return true; - if (isJpeg) return true; - if (isJpg) return true; - return false; - } - - public static bool IsDiscordInvite(this string str, out string invite) - { - if (FilterRegex.IsMatch(str)) - { - var invites = FilterRegex.GetGroupNames().FirstOrDefault(); - invite = invites; - return true; - } - - invite = null; - return false; - } - - public static string ListToString(this IEnumerable list) => string.Join("\n", list); - - public static bool FuzzyMatch(this string stringToSearch, string pattern, out int outScore) - { - // Score consts - const int adjacencyBonus = 5; // bonus for adjacent matches - const int separatorBonus = 10; // bonus if match occurs after a separator - const int camelBonus = 10; // bonus if match is uppercase and prev is lower - - const int - leadingLetterPenalty = -3; // penalty applied for every letter in stringToSearch before the first match - const int maxLeadingLetterPenalty = -9; // maximum penalty for leading letters - const int unmatchedLetterPenalty = -1; // penalty for every letter that doesn't matter - - - // Loop variables - var score = 0; - var patternIdx = 0; - var patternLength = pattern.Length; - var strIdx = 0; - var strLength = stringToSearch.Length; - var prevMatched = false; - var prevLower = false; - var prevSeparator = true; // true if first letter match gets separator bonus - - // Use "best" matched letter if multiple string letters match the pattern - char? bestLetter = null; - char? bestLower = null; - int? bestLetterIdx = null; - var bestLetterScore = 0; - - var matchedIndices = new List(); - - // Loop over strings - while (strIdx != strLength) - { - var patternChar = patternIdx != patternLength ? pattern[patternIdx] as char? : null; - var strChar = stringToSearch[strIdx]; - - var patternLower = patternChar != null ? char.ToLower((char) patternChar) as char? : null; - var strLower = char.ToLower(strChar); - var strUpper = char.ToUpper(strChar); - - var nextMatch = patternChar != null && patternLower == strLower; - var rematch = bestLetter != null && bestLower == strLower; - - var advanced = nextMatch && bestLetter != null; - var patternRepeat = bestLetter != null && patternChar != null && bestLower == patternLower; - if (advanced || patternRepeat) - { - score += bestLetterScore; - matchedIndices.Add((int) bestLetterIdx); - bestLetter = null; - bestLower = null; - bestLetterIdx = null; - bestLetterScore = 0; - } - - if (nextMatch || rematch) - { - var newScore = 0; - - // Apply penalty for each letter before the first pattern match - // Note: Math.Max because penalties are negative values. So max is smallest penalty. - if (patternIdx == 0) - { - var penalty = Math.Max(strIdx * leadingLetterPenalty, maxLeadingLetterPenalty); - score += penalty; - } - - // Apply bonus for consecutive bonuses - if (prevMatched) - newScore += adjacencyBonus; - - // Apply bonus for matches after a separator - if (prevSeparator) - newScore += separatorBonus; - - // Apply bonus across camel case boundaries. Includes "clever" isLetter check. - if (prevLower && strChar == strUpper && strLower != strUpper) - newScore += camelBonus; - - // Update pattern index IF the next pattern letter was matched - if (nextMatch) - ++patternIdx; - - // Update best letter in stringToSearch which may be for a "next" letter or a "rematch" - if (newScore >= bestLetterScore) - { - // Apply penalty for now skipped letter - if (bestLetter != null) - score += unmatchedLetterPenalty; - - bestLetter = strChar; - bestLower = char.ToLower((char) bestLetter); - bestLetterIdx = strIdx; - bestLetterScore = newScore; - } - - prevMatched = true; - } - else - { - score += unmatchedLetterPenalty; - prevMatched = false; - } - - // Includes "clever" isLetter check. - prevLower = strChar == strLower && strLower != strUpper; - prevSeparator = strChar == '_' || strChar == ' '; - - ++strIdx; - } - - // Apply score for last match - if (bestLetter != null) - { - score += bestLetterScore; - matchedIndices.Add((int) bestLetterIdx); - } - - outScore = score; - return patternIdx == patternLength; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Extensions/UserExtension.cs b/Hanekawa/Extensions/UserExtension.cs deleted file mode 100644 index 49da77ff..00000000 --- a/Hanekawa/Extensions/UserExtension.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Threading.Tasks; -using Disqord; -using Disqord.Rest; - -namespace Hanekawa.Extensions -{ - public static class UserExtension - { - public static bool HierarchyCheck(this CachedMember mainUser, CachedMember comparer) - => mainUser.Hierarchy > comparer.Hierarchy; - - public static bool HierarchyCheck(this CachedMember mainUser, CachedRole role) - => mainUser.Hierarchy > role.Position; - - public static async Task TryMute(this CachedMember user) - { - if (user.VoiceState == null) return false; - await user.ModifyAsync(x => x.Mute = true); - return true; - } - - public static async Task TryUnMute(this CachedMember user) - { - if (user.VoiceState == null) return false; - await user.ModifyAsync(x => x.Mute = false); - return true; - } - - public static string GetGame(this CachedUser user) - { - if (user.Presence.Activity == null) return "Currently not playing"; - var result = user.Presence.Activity.Type switch - { - ActivityType.Listening => $"Listening: {user.Presence.Activity.Name}", - ActivityType.Playing => $"Playing: {user.Presence.Activity.Name}", - ActivityType.Streaming => $"Streaming: {user.Presence.Activity.Name}", - ActivityType.Watching => $"Watching: {user.Presence.Activity.Name}", - _ => "Currently not playing" - }; - - return result; - } - - public static string GetStatus(this CachedUser user) - { - if (user.Presence == null || user.Presence.Status == null) return "N/A"; - var result = user.Presence.Status switch - { - UserStatus.Online => "Online", - UserStatus.Idle => "Idle", - UserStatus.DoNotDisturb => "DND", - UserStatus.Invisible => "Invisible", - UserStatus.Offline => "Offline", - _ => "N/A" - }; - return result; - } - - public static async Task GetOrFetchMemberAsync(this CachedGuild guild, Snowflake id) - { - IMember user = guild.GetMember(id); - if (user != null) return user; - user = await guild.GetMemberAsync(id); - return user; - } - - public static async Task GetOrFetchUserAsync(this DiscordClientBase client, Snowflake id) - { - var user = client.GetUser(id); - if (user != null) return user; - var restUser = await client.GetUserAsync(id); - return restUser; - } - } -} \ No newline at end of file diff --git a/Hanekawa/Hanekawa.csproj b/Hanekawa/Hanekawa.csproj index 8b3f513b..a00e10d3 100644 --- a/Hanekawa/Hanekawa.csproj +++ b/Hanekawa/Hanekawa.csproj @@ -1,258 +1,25 @@ - + - net5.0 - InProcess - 9 - Linux - ..\docker-compose.dcproj - c696b14f-766c-46aa-abdc-b3e499beb340 + net9.0 + preview + enable + enable - - - - - - - - - - - - - - - - - - - - - - - - + + PublicResXFileCodeGenerator + Localization.Designer.cs + - - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - - - - - - + + True + True + Localization.resx + - - - - - - - - - - - - - - - - - PreserveNewest - - - PreserveNewest - - - - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - - + \ No newline at end of file diff --git a/Hanekawa/Interfaces/ICached.cs b/Hanekawa/Interfaces/ICached.cs new file mode 100644 index 00000000..2c9f557b --- /dev/null +++ b/Hanekawa/Interfaces/ICached.cs @@ -0,0 +1,3 @@ +namespace Hanekawa.Interfaces; + +public interface ICached; \ No newline at end of file diff --git a/Hanekawa/Interfaces/IConfig.cs b/Hanekawa/Interfaces/IConfig.cs new file mode 100644 index 00000000..5bce4cd9 --- /dev/null +++ b/Hanekawa/Interfaces/IConfig.cs @@ -0,0 +1,3 @@ +namespace Hanekawa.Interfaces; + +public interface IConfig : IGuildEntity; \ No newline at end of file diff --git a/Hanekawa/Interfaces/IMemberEntity.cs b/Hanekawa/Interfaces/IMemberEntity.cs new file mode 100644 index 00000000..3f7a1197 --- /dev/null +++ b/Hanekawa/Interfaces/IMemberEntity.cs @@ -0,0 +1,14 @@ +namespace Hanekawa.Interfaces; + +public interface IMemberEntity : IGuildEntity, IEntity +{ } + +public interface IGuildEntity +{ + public ulong GuildId { get; init; } +} + +public interface IEntity +{ + public ulong Id { get; set; } +} \ No newline at end of file diff --git a/Hanekawa/Localize/Localization.Designer.cs b/Hanekawa/Localize/Localization.Designer.cs new file mode 100644 index 00000000..dbf9ae42 --- /dev/null +++ b/Hanekawa/Localize/Localization.Designer.cs @@ -0,0 +1,224 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Hanekawa.Localize { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Localization { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Localization() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Hanekawa.Localize.Localization", typeof(Localization).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Banned {0} from {1}. + /// + public static string BannedGuildUser { + get { + return ResourceManager.GetString("BannedGuildUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Boost configuration. + /// + public static string BoostConfig { + get { + return ResourceManager.GetString("BoostConfig", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Channel must be a text channel!. + /// + public static string ChannelMustBeTextChannel { + get { + return ResourceManager.GetString("ChannelMustBeTextChannel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cleared all warnings for {0}. + /// + public static string ClearedAllWarnUserMention { + get { + return ResourceManager.GetString("ClearedAllWarnUserMention", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Cleared warning for {0}. + /// + public static string ClearedWarningUserMention { + get { + return ResourceManager.GetString("ClearedWarningUserMention", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to List all registered boost actions. + /// + public static string Cmd_Desc_ListBoostActions { + get { + return ResourceManager.GetString("Cmd_Desc_ListBoostActions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Kicked {0} from {1}. + /// + public static string KickedGuildUser { + get { + return ResourceManager.GetString("KickedGuildUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Muted {0} for {1}. + /// + public static string MutedGuildUserDuration { + get { + return ResourceManager.GetString("MutedGuildUserDuration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No boost actions found.. + /// + public static string NoFound_BoostActions { + get { + return ResourceManager.GetString("NoFound_BoostActions", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No images found. + /// + public static string NoImagesFound { + get { + return ResourceManager.GetString("NoImagesFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Image with that ID not found. + /// + public static string NoImageWithIdFound { + get { + return ResourceManager.GetString("NoImageWithIdFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No roles found. + /// + public static string NoRolesFound { + get { + return ResourceManager.GetString("NoRolesFound", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No warnings found for {0}. + /// + public static string NoWarningsUserMention { + get { + return ResourceManager.GetString("NoWarningsUserMention", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Pruned {0} messages from this channel. + /// + public static string PrunedMessages { + get { + return ResourceManager.GetString("PrunedMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Removed image. + /// + public static string RemovedImage { + get { + return ResourceManager.GetString("RemovedImage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unbanned {0} from {1}. + /// + public static string UnbannedGuildUser { + get { + return ResourceManager.GetString("UnbannedGuildUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Un-muted {0}. + /// + public static string UnMutedUser { + get { + return ResourceManager.GetString("UnMutedUser", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Warned {0}. + /// + public static string WarnedUser { + get { + return ResourceManager.GetString("WarnedUser", resourceCulture); + } + } + } +} diff --git a/Hanekawa/Localize/Localization.resx b/Hanekawa/Localize/Localization.resx new file mode 100644 index 00000000..b334fe0f --- /dev/null +++ b/Hanekawa/Localize/Localization.resx @@ -0,0 +1,75 @@ + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Banned {0} from {1} + + + Unbanned {0} from {1} + + + Un-muted {0} + + + Kicked {0} from {1} + + + Pruned {0} messages from this channel + + + Warned {0} + + + Muted {0} for {1} + + + No images found + + + Channel must be a text channel! + + + Removed image + + + Image with that ID not found + + + No roles found + + + Cleared all warnings for {0} + + + Cleared warning for {0} + + + No warnings found for {0} + + + Boost configuration + + + No boost actions found. + + + List all registered boost actions + + \ No newline at end of file diff --git a/Hanekawa/Models/Api/BanCase.cs b/Hanekawa/Models/Api/BanCase.cs deleted file mode 100644 index 47a5a301..00000000 --- a/Hanekawa/Models/Api/BanCase.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using Disqord.Serialization.Json; -using Hanekawa.Database.Tables.Moderation; - -namespace Hanekawa.Models.Api -{ - public class BanCase - { - public BanCase() { } - - public BanCase(ModLog modLog) - { - GuildId = modLog.GuildId; - UserId = modLog.UserId; - ModeratorId = modLog.ModId; - Date = modLog.Date; - Reason = modLog.Response; - } - - [JsonProperty("guildId")] - public ulong GuildId { get; set; } - - [JsonProperty("userId")] - public ulong UserId { get; set; } - - [JsonProperty("moderatorId")] - public ulong? ModeratorId { get; set; } - - [JsonProperty("date")] - public DateTimeOffset Date { get; set; } - - [JsonProperty("reason")] - public string Reason { get; set; } - } -} diff --git a/Hanekawa/Models/Api/Command.cs b/Hanekawa/Models/Api/Command.cs deleted file mode 100644 index 5657e6aa..00000000 --- a/Hanekawa/Models/Api/Command.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; - -namespace Hanekawa.Models.Api -{ - public class Command - { - public string Name { get; set; } - public List Commands { get; set; } - public string Description { get; set; } - public List Example { get; set; } - public bool Premium { get; set; } - public List Permissions { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/Models/Api/Leaderboard.cs b/Hanekawa/Models/Api/Leaderboard.cs deleted file mode 100644 index a543bc9f..00000000 --- a/Hanekawa/Models/Api/Leaderboard.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Hanekawa.Models.Api -{ - [JsonObject(MemberSerialization.OptIn)] - public class Leaderboard - { - [JsonProperty("users")] public List Users { get; set; } = new(); - } - - [JsonObject(MemberSerialization.OptIn)] - public class LeaderboardUser - { - [JsonProperty("userId")] - public ulong UserId { get; set; } - - [JsonProperty("level")] - public int Level { get; set; } - - [JsonProperty("experience")] - public int Experience { get; set; } - - [JsonProperty("expToLevel")] - public int ExpToLevel { get; set; } - - [JsonProperty("totalExp")] - public int TotalExp { get; set; } - } - - [JsonObject(MemberSerialization.OptIn)] - public class LeaderboardWeekly - { - [JsonProperty("users")] - public List Users { get; set; } = new(); - } - - [JsonObject(MemberSerialization.OptIn)] - public class LeaderboardWeeklyUser - { - [JsonProperty("userId")] - public ulong UserId { get; set; } - - [JsonProperty("points")] - public int Points { get; set; } - } - - [JsonObject(MemberSerialization.OptIn)] - public class LeaderboardRichest - { - [JsonProperty("users")] - public List Users { get; set; } = new(); - } - - [JsonObject(MemberSerialization.OptIn)] - public class LeaderboardRichestUser - { - [JsonProperty("userId")] - public ulong UserId { get; set; } - - [JsonProperty("points")] - public int Points { get; set; } - } -} diff --git a/Hanekawa/Models/Api/Module.cs b/Hanekawa/Models/Api/Module.cs deleted file mode 100644 index 7ae5fd28..00000000 --- a/Hanekawa/Models/Api/Module.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace Hanekawa.Models.Api -{ - public class Module - { - public string Name { get; set; } - public string Description { get; set; } - public List Commands { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/Models/DslWebhook.cs b/Hanekawa/Models/DslWebhook.cs deleted file mode 100644 index 8ed39931..00000000 --- a/Hanekawa/Models/DslWebhook.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Newtonsoft.Json; - -namespace Hanekawa.Models -{ - public class DslWebhook - { - [JsonProperty("guild")] - public string Guild { get; set; } - - [JsonProperty("user")] - public string User { get; set; } - - [JsonProperty("type")] - public string Type { get; set; } - - [JsonProperty("query")] - public string Query { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/Models/HungerGame/UserAction.cs b/Hanekawa/Models/HungerGame/UserAction.cs deleted file mode 100644 index ff8188a0..00000000 --- a/Hanekawa/Models/HungerGame/UserAction.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Hanekawa.Database.Tables.Account.HungerGame; -using Hanekawa.Shared.Game.HungerGame; - -namespace Hanekawa.Models.HungerGame -{ - public class UserAction - { - public HungerGameProfile AfterProfile { get; set; } - public HungerGameProfile BeforeProfile { get; set; } - public ActionType Action { get; internal set; } = ActionType.Idle; - public string Message { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/Models/Range.cs b/Hanekawa/Models/Range.cs deleted file mode 100644 index 63e888a8..00000000 --- a/Hanekawa/Models/Range.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Hanekawa.Models -{ - public class Range - { - public Range(int minValue, int maxValue) - { - MaxValue = maxValue; - MinValue = minValue; - } - - public int MinValue { get; } - public int MaxValue { get; } - - public override string ToString() => $"{MinValue}-{MaxValue}"; - - } -} \ No newline at end of file diff --git a/Hanekawa/Models/ShipGame/ShipGame.cs b/Hanekawa/Models/ShipGame/ShipGame.cs deleted file mode 100644 index 7d6a65e2..00000000 --- a/Hanekawa/Models/ShipGame/ShipGame.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Hanekawa.Models.ShipGame -{ - public class ShipGame - { - public ShipGame(ShipGameUser playerOne, ShipGameUser playerTwo, int? bet) - { - PlayerOne = playerOne; - PlayerTwo = playerTwo; - Bet = bet; - } - - public ShipGameUser PlayerOne { get; } - public ShipGameUser PlayerTwo { get; } - public int? Bet { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/Models/ShipGame/ShipGameUser.cs b/Hanekawa/Models/ShipGame/ShipGameUser.cs deleted file mode 100644 index 6b600ac8..00000000 --- a/Hanekawa/Models/ShipGame/ShipGameUser.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Disqord; -using Hanekawa.Database.Tables.BotGame; - -namespace Hanekawa.Models.ShipGame -{ - public class ShipGameUser - { - public ShipGameUser(GameEnemy enemy, int level, GameClass gameClass, int damage, int health) - { - Id = (ulong)enemy.Id; - Name = enemy.Name; - Level = level; - - Health = damage; - Damage = health; - - DamageTaken = 0; - Avoidance = gameClass.ChanceAvoid; - CriticalChance = gameClass.ChanceCrit; - - DamageModifier = gameClass.ModifierDamage; - AvoidModifier = gameClass.ModifierAvoidance; - CritModifier = gameClass.ModifierCriticalChance; - HealthModifier = gameClass.ModifierHealth; - - IsNpc = true; - Bet = null; - - Class = gameClass; - Enemy = enemy; - } - - public ShipGameUser(CachedMember userOne, int level, GameClass gameClass, int damage, int health) - { - Id = userOne.Id.RawValue; - Name = userOne.DisplayName; - Level = level; - - Health = damage; - Damage = health; - - DamageTaken = 0; - Avoidance = gameClass.ChanceAvoid; - CriticalChance = gameClass.ChanceCrit; - - DamageModifier = gameClass.ModifierDamage; - AvoidModifier = gameClass.ModifierAvoidance; - CritModifier = gameClass.ModifierCriticalChance; - HealthModifier = gameClass.ModifierHealth; - - IsNpc = false; - Bet = null; - - Class = gameClass; - Enemy = null; - } - - public string Name { get; set; } - public ulong Id { get; set; } - public int Level { get; set; } - - public int Health { get; set; } - public int Damage { get; set; } - - public int DamageTaken { get; set; } - public int Avoidance { get; set; } - public int CriticalChance { get; set; } - - public double DamageModifier { get; set; } - public double CritModifier { get; set; } - public double AvoidModifier { get; set; } - public double HealthModifier { get; set; } - - public bool IsNpc { get; set; } - public int? Bet { get; set; } - - public GameClass Class { get; set; } - public GameEnemy? Enemy { get; set; } - } -} \ No newline at end of file diff --git a/Hanekawa/NLog-example.config b/Hanekawa/NLog-example.config deleted file mode 100644 index ce5eacb6..00000000 --- a/Hanekawa/NLog-example.config +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - INSERT INTO dbo.log ( - Logged, Level, Message, Logger, Callsite, Exception ) - values ( - @Logged, @Level, @Message, @Logger, @Callsite, @Exception - ); - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Hanekawa/Program.cs b/Hanekawa/Program.cs deleted file mode 100644 index 4dfd79e0..00000000 --- a/Hanekawa/Program.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Microsoft.Extensions.Logging; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using NLog; -using NLog.Web; -using LogLevel = Microsoft.Extensions.Logging.LogLevel; - -namespace Hanekawa -{ - public class Program - { - public static void Main(string[] args) - { - try { CreateWebHostBuilder(args).Build().Run(); } - finally { LogManager.Shutdown(); } - } - - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseStartup() - .ConfigureLogging(x => - { - x.ClearProviders(); - x.SetMinimumLevel(LogLevel.Information); - }) - .UseNLog() - .UseUrls("http://*:61039"); - } -} \ No newline at end of file diff --git a/Hanekawa/Startup.cs b/Hanekawa/Startup.cs deleted file mode 100644 index d7b0db4e..00000000 --- a/Hanekawa/Startup.cs +++ /dev/null @@ -1,251 +0,0 @@ -using System; -using System.Diagnostics; -using System.Linq; -using System.Net.Http; -using System.Reflection; -using System.Threading; -using System.Threading.Tasks; -using Disqord; -using Disqord.Extensions.Interactivity; -using Hanekawa.Bot.Prefix; -using Hanekawa.Bot.Services; -using Hanekawa.Bot.Services.Administration.Warning; -using Hanekawa.Bot.Services.Anime; -using Hanekawa.Bot.Services.Boost; -using Hanekawa.Bot.Services.Experience; -using Hanekawa.Bot.Services.Game.HungerGames; -using Hanekawa.Bot.Services.Mvp; -using Hanekawa.Database; -using Hanekawa.Extensions; -using Hanekawa.Shared.Command; -using Hanekawa.Shared.Interfaces; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Logging; -using NLog; -using NLog.Config; -using NLog.Targets; -using NLog.Targets.Wrappers; -using Qmmands; -using Quartz; -using ILogger = Disqord.Logging.ILogger; -using LogLevel = NLog.LogLevel; - -namespace Hanekawa -{ - public class Startup - { - public Startup(IConfiguration configuration) => Configuration = configuration; - public IConfiguration Configuration { get; } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - services.AddControllers(); - services.AddHostedService(); - services.AddHostedService(); - services.AddSingleton(Configuration); - services.AddLogging(); - services.AddDbContextPool(x => - { - x.UseNpgsql(Configuration["connectionString"]); - x.EnableDetailedErrors(); - x.EnableSensitiveDataLogging(false); - x.UseLoggerFactory(MyLoggerFactory); - }); - services.AddSingleton(new Random()); - services.AddSingleton(new HttpClient()); - services.AddSingleton(new ColourService()); - services.UseQuartz(typeof(WarnService)); - services.UseQuartz(typeof(MvpService)); - services.UseQuartz(typeof(BoostService)); - services.UseQuartz(typeof(HungerGameService)); - services.UseQuartz(typeof(ExpService)); - - var assembly = Assembly.GetEntryAssembly(); - var serviceList = assembly.GetTypes() - .Where(x => x.GetInterfaces().Contains(typeof(INService)) - && !x.GetTypeInfo().IsInterface && !x.GetTypeInfo().IsAbstract).ToList(); - for (var i = 0; i < serviceList.Count; i++) - { - var x = serviceList[i]; - services.AddSingleton(x); - } - - services.AddSingleton(x => - { - var bot = new Bot.Hanekawa(TokenType.Bot, Configuration["token"], new GuildPrefix(x), - new DiscordBotConfiguration - { - MessageCache = new Optional(new DefaultMessageCache(100)), - Logger = new Optional(new DiscordLogger()), - DefaultMentions = new Optional(LocalMentions.NoEveryone), - CommandServiceConfiguration = new CommandServiceConfiguration - { - DefaultRunMode = RunMode.Parallel, - StringComparison = StringComparison.OrdinalIgnoreCase, - CooldownBucketKeyGenerator = (e, context) => - { - var cooldownType = (HanaCooldown)e; - var ctx = (HanekawaCommandContext) context; - return cooldownType == HanaCooldown.User - ? ctx.User.Id.RawValue - : ctx.Guild.Id.RawValue; - } - }, - ProviderFactory = _ => x - }); - return bot; - }); - } - - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) - { - if (env.IsDevelopment()) - app.UseDeveloperExceptionPage(); - else - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); - app.UseHttpsRedirection(); - using var scope = app.ApplicationServices.CreateScope(); - using var db = scope.ServiceProvider.GetRequiredService(); - db.Database.Migrate(); - app.UseRouting(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllerRoute( - "default", - "{controller}/{action=Index}/{id?}"); - }); - NLog.Web.NLogBuilder.ConfigureNLog(ConfigureNLog()); - - var assembly = Assembly.GetEntryAssembly(); - var serviceList = assembly.GetTypes() - .Where(x => x.GetInterfaces().Contains(typeof(IRequired)) - && !x.GetTypeInfo().IsInterface && !x.GetTypeInfo().IsAbstract).ToList(); - for (var i = 0; i < serviceList.Count; i++) app.ApplicationServices.GetRequiredService(serviceList[i]); - var scheduler = app.ApplicationServices.GetRequiredService(); - QuartzExtension.StartCronJob(scheduler, "0 0 13 1/1 * ? *"); - QuartzExtension.StartCronJob(scheduler, "0 0 18 1/1 * ? *"); - QuartzExtension.StartCronJob(scheduler, "0 0 12 ? * MON *"); - QuartzExtension.StartCronJob(scheduler, "0 0 0/3 1/1 * ? *"); - QuartzExtension.StartCronJob(scheduler, "0 0 0/1 1/1 * ? *"); - } - - private static readonly ILoggerFactory MyLoggerFactory - = LoggerFactory.Create(builder => - { - builder - .AddFilter((category, level) => - category == DbLoggerCategory.Update.Name - && level == Microsoft.Extensions.Logging.LogLevel.Information) - .AddConsole(); - }); - - private LoggingConfiguration ConfigureNLog() - { - var consoleTarget = new ConsoleTarget - { - Name = "Console", - Layout = @"${longdate} | ${level} | ${message} | ${exception}", - DetectConsoleAvailable = true, - OptimizeBufferReuse = true, - AutoFlush = true - }; - var fileTarget = new FileTarget - { - Name = "File", - FileName = "${basedir}/logs/${shortdate}-log.txt", - Layout = "${longdate} | ${level} | ${message} | ${exception}", - OptimizeBufferReuse = true, - AutoFlush = true, - ConcurrentWriteAttempts = -1, - ArchiveEvery = FileArchivePeriod.Day, - ArchiveOldFileOnStartup = true, - ConcurrentWrites = true, - CreateDirs = true - }; - var dbTarget = new DatabaseTarget - { - Name = "Database", - ConnectionString = Configuration["connectionString"], - DBProvider = "Npgsql.NpgsqlConnection,Npgsql", - CommandText = @"INSERT INTO ""Logs"" " + - @"(""TimeStamp"", ""Level"", ""Message"", ""Logger"", ""CallSite"", ""Exception"") " + - @"VALUES " + - @"(@datetime, @level, @message, @logger, @callsite, @exception)", - KeepConnection = true, - Parameters = - { - new DatabaseParameterInfo("@datetime", "${longdate}"), - new DatabaseParameterInfo("@level", "${level}"), - new DatabaseParameterInfo("@message", "${message}"), - new DatabaseParameterInfo("@logger", "${logger}"), - new DatabaseParameterInfo("@callsite", "${callsite}"), - //new DatabaseParameterInfo("@exception", "${exception:format=shortType,message :separator= - }${newline}${exception:format=method}${newline}${exception:format=stackTrace:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}") - new DatabaseParameterInfo("@exception", "${exception:format=toString,Data}") - }, - OptimizeBufferReuse = true - }; - - var asyncConsoleTarget = new AsyncTargetWrapper - { - Name = "Async Console Target", - OptimizeBufferReuse = true, - OverflowAction = AsyncTargetWrapperOverflowAction.Grow, - WrappedTarget = consoleTarget, - TimeToSleepBetweenBatches = 1, - QueueLimit = 25 - }; - - var asyncFileTarget = new AsyncTargetWrapper - { - Name = "Async File Target", - OptimizeBufferReuse = true, - OverflowAction = AsyncTargetWrapperOverflowAction.Grow, - WrappedTarget = fileTarget, - TimeToSleepBetweenBatches = 1, - QueueLimit = 25 - }; - - var asyncDatabaseTarget = new AsyncTargetWrapper - { - Name = "Async Database Target", - OptimizeBufferReuse = true, - OverflowAction = AsyncTargetWrapperOverflowAction.Grow, - WrappedTarget = dbTarget, - TimeToSleepBetweenBatches = 1, - QueueLimit = 25 - }; - - var config = new LoggingConfiguration(); - config.AddTarget(asyncConsoleTarget); - config.AddTarget(asyncFileTarget); - config.AddTarget(asyncDatabaseTarget); - - config.AddRule(LogLevel.Info, LogLevel.Fatal, asyncConsoleTarget); - config.AddRule(LogLevel.Warn, LogLevel.Fatal, asyncDatabaseTarget); - LogManager.Configuration = config; - LogManager.ThrowExceptions = Debugger.IsAttached; - - return config; - } - } - - public class RunBot : BackgroundService - { - private readonly Bot.Hanekawa _client; - public RunBot(Bot.Hanekawa client) => _client = client; - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - await _client.AddExtensionAsync(new InteractivityExtension()); - await _client.RunAsync(stoppingToken); - await Task.Delay(-1, stoppingToken); - } - } -} \ No newline at end of file diff --git a/Hanekawa/Utility/MessageUtil.cs b/Hanekawa/Utility/MessageUtil.cs deleted file mode 100644 index 9024b264..00000000 --- a/Hanekawa/Utility/MessageUtil.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Text.RegularExpressions; -using Disqord; -using Quartz.Util; - -namespace Hanekawa.Utility -{ - public static class MessageUtil - { - private static Regex PlayerRegex => new Regex("%PLAYER%", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static Regex UserRegex => new Regex("%USER%", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static Regex ServerRegex => new Regex("%SERVER%", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static Regex MembersRegex => new Regex("%MEMBERS%", RegexOptions.IgnoreCase | RegexOptions.Compiled); - - private static Regex UsernameRegex => new Regex("%USERNAME%", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static Regex MentionRegex => new Regex("%MENTION%", RegexOptions.IgnoreCase | RegexOptions.Compiled); - - public static string FormatMessage(string msg, CachedMember user, CachedGuild guild) - { - if (msg.IsNullOrWhiteSpace()) return null; - if (PlayerRegex.IsMatch(msg) && user != null) msg = PlayerRegex.Replace(msg, user.Mention); - if (UserRegex.IsMatch(msg) && user != null) msg = UserRegex.Replace(msg, user.Mention); - - if (UsernameRegex.IsMatch(msg) && user != null) msg = UsernameRegex.Replace(msg, user.DisplayName); - if (MentionRegex.IsMatch(msg) && user != null) msg = MentionRegex.Replace(msg, user.Mention); - if (ServerRegex.IsMatch(msg) && guild != null) msg = ServerRegex.Replace(msg, guild.Name); - if (MembersRegex.IsMatch(msg) && guild != null) msg = MembersRegex.Replace(msg, $"{guild.MemberCount + 1}"); - return msg; - } - } -} diff --git a/Hanekawa/Utility/QuartzJonFactory.cs b/Hanekawa/Utility/QuartzJonFactory.cs deleted file mode 100644 index 69d019fc..00000000 --- a/Hanekawa/Utility/QuartzJonFactory.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using Hanekawa.Shared.Interfaces; -using Quartz; -using Quartz.Spi; - -namespace Hanekawa.Utility -{ - public class QuartzJonFactory : IJobFactory, INService - { - private readonly IServiceProvider _services; - - public QuartzJonFactory(IServiceProvider services) => _services = services; - - public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) - { - var jobDetail = bundle.JobDetail; - - var job = (IJob) _services.GetService(jobDetail.JobType); - return job; - } - - public void ReturnJob(IJob job) - { - } - } -} \ No newline at end of file diff --git a/Hanekawa/appsettings.Development.json b/Hanekawa/appsettings.Development.json deleted file mode 100644 index f999bc20..00000000 --- a/Hanekawa/appsettings.Development.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" - } - } -} \ No newline at end of file diff --git a/Hanekawa/appsettings.json b/Hanekawa/appsettings.json deleted file mode 100644 index 24bb9907..00000000 --- a/Hanekawa/appsettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Logging": { - "LogLevel": { - "Default": "Information" - } - }, - "AllowedHosts": "*" -} \ No newline at end of file diff --git a/nuget.config b/nuget.config index 76f3f85d..62dfa372 100644 --- a/nuget.config +++ b/nuget.config @@ -1,7 +1,7 @@ - + \ No newline at end of file