diff --git a/.deploy.yml b/.deploy.yml
index cf0e485..5fb394d 100644
--- a/.deploy.yml
+++ b/.deploy.yml
@@ -7,13 +7,13 @@
ansible_python_interpreter: /usr/bin/python3
tasks:
- name: Login to Gitlab Docker Registry
- docker_login:
+ 'community.docker.docker_login':
registry_url: "{{ lookup('env', 'CI_REGISTRY') }}"
username: "{{ lookup('env', 'CI_REGISTRY_USER') }}"
password: "{{ lookup('env', 'CI_REGISTRY_PASSWORD') }}"
reauthorize: yes
- name: Replace Prod Container
- docker_container:
+ 'community.docker.docker_container':
name: GeekbotProd
image: "{{ lookup('env', 'IMAGE_TAG') }}"
recreate: yes
@@ -34,5 +34,5 @@
GEEKBOT_SENTRY: "{{ lookup('env', 'GEEKBOT_SENTRY') }}"
GEEKBOT_DB_REDSHIFT_COMPAT: "true"
- name: Cleanup Old Container
- docker_prune:
+ 'community.docker.docker_prune':
images: yes
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c4d8b15..a774f5e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,12 +5,12 @@ stages:
- ops
variables:
- VERSION: 4.3.0-$CI_COMMIT_SHORT_SHA
+ VERSION: 4.4.0-V$CI_COMMIT_SHORT_SHA
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
Build:
stage: build
- image: mcr.microsoft.com/dotnet/sdk:5.0
+ image: mcr.microsoft.com/dotnet/sdk:6.0
artifacts:
expire_in: 1h
paths:
@@ -18,7 +18,7 @@ Build:
script:
- dotnet restore
- dotnet test tests
- - dotnet publish --version-suffix $VERSION -r linux-x64 -c Release -o ./app ./src/Bot/
+ - dotnet publish --version-suffix "$VERSION" -r linux-x64 -c Release -p:DebugType=embedded --no-self-contained -o ./app ./src/Startup/
Package:
stage: docker
@@ -34,7 +34,7 @@ Package:
Deploy:
stage: deploy
- image: ansible/ansible-runner
+ image: quay.io/ansible/ansible-runner:stable-2.12-latest
only:
- master
variables:
@@ -46,6 +46,7 @@ Deploy:
- chmod -R 600 /root/.ssh
- ssh-keyscan -p 65432 $PROD_IP > /root/.ssh/known_hosts
script:
+ - ansible-galaxy collection install -r ansible-requirements.yml
- ansible-playbook -i $PROD_IP, .deploy.yml
Sentry:
diff --git a/Dockerfile b/Dockerfile
index 245e06b..39529ff 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM mcr.microsoft.com/dotnet/aspnet:5.0
+FROM mcr.microsoft.com/dotnet/aspnet:6.0
COPY ./app /app/
diff --git a/Geekbot.net.sln b/Geekbot.net.sln
index 4a5b912..f33d887 100644
--- a/Geekbot.net.sln
+++ b/Geekbot.net.sln
@@ -11,6 +11,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web", "src\Web\Web.csproj",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bot", "src\Bot\Bot.csproj", "{DBF79896-9F7F-443D-B336-155E276DFF16}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Commands", "src\Commands\Commands.csproj", "{7C771DFE-912A-4276-B0A6-047E09603F1E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interactions", "src\Interactions\Interactions.csproj", "{FF6859D9-C539-4910-BE1E-9ECFED2F46FA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Startup", "src\Startup\Startup.csproj", "{A691B018-4B19-4A7A-A0F6-DBB17641254F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,6 +39,18 @@ Global
{DBF79896-9F7F-443D-B336-155E276DFF16}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DBF79896-9F7F-443D-B336-155E276DFF16}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DBF79896-9F7F-443D-B336-155E276DFF16}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7C771DFE-912A-4276-B0A6-047E09603F1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7C771DFE-912A-4276-B0A6-047E09603F1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7C771DFE-912A-4276-B0A6-047E09603F1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7C771DFE-912A-4276-B0A6-047E09603F1E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FF6859D9-C539-4910-BE1E-9ECFED2F46FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FF6859D9-C539-4910-BE1E-9ECFED2F46FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FF6859D9-C539-4910-BE1E-9ECFED2F46FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FF6859D9-C539-4910-BE1E-9ECFED2F46FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A691B018-4B19-4A7A-A0F6-DBB17641254F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A691B018-4B19-4A7A-A0F6-DBB17641254F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A691B018-4B19-4A7A-A0F6-DBB17641254F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A691B018-4B19-4A7A-A0F6-DBB17641254F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/ansible-requirements.yml b/ansible-requirements.yml
new file mode 100644
index 0000000..90d8fb4
--- /dev/null
+++ b/ansible-requirements.yml
@@ -0,0 +1,3 @@
+collections:
+ - name: community.docker
+ version: 2.7.0
\ No newline at end of file
diff --git a/src/Bot/Bot.csproj b/src/Bot/Bot.csproj
index 4cd5b39..2219b32 100644
--- a/src/Bot/Bot.csproj
+++ b/src/Bot/Bot.csproj
@@ -1,34 +1,25 @@
- Exe
- net5.0
- win-x64;linux-x64
- derp.ico
+ net6.0
$(VersionSuffix)
Geekbot.Bot
- Geekbot
- $(VersionSuffix)
+ Geekbot.Bot
+ $(VersionSuffix)
0.0.0-DEV
- Pizza and Coffee Studios
- Pizza and Coffee Studios
- A Discord bot
- https://github.com/pizzaandcoffee/Geekbot.net
NU1701
- git
- https://geekbot.pizzaandcoffee.rocks
-
-
- true
+ enable
+ True
+ Library
+
-
-
+
+
-
-
+
@@ -36,113 +27,7 @@
+
-
-
-
-
- ResXFileCodeGenerator
- Ship.Designer.cs
-
-
- ResXFileCodeGenerator
- Rank.Designer.cs
-
-
- ResXFileCodeGenerator
- Karma.Designer.cs
-
-
- ResXFileCodeGenerator
- Internal.Designer.cs
-
-
- ResXFileCodeGenerator
- Cookies.Designer.cs
-
-
- ResXFileCodeGenerator
- Roll.Designer.cs
-
-
- ResXFileCodeGenerator
- Choose.Designer.cs
-
-
- ResXFileCodeGenerator
- Admin.Designer.cs
-
-
- ResXFileCodeGenerator
- Quote.Designer.cs
-
-
- ResXFileCodeGenerator
- Role.Designer.cs
-
-
- ResXFileCodeGenerator
- Stats.Designer.cs
-
-
-
-
- True
- True
- ship.resx
-
-
- True
- True
- Rank.resx
-
-
- Ship.resx
-
-
- True
- True
- Karma.resx
-
-
- True
- True
- Internal.resx
-
-
- True
- True
- Cookies.resx
-
-
- True
- True
- Roll.resx
-
-
- True
- True
- Choose.resx
-
-
- True
- True
- Admin.resx
-
-
- True
- True
- Quote.resx
-
-
- True
- True
- Role.resx
-
-
- True
- True
- Stats.resx
-
diff --git a/src/Bot/BotStartup.cs b/src/Bot/BotStartup.cs
new file mode 100644
index 0000000..afb1a8a
--- /dev/null
+++ b/src/Bot/BotStartup.cs
@@ -0,0 +1,127 @@
+using System.Reflection;
+using Discord;
+using Discord.Commands;
+using Discord.WebSocket;
+using Geekbot.Bot.Handlers;
+using Geekbot.Core;
+using Geekbot.Core.Database;
+using Geekbot.Core.GlobalSettings;
+using Geekbot.Core.GuildSettingsManager;
+using Geekbot.Core.Logger;
+using Geekbot.Core.Logger.Adapters;
+using Geekbot.Core.ReactionListener;
+using Geekbot.Core.UserRepository;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Geekbot.Bot;
+
+public class BotStartup
+{
+ private readonly IServiceCollection _serviceCollection;
+ private readonly GeekbotLogger _logger;
+ private readonly RunParameters _runParameters;
+ private readonly IGlobalSettings _globalSettings;
+ private DiscordSocketClient _client;
+
+ public BotStartup(IServiceCollection serviceCollection, GeekbotLogger logger, RunParameters runParameters, IGlobalSettings globalSettings)
+ {
+ _serviceCollection = serviceCollection;
+ _logger = logger;
+ _runParameters = runParameters;
+ _globalSettings = globalSettings;
+ }
+
+ public async Task Start()
+ {
+ _logger.Information(LogSource.Geekbot, "Connecting to Discord");
+ SetupDiscordClient();
+ await Login();
+ await _client.SetGameAsync(_globalSettings.GetKey("Game"));
+ _logger.Information(LogSource.Geekbot, $"Now Connected as {_client.CurrentUser.Username} to {_client.Guilds.Count} Servers");
+
+ _logger.Information(LogSource.Geekbot, "Registering Gateway Handlers");
+ await RegisterHandlers();
+
+ _logger.Information(LogSource.Geekbot, "Done and ready for use");
+ await Task.Delay(-1);
+ }
+
+ private void SetupDiscordClient()
+ {
+ _client = new DiscordSocketClient(new DiscordSocketConfig
+ {
+ GatewayIntents = GatewayIntents.DirectMessageReactions |
+ GatewayIntents.DirectMessages |
+ GatewayIntents.GuildMessageReactions |
+ GatewayIntents.GuildMessages |
+ GatewayIntents.GuildWebhooks |
+ GatewayIntents.GuildIntegrations |
+ GatewayIntents.GuildEmojis |
+ GatewayIntents.GuildBans |
+ GatewayIntents.Guilds |
+ GatewayIntents.GuildMembers,
+ LogLevel = LogSeverity.Verbose,
+ MessageCacheSize = 1000,
+ });
+
+ var discordLogger = new DiscordLogger(_logger);
+ _client.Log += discordLogger.Log;
+ }
+
+ private async Task Login()
+ {
+ try
+ {
+ var token = await GetToken();
+ await _client.LoginAsync(TokenType.Bot, token);
+ await _client.StartAsync();
+ while (!_client.ConnectionState.Equals(ConnectionState.Connected)) await Task.Delay(25);
+ }
+ catch (Exception e)
+ {
+ _logger.Error(LogSource.Geekbot, "Could not connect to Discord", e);
+ Environment.Exit(GeekbotExitCode.CouldNotLogin.GetHashCode());
+ }
+ }
+
+ private async Task GetToken()
+ {
+ var token = _runParameters.Token ?? _globalSettings.GetKey("DiscordToken");
+ if (string.IsNullOrEmpty(token))
+ {
+ Console.Write("Your bot Token: ");
+ var newToken = Console.ReadLine();
+ await _globalSettings.SetKey("DiscordToken", newToken);
+ await _globalSettings.SetKey("Game", "Ping Pong");
+ token = newToken;
+ }
+
+ return token;
+ }
+
+ private async Task RegisterHandlers()
+ {
+ var applicationInfo = await _client.GetApplicationInfoAsync();
+
+ _serviceCollection.AddSingleton(_client);
+ var serviceProvider = _serviceCollection.BuildServiceProvider();
+
+ var commands = new CommandService();
+ await commands.AddModulesAsync(Assembly.GetAssembly(typeof(BotStartup)), serviceProvider);
+
+ var commandHandler = new CommandHandler(_client, _logger, serviceProvider, commands, applicationInfo, serviceProvider.GetService());
+ var userHandler = new UserHandler(serviceProvider.GetService(), _logger, serviceProvider.GetService(), _client);
+ var reactionHandler = new ReactionHandler(serviceProvider.GetService());
+ var statsHandler = new StatsHandler(_logger, serviceProvider.GetService());
+ var messageDeletedHandler = new MessageDeletedHandler(serviceProvider.GetService(), _logger, _client);
+
+ _client.MessageReceived += commandHandler.RunCommand;
+ _client.MessageDeleted += messageDeletedHandler.HandleMessageDeleted;
+ _client.UserJoined += userHandler.Joined;
+ _client.UserUpdated += userHandler.Updated;
+ _client.UserLeft += userHandler.Left;
+ _client.ReactionAdded += reactionHandler.Added;
+ _client.ReactionRemoved += reactionHandler.Removed;
+ if (!_runParameters.InMemory) _client.MessageReceived += statsHandler.UpdateStats;
+ }
+}
\ No newline at end of file
diff --git a/src/Core/CommandPreconditions/DisableInDirectMessageAttribute.cs b/src/Bot/CommandPreconditions/DisableInDirectMessageAttribute.cs
similarity index 93%
rename from src/Core/CommandPreconditions/DisableInDirectMessageAttribute.cs
rename to src/Bot/CommandPreconditions/DisableInDirectMessageAttribute.cs
index 835e0b3..b75f4a1 100644
--- a/src/Core/CommandPreconditions/DisableInDirectMessageAttribute.cs
+++ b/src/Bot/CommandPreconditions/DisableInDirectMessageAttribute.cs
@@ -2,7 +2,7 @@ using System;
using System.Threading.Tasks;
using Discord.Commands;
-namespace Geekbot.Core.CommandPreconditions
+namespace Geekbot.Bot.CommandPreconditions
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class DisableInDirectMessageAttribute : PreconditionAttribute
diff --git a/src/Bot/Commands/Admin/Admin.cs b/src/Bot/Commands/Admin/Admin.cs
index 60ba8ac..43fb3c4 100644
--- a/src/Bot/Commands/Admin/Admin.cs
+++ b/src/Bot/Commands/Admin/Admin.cs
@@ -9,11 +9,12 @@ using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
+using Geekbot.Bot.CommandPreconditions;
using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Admin
{
diff --git a/src/Bot/Commands/Admin/Mod.cs b/src/Bot/Commands/Admin/Mod.cs
deleted file mode 100644
index b642680..0000000
--- a/src/Bot/Commands/Admin/Mod.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Discord;
-using Discord.Commands;
-using Geekbot.Core.CommandPreconditions;
-using Geekbot.Core.ErrorHandling;
-
-namespace Geekbot.Bot.Commands.Admin
-{
- [Group("mod")]
- [RequireUserPermission(GuildPermission.KickMembers)]
- [RequireUserPermission(GuildPermission.ManageMessages)]
- [RequireUserPermission(GuildPermission.ManageRoles)]
- [DisableInDirectMessage]
- public class Mod : ModuleBase
- {
- private readonly IErrorHandler _errorHandler;
-
- public Mod(IErrorHandler errorHandler)
- {
- _errorHandler = errorHandler;
- }
-
- [Command("namehistory", RunMode = RunMode.Async)]
- [Summary("See past usernames of an user")]
- public async Task UsernameHistory([Summary("@someone")] IUser user)
- {
- try
- {
- await Context.Channel.SendMessageAsync("This command has been removed due to low usage and excessively high database usage");
- }
- catch (Exception e)
- {
- await _errorHandler.HandleCommandException(e, Context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Admin/Role.cs b/src/Bot/Commands/Admin/Role.cs
index efec7bd..fb8ef68 100644
--- a/src/Bot/Commands/Admin/Role.cs
+++ b/src/Bot/Commands/Admin/Role.cs
@@ -6,14 +6,15 @@ using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.Net;
+using Geekbot.Bot.CommandPreconditions;
using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.ReactionListener;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Admin
{
diff --git a/src/Bot/Commands/Games/Pokedex.cs b/src/Bot/Commands/Games/Pokedex.cs
index 426761c..325ee8c 100644
--- a/src/Bot/Commands/Games/Pokedex.cs
+++ b/src/Bot/Commands/Games/Pokedex.cs
@@ -3,13 +3,14 @@ using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using PokeAPI;
namespace Geekbot.Bot.Commands.Games
{
- public class Pokedex : ModuleBase
+ public class Pokedex : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Games/Roll/Roll.cs b/src/Bot/Commands/Games/Roll/Roll.cs
index 6ef9322..e9ed9e9 100644
--- a/src/Bot/Commands/Games/Roll/Roll.cs
+++ b/src/Bot/Commands/Games/Roll/Roll.cs
@@ -1,16 +1,13 @@
using System;
-using System.Linq;
using System.Threading.Tasks;
using Discord.Commands;
-using Geekbot.Bot.Utils;
using Geekbot.Core;
using Geekbot.Core.Database;
-using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.KvInMemoryStore;
using Geekbot.Core.RandomNumberGenerator;
+using Sentry;
namespace Geekbot.Bot.Commands.Games.Roll
{
@@ -34,63 +31,20 @@ namespace Geekbot.Bot.Commands.Games.Roll
{
try
{
- var number = _randomNumberGenerator.Next(1, 100);
- int.TryParse(stuff, out var guess);
- if (guess <= 100 && guess > 0)
- {
- var kvKey = $"{Context?.Guild?.Id ?? 0}:{Context.User.Id}:RollsPrevious";
-
- var prevRoll = _kvInMemoryStore.Get(kvKey);
-
- if (prevRoll?.LastGuess == guess && prevRoll?.GuessedOn.AddDays(1) > DateTime.Now)
- {
- await ReplyAsync(string.Format(
- Localization.Roll.NoPrevGuess,
- Context.Message.Author.Mention,
- DateLocalization.FormatDateTimeAsRemaining(prevRoll.GuessedOn.AddDays(1))));
- return;
- }
-
- _kvInMemoryStore.Set(kvKey, new RollTimeout {LastGuess = guess, GuessedOn = DateTime.Now});
-
- await ReplyAsync(string.Format(Localization.Roll.Rolled, Context.Message.Author.Mention, number, guess));
- if (guess == number)
- {
- await ReplyAsync(string.Format(Localization.Roll.Gratz, Context.Message.Author));
- var user = await GetUser(Context.User.Id);
- user.Rolls += 1;
- _database.Rolls.Update(user);
- await _database.SaveChangesAsync();
- }
- }
- else
- {
- await ReplyAsync(string.Format(Localization.Roll.RolledNoGuess, Context.Message.Author.Mention, number));
- }
+ var res = await new Geekbot.Commands.Roll.Roll(_kvInMemoryStore, _database, _randomNumberGenerator)
+ .RunFromGateway(
+ Context.Guild.Id,
+ Context.User.Id,
+ Context.User.Username,
+ stuff ?? "0"
+ );
+ await ReplyAsync(res);
}
catch (Exception e)
{
await ErrorHandler.HandleCommandException(e, Context);
+ Transaction.Status = SpanStatus.InternalError;
}
}
-
- private async Task GetUser(ulong userId)
- {
- var user = _database.Rolls.FirstOrDefault(u => u.GuildId.Equals(Context.Guild.Id.AsLong()) && u.UserId.Equals(userId.AsLong())) ?? await CreateNewRow(userId);
- return user;
- }
-
- private async Task CreateNewRow(ulong userId)
- {
- var user = new RollsModel()
- {
- GuildId = Context.Guild.Id.AsLong(),
- UserId = userId.AsLong(),
- Rolls = 0
- };
- var newUser = _database.Rolls.Add(user).Entity;
- await _database.SaveChangesAsync();
- return newUser;
- }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/LolMmr/LolMmr.cs b/src/Bot/Commands/Integrations/LolMmr/LolMmr.cs
index 4e75034..511d7b8 100644
--- a/src/Bot/Commands/Integrations/LolMmr/LolMmr.cs
+++ b/src/Bot/Commands/Integrations/LolMmr/LolMmr.cs
@@ -10,7 +10,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Integrations.LolMmr
{
- public class LolMmr : ModuleBase
+ public class LolMmr : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
@@ -46,9 +46,9 @@ namespace Geekbot.Bot.Commands.Integrations.LolMmr
var sb = new StringBuilder();
sb.AppendLine($"**MMR for {summonerName}**");
- sb.AppendLine($"Normal: {data.Normal.Avg}");
- sb.AppendLine($"Ranked: {data.Ranked.Avg}");
- sb.AppendLine($"ARAM: {data.ARAM.Avg}");
+ sb.AppendLine($"Normal: {data.Normal?.Avg ?? 0}");
+ sb.AppendLine($"Ranked: {data.Ranked?.Avg ?? 0}");
+ sb.AppendLine($"ARAM: {data.ARAM?.Avg ?? 0}");
await Context.Channel.SendMessageAsync(sb.ToString());
}
diff --git a/src/Bot/Commands/Integrations/LolMmr/LolMmrDto.cs b/src/Bot/Commands/Integrations/LolMmr/LolMmrDto.cs
index 51d4c85..233bcfc 100644
--- a/src/Bot/Commands/Integrations/LolMmr/LolMmrDto.cs
+++ b/src/Bot/Commands/Integrations/LolMmr/LolMmrDto.cs
@@ -1,9 +1,16 @@
+using System.Text.Json.Serialization;
+
namespace Geekbot.Bot.Commands.Integrations.LolMmr
{
public class LolMmrDto
{
+ [JsonPropertyName("ranked")]
public LolMrrInfoDto Ranked { get; set; }
+
+ [JsonPropertyName("normal")]
public LolMrrInfoDto Normal { get; set; }
+
+ [JsonPropertyName("aram")]
public LolMrrInfoDto ARAM { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/LolMmr/LolMrrInfoDto.cs b/src/Bot/Commands/Integrations/LolMmr/LolMrrInfoDto.cs
index 18b096a..fbcc49a 100644
--- a/src/Bot/Commands/Integrations/LolMmr/LolMrrInfoDto.cs
+++ b/src/Bot/Commands/Integrations/LolMmr/LolMrrInfoDto.cs
@@ -1,10 +1,10 @@
-using Newtonsoft.Json;
+using System.Text.Json.Serialization;
namespace Geekbot.Bot.Commands.Integrations.LolMmr
{
public class LolMrrInfoDto
{
- [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
- public decimal Avg { get; set; } = 0;
+ [JsonPropertyName("avg")]
+ public decimal? Avg { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/MagicTheGathering.cs b/src/Bot/Commands/Integrations/MagicTheGathering.cs
index b179d6e..359b41e 100644
--- a/src/Bot/Commands/Integrations/MagicTheGathering.cs
+++ b/src/Bot/Commands/Integrations/MagicTheGathering.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.Converters;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
@@ -11,7 +12,7 @@ using MtgApiManager.Lib.Service;
namespace Geekbot.Bot.Commands.Integrations
{
- public class MagicTheGathering : ModuleBase
+ public class MagicTheGathering : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
private readonly IMtgManaConverter _manaConverter;
diff --git a/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictListItemDto.cs b/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictListItemDto.cs
deleted file mode 100644
index 0aee35f..0000000
--- a/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictListItemDto.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Geekbot.Bot.Commands.Integrations.UbranDictionary
-{
- internal class UrbanListItemDto
- {
- public string Definition { get; set; }
- public string Permalink { get; set; }
- public string ThumbsUp { get; set; }
- public string Word { get; set; }
- public string Example { get; set; }
- public string ThumbsDown { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictResponseDto.cs b/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictResponseDto.cs
deleted file mode 100644
index 1846601..0000000
--- a/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictResponseDto.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-
-namespace Geekbot.Bot.Commands.Integrations.UbranDictionary
-{
- internal class UrbanResponseDto
- {
- public string[] Tags { get; set; }
- public List List { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictionary.cs b/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictionary.cs
deleted file mode 100644
index 72bc8cd..0000000
--- a/src/Bot/Commands/Integrations/UbranDictionary/UrbanDictionary.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System;
-using System.Linq;
-using System.Threading.Tasks;
-using Discord;
-using Discord.Commands;
-using Geekbot.Core;
-using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.Extensions;
-
-namespace Geekbot.Bot.Commands.Integrations.UbranDictionary
-{
- public class UrbanDictionary : ModuleBase
- {
- private readonly IErrorHandler _errorHandler;
-
- public UrbanDictionary(IErrorHandler errorHandler)
- {
- _errorHandler = errorHandler;
- }
-
- [Command("urban", RunMode = RunMode.Async)]
- [Summary("Lookup something on urban dictionary")]
- public async Task UrbanDefine([Remainder] [Summary("word")] string word)
- {
- try
- {
- var definitions = await HttpAbstractions.Get(new Uri($"https://api.urbandictionary.com/v0/define?term={word}"));
- if (definitions.List.Count == 0)
- {
- await ReplyAsync("That word hasn't been defined...");
- return;
- }
-
- var definition = definitions.List.First(e => !string.IsNullOrWhiteSpace(e.Example));
-
- var eb = new EmbedBuilder();
- eb.WithAuthor(new EmbedAuthorBuilder
- {
- Name = definition.Word,
- Url = definition.Permalink
- });
- eb.WithColor(new Color(239, 255, 0));
-
- static string ShortenIfToLong(string str, int maxLength) => str.Length > maxLength ? $"{str.Substring(0, maxLength - 5)}[...]" : str;
-
- if (!string.IsNullOrEmpty(definition.Definition)) eb.Description = ShortenIfToLong(definition.Definition, 1800);
- if (!string.IsNullOrEmpty(definition.Example)) eb.AddField("Example", ShortenIfToLong(definition.Example, 1024));
- if (!string.IsNullOrEmpty(definition.ThumbsUp)) eb.AddInlineField("Upvotes", definition.ThumbsUp);
- if (!string.IsNullOrEmpty(definition.ThumbsDown)) eb.AddInlineField("Downvotes", definition.ThumbsDown);
- if (definitions.Tags?.Length > 0) eb.AddField("Tags", string.Join(", ", definitions.Tags));
-
- await ReplyAsync("", false, eb.Build());
- }
- catch (Exception e)
- {
- await _errorHandler.HandleCommandException(e, Context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/UrbanDictionary.cs b/src/Bot/Commands/Integrations/UrbanDictionary.cs
new file mode 100644
index 0000000..44fe868
--- /dev/null
+++ b/src/Bot/Commands/Integrations/UrbanDictionary.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Threading.Tasks;
+using Discord.Commands;
+using Geekbot.Core;
+using Geekbot.Core.ErrorHandling;
+
+namespace Geekbot.Bot.Commands.Integrations
+{
+ public class UrbanDictionary : TransactionModuleBase
+ {
+ private readonly IErrorHandler _errorHandler;
+
+ public UrbanDictionary(IErrorHandler errorHandler)
+ {
+ _errorHandler = errorHandler;
+ }
+
+ [Command("urban", RunMode = RunMode.Async)]
+ [Summary("Lookup something on urban dictionary")]
+ public async Task UrbanDefine([Remainder] [Summary("word")] string word)
+ {
+ try
+ {
+ var eb = await Geekbot.Commands.UrbanDictionary.UrbanDictionary.Run(word);
+ if (eb == null)
+ {
+ await ReplyAsync("That word hasn't been defined...");
+ return;
+ }
+
+ await ReplyAsync(string.Empty, false, eb.ToDiscordNetEmbed().Build());
+ }
+ catch (Exception e)
+ {
+ await _errorHandler.HandleCommandException(e, Context);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Bot/Commands/Integrations/Wikipedia.cs b/src/Bot/Commands/Integrations/Wikipedia.cs
index 709f974..82f42a0 100644
--- a/src/Bot/Commands/Integrations/Wikipedia.cs
+++ b/src/Bot/Commands/Integrations/Wikipedia.cs
@@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.Database;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
@@ -14,7 +15,7 @@ using HtmlAgilityPack;
namespace Geekbot.Bot.Commands.Integrations
{
- public class Wikipedia : ModuleBase
+ public class Wikipedia : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
private readonly IWikipediaClient _wikipediaClient;
diff --git a/src/Bot/Commands/Integrations/Youtube.cs b/src/Bot/Commands/Integrations/Youtube.cs
index 60ebdaa..50e9519 100644
--- a/src/Bot/Commands/Integrations/Youtube.cs
+++ b/src/Bot/Commands/Integrations/Youtube.cs
@@ -1,58 +1,59 @@
-using System;
-using System.Threading.Tasks;
-using Discord.Commands;
-using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.GlobalSettings;
-using Google.Apis.Services;
-using Google.Apis.YouTube.v3;
+using Discord.Commands;
+using Geekbot.Core;
+// using Geekbot.Core.ErrorHandling;
+// using Geekbot.Core.GlobalSettings;
+// using Google.Apis.Services;
+// using Google.Apis.YouTube.v3;
namespace Geekbot.Bot.Commands.Integrations
{
- public class Youtube : ModuleBase
+ public class Youtube : TransactionModuleBase
{
- private readonly IGlobalSettings _globalSettings;
- private readonly IErrorHandler _errorHandler;
+ // private readonly IGlobalSettings _globalSettings;
+ // private readonly IErrorHandler _errorHandler;
- public Youtube(IGlobalSettings globalSettings, IErrorHandler errorHandler)
- {
- _globalSettings = globalSettings;
- _errorHandler = errorHandler;
- }
+ // public Youtube(IGlobalSettings globalSettings, IErrorHandler errorHandler)
+ // {
+ // _globalSettings = globalSettings;
+ // _errorHandler = errorHandler;
+ // }
[Command("yt", RunMode = RunMode.Async)]
[Summary("Search for something on youtube.")]
public async Task Yt([Remainder] [Summary("title")] string searchQuery)
{
- var key = _globalSettings.GetKey("YoutubeKey");
- if (string.IsNullOrEmpty(key))
- {
- await ReplyAsync("No youtube key set, please tell my senpai to set one");
- return;
- }
-
- try
- {
- var youtubeService = new YouTubeService(new BaseClientService.Initializer
- {
- ApiKey = key,
- ApplicationName = GetType().ToString()
- });
-
- var searchListRequest = youtubeService.Search.List("snippet");
- searchListRequest.Q = searchQuery;
- searchListRequest.MaxResults = 2;
-
- var searchListResponse = await searchListRequest.ExecuteAsync();
-
- var result = searchListResponse.Items[0];
-
- await ReplyAsync(
- $"\"{result.Snippet.Title}\" from \"{result.Snippet.ChannelTitle}\" https://youtu.be/{result.Id.VideoId}");
- }
- catch (Exception e)
- {
- await _errorHandler.HandleCommandException(e, Context);
- }
+ await ReplyAsync("The youtube command is temporarily disabled");
+
+ // var key = _globalSettings.GetKey("YoutubeKey");
+ // if (string.IsNullOrEmpty(key))
+ // {
+ // await ReplyAsync("No youtube key set, please tell my senpai to set one");
+ // return;
+ // }
+ //
+ // try
+ // {
+ // var youtubeService = new YouTubeService(new BaseClientService.Initializer
+ // {
+ // ApiKey = key,
+ // ApplicationName = GetType().ToString()
+ // });
+ //
+ // var searchListRequest = youtubeService.Search.List("snippet");
+ // searchListRequest.Q = searchQuery;
+ // searchListRequest.MaxResults = 2;
+ //
+ // var searchListResponse = await searchListRequest.ExecuteAsync();
+ //
+ // var result = searchListResponse.Items[0];
+ //
+ // await ReplyAsync(
+ // $"\"{result.Snippet.Title}\" from \"{result.Snippet.ChannelTitle}\" https://youtu.be/{result.Id.VideoId}");
+ // }
+ // catch (Exception e)
+ // {
+ // await _errorHandler.HandleCommandException(e, Context);
+ // }
}
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/BenedictCumberbatchNameGenerator.cs b/src/Bot/Commands/Randomness/BenedictCumberbatchNameGenerator.cs
index 995c921..23187bd 100644
--- a/src/Bot/Commands/Randomness/BenedictCumberbatchNameGenerator.cs
+++ b/src/Bot/Commands/Randomness/BenedictCumberbatchNameGenerator.cs
@@ -2,12 +2,13 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.RandomNumberGenerator;
namespace Geekbot.Bot.Commands.Randomness
{
- public class BenedictCumberbatchNameGenerator : ModuleBase
+ public class BenedictCumberbatchNameGenerator : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
private readonly IRandomNumberGenerator _randomNumberGenerator;
diff --git a/src/Bot/Commands/Randomness/Cat/Cat.cs b/src/Bot/Commands/Randomness/Cat/Cat.cs
index 7bd7e57..1198113 100644
--- a/src/Bot/Commands/Randomness/Cat/Cat.cs
+++ b/src/Bot/Commands/Randomness/Cat/Cat.cs
@@ -7,7 +7,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Randomness.Cat
{
- public class Cat : ModuleBase
+ public class Cat : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Randomness/Cat/CatResponseDto.cs b/src/Bot/Commands/Randomness/Cat/CatResponseDto.cs
index febb66f..523613b 100644
--- a/src/Bot/Commands/Randomness/Cat/CatResponseDto.cs
+++ b/src/Bot/Commands/Randomness/Cat/CatResponseDto.cs
@@ -1,7 +1,10 @@
-namespace Geekbot.Bot.Commands.Randomness.Cat
+using System.Text.Json.Serialization;
+
+namespace Geekbot.Bot.Commands.Randomness.Cat
{
internal class CatResponseDto
{
+ [JsonPropertyName("file")]
public string File { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokeResponseDto.cs b/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokeResponseDto.cs
index 99d9493..7c0aefa 100644
--- a/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokeResponseDto.cs
+++ b/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokeResponseDto.cs
@@ -1,7 +1,10 @@
-namespace Geekbot.Bot.Commands.Randomness.Chuck
+using System.Text.Json.Serialization;
+
+namespace Geekbot.Bot.Commands.Randomness.Chuck
{
internal class ChuckNorrisJokeResponseDto
{
+ [JsonPropertyName("value")]
public string Value { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokes.cs b/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokes.cs
index be328b4..e2b1f16 100644
--- a/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokes.cs
+++ b/src/Bot/Commands/Randomness/Chuck/ChuckNorrisJokes.cs
@@ -7,7 +7,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Randomness.Chuck
{
- public class ChuckNorrisJokes : ModuleBase
+ public class ChuckNorrisJokes : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Randomness/Dad/DadJokeResponseDto.cs b/src/Bot/Commands/Randomness/Dad/DadJokeResponseDto.cs
index 2d72bdd..012f9e9 100644
--- a/src/Bot/Commands/Randomness/Dad/DadJokeResponseDto.cs
+++ b/src/Bot/Commands/Randomness/Dad/DadJokeResponseDto.cs
@@ -1,7 +1,10 @@
-namespace Geekbot.Bot.Commands.Randomness.Dad
+using System.Text.Json.Serialization;
+
+namespace Geekbot.Bot.Commands.Randomness.Dad
{
internal class DadJokeResponseDto
{
+ [JsonPropertyName("joke")]
public string Joke { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Dad/DadJokes.cs b/src/Bot/Commands/Randomness/Dad/DadJokes.cs
index 136650c..67f9679 100644
--- a/src/Bot/Commands/Randomness/Dad/DadJokes.cs
+++ b/src/Bot/Commands/Randomness/Dad/DadJokes.cs
@@ -6,7 +6,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Randomness.Dad
{
- public class DadJokes : ModuleBase
+ public class DadJokes : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Randomness/Dog/Dog.cs b/src/Bot/Commands/Randomness/Dog/Dog.cs
index 051dbf3..39e57c7 100644
--- a/src/Bot/Commands/Randomness/Dog/Dog.cs
+++ b/src/Bot/Commands/Randomness/Dog/Dog.cs
@@ -7,7 +7,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Randomness.Dog
{
- public class Dog : ModuleBase
+ public class Dog : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Randomness/Dog/DogResponseDto.cs b/src/Bot/Commands/Randomness/Dog/DogResponseDto.cs
index 473c1ce..9f0dfce 100644
--- a/src/Bot/Commands/Randomness/Dog/DogResponseDto.cs
+++ b/src/Bot/Commands/Randomness/Dog/DogResponseDto.cs
@@ -1,7 +1,10 @@
-namespace Geekbot.Bot.Commands.Randomness.Dog
+using System.Text.Json.Serialization;
+
+namespace Geekbot.Bot.Commands.Randomness.Dog
{
internal class DogResponseDto
{
+ [JsonPropertyName("url")]
public string Url { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/EightBall.cs b/src/Bot/Commands/Randomness/EightBall.cs
index e1a3a71..b5f0c3a 100644
--- a/src/Bot/Commands/Randomness/EightBall.cs
+++ b/src/Bot/Commands/Randomness/EightBall.cs
@@ -1,18 +1,19 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Threading.Tasks;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
+using Geekbot.Core.GuildSettingsManager;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Randomness
{
- public class EightBall : ModuleBase
+ public class EightBall : GeekbotCommandBase
{
- private readonly IErrorHandler _errorHandler;
-
- public EightBall(IErrorHandler errorHandler)
+ public EightBall(IErrorHandler errorHandler, IGuildSettingsManager guildSettingsManager) : base(errorHandler, guildSettingsManager)
{
- _errorHandler = errorHandler;
}
[Command("8ball", RunMode = RunMode.Async)]
@@ -21,36 +22,19 @@ namespace Geekbot.Bot.Commands.Randomness
{
try
{
- var replies = new List
+ var enumerator = Localization.EightBall.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true).GetEnumerator();
+ var replies = new List();
+ while (enumerator.MoveNext())
{
- "It is certain",
- "It is decidedly so",
- "Without a doubt",
- "Yes, definitely",
- "You may rely on it",
- "As I see it, yes",
- "Most likely",
- "Outlook good",
- "Yes",
- "Signs point to yes",
- "Reply hazy try again",
- "Ask again later",
- "Better not tell you now",
- "Cannot predict now",
- "Concentrate and ask again",
- "Don't count on it",
- "My reply is no",
- "My sources say no",
- "Outlook not so good",
- "Very doubtful"
- };
-
+ replies.Add(enumerator.Value?.ToString());
+ }
+
var answer = new Random().Next(replies.Count);
await ReplyAsync(replies[answer]);
}
catch (Exception e)
{
- await _errorHandler.HandleCommandException(e, Context);
+ await ErrorHandler.HandleCommandException(e, Context);
}
}
}
diff --git a/src/Bot/Commands/Randomness/Fortune.cs b/src/Bot/Commands/Randomness/Fortune.cs
index cc31536..1157603 100644
--- a/src/Bot/Commands/Randomness/Fortune.cs
+++ b/src/Bot/Commands/Randomness/Fortune.cs
@@ -1,10 +1,11 @@
using System.Threading.Tasks;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.Media;
namespace Geekbot.Bot.Commands.Randomness
{
- public class Fortune : ModuleBase
+ public class Fortune : TransactionModuleBase
{
private readonly IFortunesProvider _fortunes;
diff --git a/src/Bot/Commands/Randomness/Gdq.cs b/src/Bot/Commands/Randomness/Gdq.cs
deleted file mode 100644
index c6d9fa8..0000000
--- a/src/Bot/Commands/Randomness/Gdq.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System;
-using System.Net;
-using System.Threading.Tasks;
-using Discord.Commands;
-using Geekbot.Core.ErrorHandling;
-
-namespace Geekbot.Bot.Commands.Randomness
-{
- public class Gdq : ModuleBase
- {
- private readonly IErrorHandler _errorHandler;
-
- public Gdq(IErrorHandler errorHandler)
- {
- _errorHandler = errorHandler;
- }
-
- [Command("gdq", RunMode = RunMode.Async)]
- [Summary("Get a quote from the GDQ donation generator.")]
- public async Task GetQuote()
- {
- try
- {
- using var client = new WebClient();
- var url = new Uri("http://taskinoz.com/gdq/api/");
- var response = client.DownloadString(url);
-
- await ReplyAsync(response);
- }
- catch (Exception e)
- {
- await _errorHandler.HandleCommandException(e, Context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Greetings/GreetingBaseDto.cs b/src/Bot/Commands/Randomness/Greetings/GreetingBaseDto.cs
deleted file mode 100644
index ae0274b..0000000
--- a/src/Bot/Commands/Randomness/Greetings/GreetingBaseDto.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Geekbot.Bot.Commands.Randomness.Greetings
-{
- public class GreetingBaseDto
- {
- public string Language { get; set; }
- public string LanguageNative { get; set; }
- public string LanguageCode { get; set; }
- public string Script { get; set; }
- public GreetingDto Primary { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Greetings/GreetingDto.cs b/src/Bot/Commands/Randomness/Greetings/GreetingDto.cs
deleted file mode 100644
index 679e544..0000000
--- a/src/Bot/Commands/Randomness/Greetings/GreetingDto.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-namespace Geekbot.Bot.Commands.Randomness.Greetings
-{
- public class GreetingDto
- {
- public string Text { get; set; }
- public string Dialect { get; set; }
- public string Romanization { get; set; }
- public string[] Use { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Greetings/Greetings.cs b/src/Bot/Commands/Randomness/Greetings/Greetings.cs
deleted file mode 100644
index cd69010..0000000
--- a/src/Bot/Commands/Randomness/Greetings/Greetings.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Discord;
-using Discord.Commands;
-using Geekbot.Core;
-using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.Extensions;
-
-namespace Geekbot.Bot.Commands.Randomness.Greetings
-{
- public class Greetings : ModuleBase
- {
- private readonly IErrorHandler _errorHandler;
-
- public Greetings(IErrorHandler errorHandler)
- {
- _errorHandler = errorHandler;
- }
-
- [Command("hello", RunMode = RunMode.Async)]
- [Alias("greeting", "hi", "hallo")]
- [Summary("Say hello to the bot and get a reply in a random language")]
- public async Task GetGreeting()
- {
- try
- {
- var greeting = await HttpAbstractions.Get(new Uri("https://api.greetings.dev/v1/greeting"));
-
- var eb = new EmbedBuilder();
- eb.Title = greeting.Primary.Text;
- eb.AddInlineField("Language", greeting.Language);
-
- if (greeting.Primary.Dialect != null)
- {
- eb.AddInlineField("Dialect", greeting.Primary.Dialect);
- }
-
- if (greeting.Primary.Romanization != null)
- {
- eb.AddInlineField("Roman", greeting.Primary.Romanization);
- }
-
- await ReplyAsync(string.Empty, false, eb.Build());
- }
- catch (Exception e)
- {
- await _errorHandler.HandleCommandException(e, Context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/Kanye/Kanye.cs b/src/Bot/Commands/Randomness/Kanye/Kanye.cs
index 6ad67cb..e5d2e95 100644
--- a/src/Bot/Commands/Randomness/Kanye/Kanye.cs
+++ b/src/Bot/Commands/Randomness/Kanye/Kanye.cs
@@ -6,7 +6,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Randomness.Kanye
{
- public class Kanye : ModuleBase
+ public class Kanye : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Randomness/Kanye/KanyeResponseDto.cs b/src/Bot/Commands/Randomness/Kanye/KanyeResponseDto.cs
index 8ca248e..ab8c06f 100644
--- a/src/Bot/Commands/Randomness/Kanye/KanyeResponseDto.cs
+++ b/src/Bot/Commands/Randomness/Kanye/KanyeResponseDto.cs
@@ -1,8 +1,10 @@
+using System.Text.Json.Serialization;
+
namespace Geekbot.Bot.Commands.Randomness.Kanye
{
public class KanyeResponseDto
{
- public string Id { get; set; }
+ [JsonPropertyName("quote")]
public string Quote { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Randomness/RandomAnimals.cs b/src/Bot/Commands/Randomness/RandomAnimals.cs
index b9c1bdd..5493485 100644
--- a/src/Bot/Commands/Randomness/RandomAnimals.cs
+++ b/src/Bot/Commands/Randomness/RandomAnimals.cs
@@ -1,11 +1,12 @@
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.Media;
namespace Geekbot.Bot.Commands.Randomness
{
- public class RandomAnimals : ModuleBase
+ public class RandomAnimals : TransactionModuleBase
{
private readonly IMediaProvider _mediaProvider;
diff --git a/src/Bot/Commands/Randomness/Ship.cs b/src/Bot/Commands/Randomness/Ship.cs
index f48713e..55e55c5 100644
--- a/src/Bot/Commands/Randomness/Ship.cs
+++ b/src/Bot/Commands/Randomness/Ship.cs
@@ -10,6 +10,7 @@ using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.RandomNumberGenerator;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Randomness
{
diff --git a/src/Bot/Commands/Randomness/Slap.cs b/src/Bot/Commands/Randomness/Slap.cs
index b512e73..c99c325 100644
--- a/src/Bot/Commands/Randomness/Slap.cs
+++ b/src/Bot/Commands/Randomness/Slap.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
@@ -11,7 +12,7 @@ using Geekbot.Core.Extensions;
namespace Geekbot.Bot.Commands.Randomness
{
- public class Slap : ModuleBase
+ public class Slap : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
private readonly DatabaseContext _database;
@@ -76,10 +77,14 @@ namespace Geekbot.Bot.Commands.Randomness
"teapot",
"candle",
"dictionary",
- "powerless banhammer"
+ "powerless banhammer",
+ "piece of low fat mozzarella",
+ // For some reason it never picks the last one
+ // Adding this workaround, because i'm to lazy to actually fix it at the time of writing this
+ "padding"
};
- await ReplyAsync($"{Context.User.Username} slapped {user.Username} with a {things[new Random().Next(things.Count - 1)]}");
+ await ReplyAsync($"{Context.User.Username} slapped {user.Username} with a {things[new Random().Next(0, things.Count - 1)]}");
await UpdateRecieved(user.Id);
await UpdateGiven(Context.User.Id);
@@ -127,4 +132,4 @@ namespace Geekbot.Bot.Commands.Randomness
e.UserId.Equals(userId.AsLong()));
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Bot/Commands/Rpg/Cookies.cs b/src/Bot/Commands/Rpg/Cookies.cs
index a51d652..66d845f 100644
--- a/src/Bot/Commands/Rpg/Cookies.cs
+++ b/src/Bot/Commands/Rpg/Cookies.cs
@@ -3,15 +3,15 @@ using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
-using Geekbot.Bot.Utils;
+using Geekbot.Bot.CommandPreconditions;
using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.RandomNumberGenerator;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Rpg
{
@@ -37,14 +37,16 @@ namespace Geekbot.Bot.Commands.Rpg
try
{
var actor = await GetUser(Context.User.Id);
- if (actor.LastPayout.Value.AddDays(1).Date > DateTime.Now.Date)
+ var timeoutDays = 1;
+ if (actor.LastPayout?.AddDays(timeoutDays) > DateTime.Now.ToUniversalTime())
{
- var formattedWaitTime = DateLocalization.FormatDateTimeAsRemaining(DateTimeOffset.Now.AddDays(1).Date);
+ var remaining = actor.LastPayout.Value.AddDays(timeoutDays) - DateTimeOffset.Now.ToUniversalTime();
+ var formattedWaitTime = DateLocalization.FormatDateTimeAsRemaining(remaining);
await ReplyAsync(string.Format(Localization.Cookies.WaitForMoreCookies, formattedWaitTime));
return;
}
actor.Cookies += 10;
- actor.LastPayout = DateTimeOffset.Now;
+ actor.LastPayout = DateTimeOffset.Now.ToUniversalTime();
await SetUser(actor);
await ReplyAsync(string.Format(Localization.Cookies.GetCookies, 10, actor.Cookies));
@@ -78,6 +80,12 @@ namespace Geekbot.Bot.Commands.Rpg
{
var giver = await GetUser(Context.User.Id);
+ if (amount < 1)
+ {
+ await ReplyAsync(Localization.Cookies.CantTakeCookies);
+ return;
+ }
+
if (giver.Cookies < amount)
{
await ReplyAsync(Localization.Cookies.NotEnoughToGive);
@@ -146,7 +154,7 @@ namespace Geekbot.Bot.Commands.Rpg
GuildId = Context.Guild.Id.AsLong(),
UserId = userId.AsLong(),
Cookies = 0,
- LastPayout = DateTimeOffset.MinValue
+ LastPayout = DateTimeOffset.MinValue.ToUniversalTime()
};
var newUser = _database.Cookies.Add(user).Entity;
await _database.SaveChangesAsync();
diff --git a/src/Bot/Commands/User/GuildInfo.cs b/src/Bot/Commands/User/GuildInfo.cs
index c596186..c063d89 100644
--- a/src/Bot/Commands/User/GuildInfo.cs
+++ b/src/Bot/Commands/User/GuildInfo.cs
@@ -3,7 +3,8 @@ using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
-using Geekbot.Core.CommandPreconditions;
+using Geekbot.Bot.CommandPreconditions;
+using Geekbot.Core;
using Geekbot.Core.Database;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
@@ -11,7 +12,7 @@ using Geekbot.Core.Levels;
namespace Geekbot.Bot.Commands.User
{
- public class GuildInfo : ModuleBase
+ public class GuildInfo : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
private readonly DatabaseContext _database;
diff --git a/src/Bot/Commands/User/Karma.cs b/src/Bot/Commands/User/Karma.cs
index 4778bce..469c371 100644
--- a/src/Bot/Commands/User/Karma.cs
+++ b/src/Bot/Commands/User/Karma.cs
@@ -1,13 +1,11 @@
using System;
-using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
-using Geekbot.Bot.Utils;
+using Geekbot.Bot.CommandPreconditions;
+using Geekbot.Commands.Karma;
using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
-using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
@@ -28,122 +26,51 @@ namespace Geekbot.Bot.Commands.User
[Summary("Increase Someones Karma")]
public async Task Good([Summary("@someone")] IUser user)
{
- try
- {
- var actor = await GetUser(Context.User.Id);
- if (user.Id == Context.User.Id)
- {
- await ReplyAsync(string.Format(Localization.Karma.CannotChangeOwnUp, Context.User.Username));
- }
- else if (TimeoutFinished(actor.TimeOut))
- {
- var formatedWaitTime = DateLocalization.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3));
- await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime));
- }
- else
- {
- var target = await GetUser(user.Id);
- target.Karma += 1;
- SetUser(target);
-
- actor.TimeOut = DateTimeOffset.Now;
- SetUser(actor);
-
- await _database.SaveChangesAsync();
-
- var eb = new EmbedBuilder();
- eb.WithAuthor(new EmbedAuthorBuilder()
- .WithIconUrl(user.GetAvatarUrl())
- .WithName(user.Username));
-
- eb.WithColor(new Color(138, 219, 146));
- eb.Title = Localization.Karma.Increased;
- eb.AddInlineField(Localization.Karma.By, Context.User.Username);
- eb.AddInlineField(Localization.Karma.Amount, "+1");
- eb.AddInlineField(Localization.Karma.Current, target.Karma);
- await ReplyAsync("", false, eb.Build());
- }
- }
- catch (Exception e)
- {
- await ErrorHandler.HandleCommandException(e, Context);
- }
+ await ChangeKarma(user, KarmaChange.Up);
}
[Command("bad", RunMode = RunMode.Async)]
[Summary("Decrease Someones Karma")]
public async Task Bad([Summary("@someone")] IUser user)
+ {
+ await ChangeKarma(user, KarmaChange.Down);
+ }
+
+ [Command("neutral", RunMode = RunMode.Async)]
+ [Summary("Do nothing to someones Karma")]
+ public async Task Neutral([Summary("@someone")] IUser user)
+ {
+ await ChangeKarma(user, KarmaChange.Same);
+ }
+
+ private async Task ChangeKarma(IUser user, KarmaChange change)
{
try
{
- var actor = await GetUser(Context.User.Id);
- if (user.Id == Context.User.Id)
+ var author = new Interactions.Resolved.User()
{
- await ReplyAsync(string.Format(Localization.Karma.CannotChangeOwnDown, Context.User.Username));
- }
- else if (TimeoutFinished(actor.TimeOut))
+ Id = Context.User.Id.ToString(),
+ Username = Context.User.Username,
+ Discriminator = Context.User.Discriminator,
+ Avatar = Context.User.AvatarId,
+ };
+ var targetUser = new Interactions.Resolved.User()
{
- var formatedWaitTime = DateLocalization.FormatDateTimeAsRemaining(actor.TimeOut.AddMinutes(3));
- await ReplyAsync(string.Format(Localization.Karma.WaitUntill, Context.User.Username, formatedWaitTime));
- }
- else
- {
- var target = await GetUser(user.Id);
- target.Karma -= 1;
- SetUser(target);
-
- actor.TimeOut = DateTimeOffset.Now;
- SetUser(actor);
+ Id = user.Id.ToString(),
+ Username = user.Username,
+ Discriminator = user.Discriminator,
+ Avatar = user.AvatarId,
+ };
+
+ var karma = new Geekbot.Commands.Karma.Karma(_database, Context.Guild.Id.AsLong());
+ var res = await karma.ChangeKarma(author, targetUser, change);
- await _database.SaveChangesAsync();
-
- var eb = new EmbedBuilder();
- eb.WithAuthor(new EmbedAuthorBuilder()
- .WithIconUrl(user.GetAvatarUrl())
- .WithName(user.Username));
-
- eb.WithColor(new Color(138, 219, 146));
- eb.Title = Localization.Karma.Decreased;
- eb.AddInlineField(Localization.Karma.By, Context.User.Username);
- eb.AddInlineField(Localization.Karma.Amount, "-1");
- eb.AddInlineField(Localization.Karma.Current, target.Karma);
- await ReplyAsync("", false, eb.Build());
- }
+ await ReplyAsync(string.Empty, false, res.ToDiscordNetEmbed().Build());
}
catch (Exception e)
{
await ErrorHandler.HandleCommandException(e, Context);
}
}
-
- private bool TimeoutFinished(DateTimeOffset lastKarma)
- {
- return lastKarma.AddMinutes(3) > DateTimeOffset.Now;
- }
-
- private async Task GetUser(ulong userId)
- {
- var user = _database.Karma.FirstOrDefault(u =>u.GuildId.Equals(Context.Guild.Id.AsLong()) && u.UserId.Equals(userId.AsLong())) ?? await CreateNewRow(userId);
- return user;
- }
-
- private void SetUser(KarmaModel user)
- {
- _database.Karma.Update(user);
- }
-
- private async Task CreateNewRow(ulong userId)
- {
- var user = new KarmaModel()
- {
- GuildId = Context.Guild.Id.AsLong(),
- UserId = userId.AsLong(),
- Karma = 0,
- TimeOut = DateTimeOffset.MinValue
- };
- var newUser = _database.Karma.Add(user).Entity;
- await _database.SaveChangesAsync();
- return newUser;
- }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/User/Rank.cs b/src/Bot/Commands/User/Rank.cs
new file mode 100644
index 0000000..639469f
--- /dev/null
+++ b/src/Bot/Commands/User/Rank.cs
@@ -0,0 +1,43 @@
+using Discord.Commands;
+using Geekbot.Bot.CommandPreconditions;
+using Geekbot.Core;
+using Geekbot.Core.Database;
+using Geekbot.Core.ErrorHandling;
+using Geekbot.Core.GuildSettingsManager;
+using Geekbot.Core.Highscores;
+
+namespace Geekbot.Bot.Commands.User
+{
+ public class Rank : GeekbotCommandBase
+ {
+ private readonly IHighscoreManager _highscoreManager;
+ private readonly DatabaseContext _database;
+
+ public Rank(DatabaseContext database, IErrorHandler errorHandler, IHighscoreManager highscoreManager, IGuildSettingsManager guildSettingsManager)
+ : base(errorHandler, guildSettingsManager)
+ {
+ _database = database;
+ _highscoreManager = highscoreManager;
+ }
+
+ [Command("rank", RunMode = RunMode.Async)]
+ [Summary("Get the highscore for various stats like message count, karma, correctly guessed roles, etc...")]
+ [DisableInDirectMessage]
+ public async Task RankCmd(
+ [Summary("type")] string typeUnformated = "messages",
+ [Summary("amount")] int amount = 10,
+ [Summary("season")] string season = null)
+ {
+ try
+ {
+ var res = new Geekbot.Commands.Rank(_database, _highscoreManager)
+ .Run(typeUnformated, amount, season, Context.Guild.Id, Context.Guild.Name);
+ await ReplyAsync(res);
+ }
+ catch (Exception e)
+ {
+ await ErrorHandler.HandleCommandException(e, Context);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Bot/Commands/User/Ranking/Rank.cs b/src/Bot/Commands/User/Ranking/Rank.cs
deleted file mode 100644
index 20749a8..0000000
--- a/src/Bot/Commands/User/Ranking/Rank.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Discord.Commands;
-using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
-using Geekbot.Core.Converters;
-using Geekbot.Core.Database;
-using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.Extensions;
-using Geekbot.Core.GuildSettingsManager;
-using Geekbot.Core.Highscores;
-
-namespace Geekbot.Bot.Commands.User.Ranking
-{
- public class Rank : GeekbotCommandBase
- {
- private readonly IEmojiConverter _emojiConverter;
- private readonly IHighscoreManager _highscoreManager;
- private readonly DatabaseContext _database;
-
- public Rank(DatabaseContext database, IErrorHandler errorHandler, IEmojiConverter emojiConverter, IHighscoreManager highscoreManager, IGuildSettingsManager guildSettingsManager)
- : base(errorHandler, guildSettingsManager)
- {
- _database = database;
- _emojiConverter = emojiConverter;
- _highscoreManager = highscoreManager;
- }
-
- [Command("rank", RunMode = RunMode.Async)]
- [Summary("get user top 10 in messages or karma")]
- [DisableInDirectMessage]
- public async Task RankCmd([Summary("type")] string typeUnformated = "messages", [Summary("amount")] int amount = 10)
- {
- try
- {
- HighscoreTypes type;
- try
- {
- type = Enum.Parse(typeUnformated, true);
- if (!Enum.IsDefined(typeof(HighscoreTypes), type)) throw new Exception();
- }
- catch
- {
- await ReplyAsync(Localization.Rank.InvalidType);
- return;
- }
-
- var replyBuilder = new StringBuilder();
- if (amount > 20)
- {
- await ReplyAsync(Localization.Rank.LimitingTo20Warning);
- amount = 20;
- }
-
- var guildId = Context.Guild.Id;
- Dictionary highscoreUsers;
- try
- {
- highscoreUsers = _highscoreManager.GetHighscoresWithUserData(type, guildId, amount);
- }
- catch (HighscoreListEmptyException)
- {
- await ReplyAsync(string.Format(Localization.Rank.NoTypeFoundForServer, type));
- return;
- }
-
- var guildMessages = 0;
- if (type == HighscoreTypes.messages)
- {
- guildMessages = _database.Messages
- .Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong()))
- .Select(e => e.MessageCount)
- .Sum();
- }
-
- var failedToRetrieveUser = highscoreUsers.Any(e => string.IsNullOrEmpty(e.Key.Username));
-
- if (failedToRetrieveUser) replyBuilder.AppendLine(Localization.Rank.FailedToResolveAllUsernames).AppendLine();
-
- replyBuilder.AppendLine(string.Format(Localization.Rank.HighscoresFor, type.ToString().CapitalizeFirst(), Context.Guild.Name));
-
- var highscorePlace = 1;
- foreach (var (user, value) in highscoreUsers)
- {
- replyBuilder.Append(highscorePlace < 11
- ? $"{_emojiConverter.NumberToEmoji(highscorePlace)} "
- : $"`{highscorePlace}.` ");
-
- replyBuilder.Append(user.Username != null
- ? $"**{user.Username}#{user.Discriminator}**"
- : $"**{user.Id}**");
-
- replyBuilder.Append(type == HighscoreTypes.messages
- ? $" - {value} {type} - {Math.Round((double) (100 * value) / guildMessages, 2)}%\n"
- : $" - {value} {type}\n");
-
- highscorePlace++;
- }
-
- await ReplyAsync(replyBuilder.ToString());
- }
- catch (Exception e)
- {
- await ErrorHandler.HandleCommandException(e, Context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/User/Stats.cs b/src/Bot/Commands/User/Stats.cs
index a2a54a2..61505c0 100644
--- a/src/Bot/Commands/User/Stats.cs
+++ b/src/Bot/Commands/User/Stats.cs
@@ -3,13 +3,14 @@ using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Bot.CommandPreconditions;
using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Levels;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.User
{
@@ -54,6 +55,8 @@ namespace Geekbot.Bot.Commands.User
?.FirstOrDefault(e => e.GuildId.Equals(Context.Guild.Id.AsLong()) && e.UserId.Equals(userInfo.Id.AsLong()))
?.Cookies ?? 0;
+ var quotes = _database.Quotes.Count(e => e.GuildId.Equals(Context.Guild.Id.AsLong()) && e.UserId.Equals(userInfo.Id.AsLong()));
+
var eb = new EmbedBuilder();
eb.WithAuthor(new EmbedAuthorBuilder()
.WithIconUrl(userInfo.GetAvatarUrl())
@@ -68,9 +71,9 @@ namespace Geekbot.Bot.Commands.User
e.UserId.Equals(userInfo.Id.AsLong()));
eb.AddInlineField(Localization.Stats.OnDiscordSince,
- $"{createdAt.Day}.{createdAt.Month}.{createdAt.Year} ({age} days)")
+ $"{createdAt.Day}.{createdAt.Month}.{createdAt.Year} ({age} {Localization.Stats.Days})")
.AddInlineField(Localization.Stats.JoinedServer,
- $"{joinedAt.Day}.{joinedAt.Month}.{joinedAt.Year} ({joinedDayAgo} days)")
+ $"{joinedAt.Day}.{joinedAt.Month}.{joinedAt.Year} ({joinedDayAgo} {Localization.Stats.Days})")
.AddInlineField(Localization.Stats.Karma, karma?.Karma ?? 0)
.AddInlineField(Localization.Stats.Level, level)
.AddInlineField(Localization.Stats.MessagesSent, messages)
@@ -78,6 +81,7 @@ namespace Geekbot.Bot.Commands.User
if (correctRolls != null) eb.AddInlineField(Localization.Stats.GuessedRolls, correctRolls.Rolls);
if (cookies > 0) eb.AddInlineField(Localization.Stats.Cookies, cookies);
+ if (quotes > 0) eb.AddInlineField(Localization.Stats.Quotes, quotes);
await ReplyAsync("", false, eb.Build());
}
diff --git a/src/Bot/Commands/Utils/AvatarGetter.cs b/src/Bot/Commands/Utils/AvatarGetter.cs
index 6585a75..458eec8 100644
--- a/src/Bot/Commands/Utils/AvatarGetter.cs
+++ b/src/Bot/Commands/Utils/AvatarGetter.cs
@@ -2,11 +2,12 @@
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Utils
{
- public class AvatarGetter : ModuleBase
+ public class AvatarGetter : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
@@ -21,8 +22,8 @@ namespace Geekbot.Bot.Commands.Utils
{
try
{
- if (user == null) user = Context.User;
- var url = user.GetAvatarUrl().Replace("128", "1024");
+ user ??= Context.User;
+ var url = user.GetAvatarUrl(ImageFormat.Auto, 1024);
await ReplyAsync(url);
}
catch (Exception e)
diff --git a/src/Bot/Commands/Utils/Changelog/Changelog.cs b/src/Bot/Commands/Utils/Changelog/Changelog.cs
index 92d5ddd..989ac0d 100644
--- a/src/Bot/Commands/Utils/Changelog/Changelog.cs
+++ b/src/Bot/Commands/Utils/Changelog/Changelog.cs
@@ -11,7 +11,7 @@ using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Utils.Changelog
{
- public class Changelog : ModuleBase
+ public class Changelog : TransactionModuleBase
{
private readonly DiscordSocketClient _client;
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Utils/Changelog/CommitAuthorDto.cs b/src/Bot/Commands/Utils/Changelog/CommitAuthorDto.cs
index 7cabece..19d93eb 100644
--- a/src/Bot/Commands/Utils/Changelog/CommitAuthorDto.cs
+++ b/src/Bot/Commands/Utils/Changelog/CommitAuthorDto.cs
@@ -1,11 +1,17 @@
using System;
+using System.Text.Json.Serialization;
namespace Geekbot.Bot.Commands.Utils.Changelog
{
public class CommitAuthorDto
{
+ [JsonPropertyName("name")]
public string Name { get; set; }
+
+ [JsonPropertyName("email")]
public string Email { get; set; }
+
+ [JsonPropertyName("date")]
public DateTimeOffset Date { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Utils/Changelog/CommitDto.cs b/src/Bot/Commands/Utils/Changelog/CommitDto.cs
index a534730..e67d08c 100644
--- a/src/Bot/Commands/Utils/Changelog/CommitDto.cs
+++ b/src/Bot/Commands/Utils/Changelog/CommitDto.cs
@@ -1,7 +1,10 @@
-namespace Geekbot.Bot.Commands.Utils.Changelog
+using System.Text.Json.Serialization;
+
+namespace Geekbot.Bot.Commands.Utils.Changelog
{
public class CommitDto
{
+ [JsonPropertyName("commit")]
public CommitInfoDto Commit { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Utils/Changelog/CommitInfoDto.cs b/src/Bot/Commands/Utils/Changelog/CommitInfoDto.cs
index d6f806e..592da9e 100644
--- a/src/Bot/Commands/Utils/Changelog/CommitInfoDto.cs
+++ b/src/Bot/Commands/Utils/Changelog/CommitInfoDto.cs
@@ -1,8 +1,13 @@
-namespace Geekbot.Bot.Commands.Utils.Changelog
+using System.Text.Json.Serialization;
+
+namespace Geekbot.Bot.Commands.Utils.Changelog
{
public class CommitInfoDto
{
+ [JsonPropertyName("author")]
public CommitAuthorDto Author { get; set; }
+
+ [JsonPropertyName("message")]
public string Message { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Bot/Commands/Utils/Choose.cs b/src/Bot/Commands/Utils/Choose.cs
index 731bee6..450433d 100644
--- a/src/Bot/Commands/Utils/Choose.cs
+++ b/src/Bot/Commands/Utils/Choose.cs
@@ -1,9 +1,8 @@
-using System;
-using System.Threading.Tasks;
-using Discord.Commands;
+using Discord.Commands;
using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
using Geekbot.Core.GuildSettingsManager;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Utils
{
@@ -14,7 +13,7 @@ namespace Geekbot.Bot.Commands.Utils
}
[Command("choose", RunMode = RunMode.Async)]
- [Summary("Let the bot choose for you, seperate options with a semicolon.")]
+ [Summary("Let the bot choose for you, separate options with a semicolon.")]
public async Task Command([Remainder] [Summary("option1;option2")]
string choices)
{
diff --git a/src/Bot/Commands/Utils/Corona/CoronaStats.cs b/src/Bot/Commands/Utils/Corona/CoronaStats.cs
deleted file mode 100644
index 3f9f3ea..0000000
--- a/src/Bot/Commands/Utils/Corona/CoronaStats.cs
+++ /dev/null
@@ -1,66 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using Discord;
-using Discord.Commands;
-using Geekbot.Core;
-using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.Extensions;
-
-namespace Geekbot.Bot.Commands.Utils.Corona
-{
- public class CoronaStats : ModuleBase
- {
- private readonly IErrorHandler _errorHandler;
-
- public CoronaStats(IErrorHandler errorHandler)
- {
- _errorHandler = errorHandler;
- }
-
- [Command("corona", RunMode = RunMode.Async)]
- [Summary("Get the latest worldwide corona statistics")]
- public async Task Summary()
- {
- try
- {
- var summary = await HttpAbstractions.Get(new Uri("https://api.covid19api.com/world/total"));
- var activeCases = summary.TotalConfirmed - (summary.TotalRecovered + summary.TotalDeaths);
-
- string CalculatePercentage(decimal i) => (i / summary.TotalConfirmed).ToString("#0.##%");
- var activePercent = CalculatePercentage(activeCases);
- var recoveredPercentage = CalculatePercentage(summary.TotalRecovered);
- var deathsPercentage = CalculatePercentage(summary.TotalDeaths);
-
- var numberFormat = "#,#";
- var totalFormatted = summary.TotalConfirmed.ToString(numberFormat);
- var activeFormatted = activeCases.ToString(numberFormat);
- var recoveredFormatted = summary.TotalRecovered.ToString(numberFormat);
- var deathsFormatted = summary.TotalDeaths.ToString(numberFormat);
-
- var eb = new EmbedBuilder
- {
- Author = new EmbedAuthorBuilder
- {
- Name = "Confirmed Corona Cases",
- IconUrl = "https://www.redcross.org/content/dam/icons/disasters/virus/Virus-1000x1000-R-Pl.png"
- },
- Footer = new EmbedFooterBuilder
- {
- Text = "Source: covid19api.com",
- },
- Color = Color.Red
- };
- eb.AddField("Total", totalFormatted);
- eb.AddInlineField("Active", $"{activeFormatted} ({activePercent})");
- eb.AddInlineField("Recovered", $"{recoveredFormatted} ({recoveredPercentage})");
- eb.AddInlineField("Deaths", $"{deathsFormatted} ({deathsPercentage})");
-
- await Context.Channel.SendMessageAsync(String.Empty, false, eb.Build());
- }
- catch (Exception e)
- {
- await _errorHandler.HandleCommandException(e, Context);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Utils/Corona/CoronaSummaryDto.cs b/src/Bot/Commands/Utils/Corona/CoronaSummaryDto.cs
deleted file mode 100644
index 3f6a820..0000000
--- a/src/Bot/Commands/Utils/Corona/CoronaSummaryDto.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Geekbot.Bot.Commands.Utils.Corona
-{
- public class CoronaSummaryDto
- {
- public decimal TotalConfirmed { get; set; }
- public decimal TotalDeaths { get; set; }
- public decimal TotalRecovered { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/Bot/Commands/Utils/Dice.cs b/src/Bot/Commands/Utils/Dice.cs
index 0668493..c57001f 100644
--- a/src/Bot/Commands/Utils/Dice.cs
+++ b/src/Bot/Commands/Utils/Dice.cs
@@ -3,12 +3,13 @@ using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.DiceParser;
using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Utils
{
- public class Dice : ModuleBase
+ public class Dice : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
private readonly IDiceParser _diceParser;
diff --git a/src/Bot/Commands/Utils/Emojify.cs b/src/Bot/Commands/Utils/Emojify.cs
index 8bb880e..a513710 100644
--- a/src/Bot/Commands/Utils/Emojify.cs
+++ b/src/Bot/Commands/Utils/Emojify.cs
@@ -1,20 +1,17 @@
-using System;
-using System.Threading.Tasks;
-using Discord.Commands;
+using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.Converters;
using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Utils
{
- public class Emojify : ModuleBase
+ public class Emojify : TransactionModuleBase
{
- private readonly IEmojiConverter _emojiConverter;
private readonly IErrorHandler _errorHandler;
- public Emojify(IErrorHandler errorHandler, IEmojiConverter emojiConverter)
+ public Emojify(IErrorHandler errorHandler)
{
_errorHandler = errorHandler;
- _emojiConverter = emojiConverter;
}
[Command("emojify", RunMode = RunMode.Async)]
@@ -23,7 +20,7 @@ namespace Geekbot.Bot.Commands.Utils
{
try
{
- var emojis = _emojiConverter.TextToEmoji(text);
+ var emojis = EmojiConverter.TextToEmoji(text);
if (emojis.Length > 1999)
{
await ReplyAsync("I can't take that much at once!");
diff --git a/src/Bot/Commands/Utils/Help.cs b/src/Bot/Commands/Utils/Help.cs
index 58630fe..7aa9aff 100644
--- a/src/Bot/Commands/Utils/Help.cs
+++ b/src/Bot/Commands/Utils/Help.cs
@@ -3,11 +3,12 @@ using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Utils
{
- public class Help : ModuleBase
+ public class Help : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
@@ -26,7 +27,7 @@ namespace Geekbot.Bot.Commands.Utils
sb.AppendLine("For a list of all commands, please visit the following page");
sb.AppendLine("https://geekbot.pizzaandcoffee.rocks/commands");
- var dm = await Context.User.GetOrCreateDMChannelAsync();
+ var dm = await Context.User.CreateDMChannelAsync(RequestOptions.Default);
await dm.SendMessageAsync(sb.ToString());
await Context.Message.AddReactionAsync(new Emoji("✅"));
}
diff --git a/src/Bot/Commands/Utils/Info.cs b/src/Bot/Commands/Utils/Info.cs
index 663dd07..912528d 100644
--- a/src/Bot/Commands/Utils/Info.cs
+++ b/src/Bot/Commands/Utils/Info.cs
@@ -11,7 +11,7 @@ using Geekbot.Core.Extensions;
namespace Geekbot.Bot.Commands.Utils
{
- public class Info : ModuleBase
+ public class Info : TransactionModuleBase
{
private readonly DiscordSocketClient _client;
private readonly CommandService _commands;
diff --git a/src/Bot/Commands/Utils/Lmgtfy.cs b/src/Bot/Commands/Utils/Lmgtfy.cs
index 6063cf9..76fa6fa 100644
--- a/src/Bot/Commands/Utils/Lmgtfy.cs
+++ b/src/Bot/Commands/Utils/Lmgtfy.cs
@@ -2,11 +2,12 @@ using System;
using System.Threading.Tasks;
using System.Web;
using Discord.Commands;
+using Geekbot.Core;
using Geekbot.Core.ErrorHandling;
namespace Geekbot.Bot.Commands.Utils
{
- public class Lmgtfy : ModuleBase
+ public class Lmgtfy : TransactionModuleBase
{
private readonly IErrorHandler _errorHandler;
diff --git a/src/Bot/Commands/Utils/Ping.cs b/src/Bot/Commands/Utils/Ping.cs
index d4faa53..ee751cd 100644
--- a/src/Bot/Commands/Utils/Ping.cs
+++ b/src/Bot/Commands/Utils/Ping.cs
@@ -1,9 +1,10 @@
using System.Threading.Tasks;
using Discord.Commands;
+using Geekbot.Core;
namespace Geekbot.Bot.Commands.Utils
{
- public class Ping : ModuleBase
+ public class Ping : TransactionModuleBase
{
[Command("👀", RunMode = RunMode.Async)]
[Summary("Look at the bot.")]
diff --git a/src/Bot/Commands/Utils/Quote/Quote.cs b/src/Bot/Commands/Utils/Quote/Quote.cs
index 0b197cd..243e5dd 100644
--- a/src/Bot/Commands/Utils/Quote/Quote.cs
+++ b/src/Bot/Commands/Utils/Quote/Quote.cs
@@ -4,8 +4,8 @@ using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
+using Geekbot.Bot.CommandPreconditions;
using Geekbot.Core;
-using Geekbot.Core.CommandPreconditions;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.ErrorHandling;
@@ -13,6 +13,11 @@ using Geekbot.Core.Extensions;
using Geekbot.Core.GuildSettingsManager;
using Geekbot.Core.Polyfills;
using Geekbot.Core.RandomNumberGenerator;
+using Geekbot.Core.UserRepository;
+using Microsoft.EntityFrameworkCore;
+using Sentry;
+using Constants = Geekbot.Core.Constants;
+using Localization = Geekbot.Core.Localization;
namespace Geekbot.Bot.Commands.Utils.Quote
{
@@ -22,13 +27,15 @@ namespace Geekbot.Bot.Commands.Utils.Quote
{
private readonly DatabaseContext _database;
private readonly IRandomNumberGenerator _randomNumberGenerator;
+ private readonly IUserRepository _userRepository;
private readonly bool _isDev;
- public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator, IGuildSettingsManager guildSettingsManager)
+ public Quote(IErrorHandler errorHandler, DatabaseContext database, IRandomNumberGenerator randomNumberGenerator, IGuildSettingsManager guildSettingsManager, IUserRepository userRepository)
: base(errorHandler, guildSettingsManager)
{
_database = database;
_randomNumberGenerator = randomNumberGenerator;
+ _userRepository = userRepository;
// to remove restrictions when developing
_isDev = Constants.BotVersion() == "0.0.0-DEV";
}
@@ -39,23 +46,26 @@ namespace Geekbot.Bot.Commands.Utils.Quote
{
try
{
- var totalQuotes = await _database.Quotes.CountAsync(e => e.GuildId.Equals(Context.Guild.Id.AsLong()));
-
- if (totalQuotes == 0)
+ var getQuoteFromDbSpan = Transaction.StartChild("GetQuoteFromDB");
+ var quote = _database.Quotes.FromSqlInterpolated($"select * from \"Quotes\" where \"GuildId\" = {Context.Guild.Id} order by random() limit 1");
+ getQuoteFromDbSpan.Finish();
+
+ if (!quote.Any())
{
await ReplyAsync(Localization.Quote.NoQuotesFound);
+ Transaction.Status = SpanStatus.NotFound;
return;
}
- var random = _randomNumberGenerator.Next(0, totalQuotes - 1);
- var quote = _database.Quotes.Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())).Skip(random).Take(1);
-
+ var buildQuoteEmbedSpan = Transaction.StartChild("BuildQuoteEmbed");
var embed = QuoteBuilder(quote.FirstOrDefault());
+ buildQuoteEmbedSpan.Finish();
await ReplyAsync("", false, embed.Build());
}
catch (Exception e)
{
await ErrorHandler.HandleCommandException(e, Context, "Whoops, seems like the quote was to edgy to return");
+ Transaction.Status = SpanStatus.InternalError;
}
}
@@ -74,22 +84,6 @@ namespace Geekbot.Bot.Commands.Utils.Quote
{
await QuoteFromMention(user, false);
}
-
- [Command("add")]
- [Alias("save")]
- [Summary("Add a quote from a message id")]
- public async Task AddQuote([Summary("message-ID")] ulong messageId)
- {
- await QuoteFromMessageId(messageId, true);
- }
-
- [Command("make")]
- [Alias("preview")]
- [Summary("Preview a quote from a message id")]
- public async Task ReturnSpecifiedQuote([Summary("message-ID")] ulong messageId)
- {
- await QuoteFromMessageId(messageId, false);
- }
[Command("add")]
[Alias("save")]
@@ -160,8 +154,8 @@ namespace Geekbot.Bot.Commands.Utils.Quote
.Where(row => row.GuildId == Context.Guild.Id.AsLong())
.GroupBy(row => row.UserId)
.Select(row => new { userId = row.Key, amount = row.Count()})
- .OrderBy(row => row.amount)
- .Last();
+ .OrderByDescending(row => row.amount)
+ .First();
var mostQuotedPersonUser = Context.Client.GetUserAsync(mostQuotedPerson.userId.AsUlong()).Result ?? new UserPolyfillDto {Username = "Unknown User"};
var quotesByYear = _database.Quotes
@@ -208,21 +202,7 @@ namespace Geekbot.Bot.Commands.Utils.Quote
}
- private async Task QuoteFromMessageId(ulong messageId, bool saveToDb)
- {
- try
- {
- var message = await Context.Channel.GetMessageAsync(messageId);
-
- await ProcessQuote(message, saveToDb, true);
- }
- catch (Exception e)
- {
- await ErrorHandler.HandleCommandException(e, Context, "I couldn't find a message with that id :disappointed:");
- }
- }
-
- private async Task QuoteFromMessageLink(string messageLink, bool saveToDb)
+ private async Task QuoteFromMessageLink(string messageLink, bool saveToDb)
{
try
{
@@ -253,7 +233,7 @@ namespace Geekbot.Bot.Commands.Utils.Quote
}
}
- private async Task ProcessQuote(IMessage message, bool saveToDb, bool showMessageIdWarning = false)
+ private async Task ProcessQuote(IMessage message, bool saveToDb)
{
if (message.Author.Id == Context.Message.Author.Id && saveToDb && !_isDev)
{
@@ -278,27 +258,38 @@ namespace Geekbot.Bot.Commands.Utils.Quote
var sb = new StringBuilder();
if (saveToDb) sb.AppendLine(Localization.Quote.QuoteAdded);
- if (showMessageIdWarning) sb.AppendLine(Localization.Quote.MessageIdDeprecation);
await ReplyAsync(sb.ToString(), false, embed.Build());
}
private EmbedBuilder QuoteBuilder(QuoteModel quote)
{
- var user = Context.Client.GetUserAsync(quote.UserId.AsUlong()).Result ?? new UserPolyfillDto { Username = "Unknown User" };
+ var getEmbedUserSpan = Transaction.StartChild("GetEmbedUser");
+ var user = Context.Client.GetUserAsync(quote.UserId.AsUlong()).Result;
+ if (user == null)
+ {
+ var getEmbedUserFromRepoSpan = Transaction.StartChild("GetEmbedUserFromRepo");
+ var fallbackUserFromRepo = _userRepository.Get(quote.UserId.AsUlong());
+ user = new UserPolyfillDto()
+ {
+ Username = fallbackUserFromRepo?.Username ?? "Unknown User",
+ AvatarUrl = fallbackUserFromRepo?.AvatarUrl
+ };
+ getEmbedUserFromRepoSpan.Finish();
+ }
+ getEmbedUserSpan.Finish();
+
+ var embedBuilderSpan = Transaction.StartChild("EmbedBuilder");
var eb = new EmbedBuilder();
eb.WithColor(new Color(143, 167, 232));
- if (quote.InternalId == 0)
- {
- eb.Title = $"{user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}";
- }
- else
- {
- eb.Title = $"#{quote.InternalId} | {user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}";
- }
+ eb.Title = quote.InternalId == 0
+ ? $"{user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}"
+ : $"#{quote.InternalId} | {user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}";
eb.Description = quote.Quote;
eb.ThumbnailUrl = user.GetAvatarUrl();
if (quote.Image != null) eb.ImageUrl = quote.Image;
+ embedBuilderSpan.Finish();
+
return eb;
}
@@ -322,7 +313,7 @@ namespace Geekbot.Bot.Commands.Utils.Quote
InternalId = internalId,
GuildId = Context.Guild.Id.AsLong(),
UserId = message.Author.Id.AsLong(),
- Time = message.Timestamp.DateTime,
+ Time = message.Timestamp.DateTime.ToUniversalTime(),
Quote = message.Content,
Image = image
};
diff --git a/src/Bot/Handlers/CommandHandler.cs b/src/Bot/Handlers/CommandHandler.cs
index 52e9a52..19d4edd 100644
--- a/src/Bot/Handlers/CommandHandler.cs
+++ b/src/Bot/Handlers/CommandHandler.cs
@@ -21,12 +21,10 @@ namespace Geekbot.Bot.Handlers
private readonly RestApplication _applicationInfo;
private readonly IGuildSettingsManager _guildSettingsManager;
private readonly List _ignoredServers;
- private readonly DatabaseContext _database;
- public CommandHandler(DatabaseContext database, IDiscordClient client, IGeekbotLogger logger, IServiceProvider servicesProvider, CommandService commands, RestApplication applicationInfo,
+ public CommandHandler(IDiscordClient client, IGeekbotLogger logger, IServiceProvider servicesProvider, CommandService commands, RestApplication applicationInfo,
IGuildSettingsManager guildSettingsManager)
{
- _database = database;
_client = client;
_logger = logger;
_servicesProvider = servicesProvider;
@@ -39,7 +37,7 @@ namespace Geekbot.Bot.Handlers
_ignoredServers = new List
{
228623803201224704, // SwitzerLAN
- 169844523181015040, // EEvent
+ // 169844523181015040, // EEvent
248531441548263425, // MYI
110373943822540800 // Discord Bots
};
diff --git a/src/Bot/Handlers/MessageDeletedHandler.cs b/src/Bot/Handlers/MessageDeletedHandler.cs
index d0377f7..b8ffe5c 100644
--- a/src/Bot/Handlers/MessageDeletedHandler.cs
+++ b/src/Bot/Handlers/MessageDeletedHandler.cs
@@ -23,11 +23,11 @@ namespace Geekbot.Bot.Handlers
_client = client;
}
- public async Task HandleMessageDeleted(Cacheable message, ISocketMessageChannel channel)
+ public async Task HandleMessageDeleted(Cacheable message, Cacheable cacheableMessageChannel)
{
try
{
- var guildSocketData = ((IGuildChannel) channel).Guild;
+ var guildSocketData = ((IGuildChannel) cacheableMessageChannel.Value).Guild;
var guild = _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(guildSocketData.Id.AsLong()));
if ((guild?.ShowDelete ?? false) && guild?.ModChannel != 0)
{
@@ -35,7 +35,7 @@ namespace Geekbot.Bot.Handlers
var sb = new StringBuilder();
if (message.Value != null)
{
- sb.AppendLine($"The following message from {message.Value.Author.Username}#{message.Value.Author.Discriminator} was deleted in <#{channel.Id}>");
+ sb.AppendLine($"The following message from {message.Value.Author.Username}#{message.Value.Author.Discriminator} was deleted in <#{cacheableMessageChannel.Id}>");
sb.AppendLine(message.Value.Content);
}
else
diff --git a/src/Bot/Handlers/ReactionHandler.cs b/src/Bot/Handlers/ReactionHandler.cs
index 66af3e8..816e125 100644
--- a/src/Bot/Handlers/ReactionHandler.cs
+++ b/src/Bot/Handlers/ReactionHandler.cs
@@ -14,19 +14,19 @@ namespace Geekbot.Bot.Handlers
_reactionListener = reactionListener;
}
- public Task Added(Cacheable cacheable, ISocketMessageChannel socketMessageChannel, SocketReaction reaction)
+ public Task Added(Cacheable cacheableUserMessage, Cacheable cacheableMessageChannel, SocketReaction reaction)
{
if (reaction.User.Value.IsBot) return Task.CompletedTask;
if (!_reactionListener.IsListener(reaction.MessageId)) return Task.CompletedTask;
- _reactionListener.GiveRole(socketMessageChannel, reaction);
+ _reactionListener.GiveRole(cacheableMessageChannel.Value, reaction);
return Task.CompletedTask;
}
- public Task Removed(Cacheable cacheable, ISocketMessageChannel socketMessageChannel, SocketReaction reaction)
+ public Task Removed(Cacheable cacheableUserMessage, Cacheable cacheableMessageChannel, SocketReaction reaction)
{
if (reaction.User.Value.IsBot) return Task.CompletedTask;
if (!_reactionListener.IsListener(reaction.MessageId)) return Task.CompletedTask;
- _reactionListener.RemoveRole(socketMessageChannel, reaction);
+ _reactionListener.RemoveRole(cacheableMessageChannel.Value, reaction);
return Task.CompletedTask;
}
}
diff --git a/src/Bot/Handlers/StatsHandler.cs b/src/Bot/Handlers/StatsHandler.cs
index 197bbb8..b089515 100644
--- a/src/Bot/Handlers/StatsHandler.cs
+++ b/src/Bot/Handlers/StatsHandler.cs
@@ -4,6 +4,7 @@ using Discord.WebSocket;
using Geekbot.Core.Database;
using Geekbot.Core.Database.Models;
using Geekbot.Core.Extensions;
+using Geekbot.Core.Highscores;
using Geekbot.Core.Logger;
using Microsoft.EntityFrameworkCore;
@@ -13,11 +14,26 @@ namespace Geekbot.Bot.Handlers
{
private readonly IGeekbotLogger _logger;
private readonly DatabaseContext _database;
+ private string _season;
public StatsHandler(IGeekbotLogger logger, DatabaseContext database)
{
_logger = logger;
_database = database;
+ _season = SeasonsUtils.GetCurrentSeason();
+
+ var timer = new System.Timers.Timer()
+ {
+ Enabled = true,
+ AutoReset = true,
+ Interval = TimeSpan.FromMinutes(5).TotalMilliseconds
+ };
+ timer.Elapsed += (sender, args) =>
+ {
+ var current = SeasonsUtils.GetCurrentSeason();
+ if (current == _season) return;
+ _season = SeasonsUtils.GetCurrentSeason();
+ };
}
public async Task UpdateStats(SocketMessage message)
@@ -33,22 +49,16 @@ namespace Geekbot.Bot.Handlers
var channel = (SocketGuildChannel) message.Channel;
- var rowId = await _database.Database.ExecuteSqlRawAsync(
- "UPDATE \"Messages\" SET \"MessageCount\" = \"MessageCount\" + 1 WHERE \"GuildId\" = {0} AND \"UserId\" = {1}",
- channel.Guild.Id.AsLong(),
- message.Author.Id.AsLong()
- );
-
- if (rowId == 0)
+ // ignore the discord bots server
+ // ToDo: create a clean solution for this...
+ if (channel.Guild.Id == 110373943822540800)
{
- await _database.Messages.AddAsync(new MessagesModel
- {
- UserId = message.Author.Id.AsLong(),
- GuildId = channel.Guild.Id.AsLong(),
- MessageCount = 1
- });
- await _database.SaveChangesAsync();
+ return;
}
+
+ await UpdateTotalTable(message, channel);
+ await UpdateSeasonsTable(message, channel);
+
if (message.Author.IsBot) return;
_logger.Information(LogSource.Message, message.Content, SimpleConextConverter.ConvertSocketMessage(message));
@@ -58,5 +68,47 @@ namespace Geekbot.Bot.Handlers
_logger.Error(LogSource.Message, "Could not process message stats", e);
}
}
+
+ private async Task UpdateTotalTable(SocketMessage message, SocketGuildChannel channel)
+ {
+ var rowId = await _database.Database.ExecuteSqlRawAsync(
+ "UPDATE \"Messages\" SET \"MessageCount\" = \"MessageCount\" + 1 WHERE \"GuildId\" = {0} AND \"UserId\" = {1}",
+ channel.Guild.Id.AsLong(),
+ message.Author.Id.AsLong()
+ );
+
+ if (rowId == 0)
+ {
+ await _database.Messages.AddAsync(new MessagesModel
+ {
+ UserId = message.Author.Id.AsLong(),
+ GuildId = channel.Guild.Id.AsLong(),
+ MessageCount = 1
+ });
+ await _database.SaveChangesAsync();
+ }
+ }
+
+ private async Task UpdateSeasonsTable(SocketMessage message, SocketGuildChannel channel)
+ {
+ var rowId = await _database.Database.ExecuteSqlRawAsync(
+ "UPDATE \"MessagesSeasons\" SET \"MessageCount\" = \"MessageCount\" + 1 WHERE \"GuildId\" = {0} AND \"UserId\" = {1} AND \"Season\" = {2}",
+ channel.Guild.Id.AsLong(),
+ message.Author.Id.AsLong(),
+ _season
+ );
+
+ if (rowId == 0)
+ {
+ await _database.MessagesSeasons.AddAsync(new MessageSeasonsModel()
+ {
+ UserId = message.Author.Id.AsLong(),
+ GuildId = channel.Guild.Id.AsLong(),
+ Season = _season,
+ MessageCount = 1
+ });
+ await _database.SaveChangesAsync();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Bot/Handlers/UserHandler.cs b/src/Bot/Handlers/UserHandler.cs
index a22d0e1..1f58131 100644
--- a/src/Bot/Handlers/UserHandler.cs
+++ b/src/Bot/Handlers/UserHandler.cs
@@ -74,15 +74,15 @@ namespace Geekbot.Bot.Handlers
await _userRepository.Update(newUser);
}
- public async Task Left(SocketGuildUser user)
+ public async Task Left(SocketGuild socketGuild, SocketUser socketUser)
{
try
{
- var guild = _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(user.Guild.Id.AsLong()));
+ var guild = _database.GuildSettings.FirstOrDefault(g => g.GuildId.Equals(socketGuild.Id.AsLong()));
if (guild?.ShowLeave ?? false)
{
var modChannelSocket = (ISocketMessageChannel) await _client.GetChannelAsync(guild.ModChannel.AsUlong());
- await modChannelSocket.SendMessageAsync($"{user.Username}#{user.Discriminator} left the server");
+ await modChannelSocket.SendMessageAsync($"{socketUser.Username}#{socketUser.Discriminator} left the server");
}
}
catch (Exception e)
@@ -90,7 +90,7 @@ namespace Geekbot.Bot.Handlers
_logger.Error(LogSource.Geekbot, "Failed to send leave message", e);
}
- _logger.Information(LogSource.Geekbot, $"{user.Username} ({user.Id}) joined {user.Guild.Name} ({user.Guild.Id})");
+ _logger.Information(LogSource.Geekbot, $"{socketUser.Username} ({socketUser.Id}) joined {socketGuild.Name} ({socketGuild.Id})");
}
}
}
\ No newline at end of file
diff --git a/src/Bot/Program.cs b/src/Bot/Program.cs
deleted file mode 100644
index dee6ec3..0000000
--- a/src/Bot/Program.cs
+++ /dev/null
@@ -1,228 +0,0 @@
-using System;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using CommandLine;
-using Discord;
-using Discord.Commands;
-using Discord.WebSocket;
-using Geekbot.Bot.Handlers;
-using Geekbot.Core;
-using Geekbot.Core.Converters;
-using Geekbot.Core.Database;
-using Geekbot.Core.DiceParser;
-using Geekbot.Core.ErrorHandling;
-using Geekbot.Core.GlobalSettings;
-using Geekbot.Core.GuildSettingsManager;
-using Geekbot.Core.Highscores;
-using Geekbot.Core.KvInMemoryStore;
-using Geekbot.Core.Levels;
-using Geekbot.Core.Logger;
-using Geekbot.Core.Media;
-using Geekbot.Core.RandomNumberGenerator;
-using Geekbot.Core.ReactionListener;
-using Geekbot.Core.UserRepository;
-using Geekbot.Core.WikipediaClient;
-using Geekbot.Web;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
-
-namespace Geekbot.Bot
-{
- internal class Program
- {
- private DiscordSocketClient _client;
- private CommandService _commands;
- private DatabaseInitializer _databaseInitializer;
- private IGlobalSettings _globalSettings;
- private IServiceProvider _servicesProvider;
- private GeekbotLogger _logger;
- private IUserRepository _userRepository;
- private RunParameters _runParameters;
- private IReactionListener _reactionListener;
- private IGuildSettingsManager _guildSettingsManager;
-
- private static async Task Main(string[] args)
- {
- RunParameters runParameters = null;
- Parser.Default.ParseArguments(args)
- .WithParsed(e => runParameters = e)
- .WithNotParsed(_ => Environment.Exit(GeekbotExitCode.InvalidArguments.GetHashCode()));
-
- var logo = new StringBuilder();
- logo.AppendLine(@" ____ _____ _____ _ ______ ___ _____");
- logo.AppendLine(@" / ___| ____| ____| |/ / __ ) / _ \\_ _|");
- logo.AppendLine(@"| | _| _| | _| | ' /| _ \| | | || |");
- logo.AppendLine(@"| |_| | |___| |___| . \| |_) | |_| || |");
- logo.AppendLine(@" \____|_____|_____|_|\_\____/ \___/ |_|");
- logo.AppendLine($"Version {Constants.BotVersion()} ".PadRight(41, '='));
- Console.WriteLine(logo.ToString());
- var logger = new GeekbotLogger(runParameters);
- logger.Information(LogSource.Geekbot, "Starting...");
- try
- {
- await new Program().Start(runParameters, logger);
- }
- catch (Exception e)
- {
- logger.Error(LogSource.Geekbot, "RIP", e);
- }
- }
-
- private async Task Start(RunParameters runParameters, GeekbotLogger logger)
- {
- _logger = logger;
- _runParameters = runParameters;
-
- logger.Information(LogSource.Geekbot, "Connecting to Database");
- var database = ConnectToDatabase();
- _globalSettings = new GlobalSettings(database);
-
- logger.Information(LogSource.Geekbot, "Connecting to Discord");
- SetupDiscordClient();
- await Login();
- _logger.Information(LogSource.Geekbot, $"Now Connected as {_client.CurrentUser.Username} to {_client.Guilds.Count} Servers");
- await _client.SetGameAsync(_globalSettings.GetKey("Game"));
-
- _logger.Information(LogSource.Geekbot, "Loading Dependencies and Handlers");
- RegisterDependencies();
- await RegisterHandlers();
-
- _logger.Information(LogSource.Api, "Starting Web API");
- StartWebApi();
-
- _logger.Information(LogSource.Geekbot, "Done and ready for use");
-
- await Task.Delay(-1);
- }
-
- private async Task Login()
- {
- try
- {
- var token = await GetToken();
- await _client.LoginAsync(TokenType.Bot, token);
- await _client.StartAsync();
- while (!_client.ConnectionState.Equals(ConnectionState.Connected)) await Task.Delay(25);
- }
- catch (Exception e)
- {
- _logger.Error(LogSource.Geekbot, "Could not connect to Discord", e);
- Environment.Exit(GeekbotExitCode.CouldNotLogin.GetHashCode());
- }
- }
-
- private DatabaseContext ConnectToDatabase()
- {
- _databaseInitializer = new DatabaseInitializer(_runParameters, _logger);
- var database = _databaseInitializer.Initialize();
- database.Database.EnsureCreated();
- if(!_runParameters.InMemory) database.Database.Migrate();
-
- return database;
- }
-
- private async Task GetToken()
- {
- var token = _runParameters.Token ?? _globalSettings.GetKey("DiscordToken");
- if (string.IsNullOrEmpty(token))
- {
- Console.Write("Your bot Token: ");
- var newToken = Console.ReadLine();
- await _globalSettings.SetKey("DiscordToken", newToken);
- await _globalSettings.SetKey("Game", "Ping Pong");
- token = newToken;
- }
-
- return token;
- }
-
- private void SetupDiscordClient()
- {
- _client = new DiscordSocketClient(new DiscordSocketConfig
- {
- LogLevel = LogSeverity.Verbose,
- MessageCacheSize = 1000,
- ExclusiveBulkDelete = true
- });
-
- var discordLogger = new DiscordLogger(_logger);
- _client.Log += discordLogger.Log;
- }
-
- private void RegisterDependencies()
- {
- var services = new ServiceCollection();
-
- _userRepository = new UserRepository(_databaseInitializer.Initialize(), _logger);
- _reactionListener = new ReactionListener(_databaseInitializer.Initialize());
- _guildSettingsManager = new GuildSettingsManager(_databaseInitializer.Initialize());
- var fortunes = new FortunesProvider(_logger);
- var levelCalc = new LevelCalc();
- var emojiConverter = new EmojiConverter();
- var mtgManaConverter = new MtgManaConverter();
- var wikipediaClient = new WikipediaClient();
- var randomNumberGenerator = new RandomNumberGenerator(_globalSettings);
- var mediaProvider = new MediaProvider(_logger, randomNumberGenerator);
- var kvMemoryStore = new KvInInMemoryStore();
- var errorHandler = new ErrorHandler(_logger, _runParameters, () => Localization.Internal.SomethingWentWrong);
- var diceParser = new DiceParser(randomNumberGenerator);
-
- services.AddSingleton(_userRepository);
- services.AddSingleton(_logger);
- services.AddSingleton(levelCalc);
- services.AddSingleton(emojiConverter);
- services.AddSingleton(fortunes);
- services.AddSingleton(mediaProvider);
- services.AddSingleton(mtgManaConverter);
- services.AddSingleton(wikipediaClient);
- services.AddSingleton(randomNumberGenerator);
- services.AddSingleton(kvMemoryStore);
- services.AddSingleton(_globalSettings);
- services.AddSingleton(errorHandler);
- services.AddSingleton(diceParser);
- services.AddSingleton(_reactionListener);
- services.AddSingleton(_guildSettingsManager);
- services.AddSingleton(_client);
- services.AddTransient(e => new HighscoreManager(_databaseInitializer.Initialize(), _userRepository));
- services.AddTransient(e => _databaseInitializer.Initialize());
-
- _servicesProvider = services.BuildServiceProvider();
- }
-
- private async Task RegisterHandlers()
- {
- var applicationInfo = await _client.GetApplicationInfoAsync();
-
- _commands = new CommandService();
- await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _servicesProvider);
-
- var commandHandler = new CommandHandler(_databaseInitializer.Initialize(), _client, _logger, _servicesProvider, _commands, applicationInfo, _guildSettingsManager);
- var userHandler = new UserHandler(_userRepository, _logger, _databaseInitializer.Initialize(), _client);
- var reactionHandler = new ReactionHandler(_reactionListener);
- var statsHandler = new StatsHandler(_logger, _databaseInitializer.Initialize());
- var messageDeletedHandler = new MessageDeletedHandler(_databaseInitializer.Initialize(), _logger, _client);
-
- _client.MessageReceived += commandHandler.RunCommand;
- _client.MessageDeleted += messageDeletedHandler.HandleMessageDeleted;
- _client.UserJoined += userHandler.Joined;
- _client.UserUpdated += userHandler.Updated;
- _client.UserLeft += userHandler.Left;
- _client.ReactionAdded += reactionHandler.Added;
- _client.ReactionRemoved += reactionHandler.Removed;
- if (!_runParameters.InMemory) _client.MessageReceived += statsHandler.UpdateStats;
- }
-
- private void StartWebApi()
- {
- if (_runParameters.DisableApi)
- {
- _logger.Warning(LogSource.Api, "Web API is disabled");
- return;
- }
-
- var highscoreManager = new HighscoreManager(_databaseInitializer.Initialize(), _userRepository);
- WebApiStartup.StartWebApi(_logger, _runParameters, _commands, _databaseInitializer.Initialize(), _client, _globalSettings, highscoreManager);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Commands/Commands.csproj b/src/Commands/Commands.csproj
new file mode 100644
index 0000000..7f0bd8f
--- /dev/null
+++ b/src/Commands/Commands.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net6.0
+ $(VersionSuffix)
+ $(VersionSuffix)
+ 0.0.0-DEV
+ Geekbot.Commands
+ Geekbot.Commands
+ NU1701
+ CS8618
+ enable
+ enable
+ True
+ Library
+
+
+
+
+
+
+
+
diff --git a/src/Commands/Karma/Karma.cs b/src/Commands/Karma/Karma.cs
new file mode 100644
index 0000000..026af2f
--- /dev/null
+++ b/src/Commands/Karma/Karma.cs
@@ -0,0 +1,103 @@
+using System.Drawing;
+using Geekbot.Core;
+using Geekbot.Core.Database;
+using Geekbot.Core.Database.Models;
+using Geekbot.Interactions.Embed;
+using Geekbot.Interactions.Resolved;
+using Localization = Geekbot.Core.Localization;
+
+namespace Geekbot.Commands.Karma;
+
+public class Karma
+{
+ private readonly DatabaseContext _database;
+ private readonly long _guildId;
+
+ public Karma(DatabaseContext database, long guildId)
+ {
+ _database = database;
+ _guildId = guildId;
+ }
+
+ public async Task