diff --git a/.gitignore b/.gitignore
index 1ea847e7..f6f24756 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,6 @@
-# Created by https://www.gitignore.io/api/visualstudio
-# Edit at https://www.gitignore.io/?templates=visualstudio
+# Created by https://www.toptal.com/developers/gitignore/api/visualstudio
+# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudio
### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
@@ -34,6 +34,7 @@ bld/
[Bb]in/
[Oo]bj/
[Ll]og/
+[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
@@ -73,6 +74,7 @@ StyleCopReport.xml
*_p.c
*_h.h
*.ilk
+*.meta
*.obj
*.iobj
*.pch
@@ -130,9 +132,6 @@ _ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
-# JustCode is a .NET coding add-in
-.JustCode
-
# TeamCity is a build add-in
_TeamCity*
@@ -143,6 +142,9 @@ _TeamCity*
.axoCover/*
!.axoCover/settings.json
+# Coverlet is a free, cross platform Code Coverage Tool
+coverage*[.json, .xml, .info]
+
# Visual Studio code coverage results
*.coverage
*.coveragexml
@@ -352,4 +354,8 @@ healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
-# End of https://www.gitignore.io/api/visualstudio
\ No newline at end of file
+# Ionide (cross platform F# VS Code tools) working folder
+.ionide/
+
+# End of https://www.toptal.com/developers/gitignore/api/visualstudio
+src/FlawBOT/Lavalink.jar
diff --git a/README.md b/README.md
index dc2076d7..26efa32a 100644
--- a/README.md
+++ b/README.md
@@ -13,11 +13,12 @@ To run your own instance of FlawBOT, [clone this repository](https://github.com/
## API Tokens
* [Discord](https://discordapp.com/developers/applications/me) (*required*)
-* [Google](https://console.cloud.google.com/projectselector/apis/credentials) (*YouTube, Geological Data*)
* [Steam](https://steamcommunity.com/dev/apikey)
* [Imgur](https://api.imgur.com/oauth2/addclient)
* [OMDB](http://www.omdbapi.com/apikey.aspx)
* [Twitch](https://dev.twitch.tv/dashboard/apps/create)
* [NASA](https://api.nasa.gov/)
-* [Teamwork.TF](https://teamwork.tf/api)
-* [News API](https://newsapi.org/)
\ No newline at end of file
+* [Teamwork.TF](https://github.com/teamworktf/website_api)
+* [News API](https://newsapi.org/)
+* [WeatherStack](https://weatherstack.com/)
+* [YouTube](https://console.cloud.google.com/projectselector/apis/credentials)
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Common/SharedData.cs b/src/FlawBOT.Core/Common/SharedData.cs
deleted file mode 100644
index db0aece8..00000000
--- a/src/FlawBOT.Core/Common/SharedData.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using DSharpPlus.Entities;
-using System;
-using System.Reflection;
-
-namespace FlawBOT.Common
-{
- public class SharedData
- {
- public static string Name { get; } = "FlawBOT";
- public static string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version?.ToString();
- public static string GitHubLink { get; set; } = "https://github.com/CriticalFlaw/FlawBOT/";
- public static string InviteLink { get; } = "https://discordapp.com/oauth2/authorize?client_id=339833029013012483&scope=bot&permissions=66186303";
- public static DiscordColor DefaultColor { get; set; } = new DiscordColor("#00FF7F");
- public static DateTime ProcessStarted { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/FlawBOT.Core.csproj b/src/FlawBOT.Core/FlawBOT.Core.csproj
deleted file mode 100644
index 3e6b6d3d..00000000
--- a/src/FlawBOT.Core/FlawBOT.Core.csproj
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
- Exe
- netcoreapp3.1
- icon.ico
- FlawBOT.Program
- false
- 2.6.1
-
- 7.2
- 2.6.1.0
- 2.6.1.0
- FlawBOT.Core
- FlawBOT.Core
-
- Multipurpose Discord bot written in C# using DSharpPlus. Application Core.
- https://top.gg/bot/339833029013012483
- https://github.com/CriticalFlaw/FlawBOT
-
- CriticalFlaw
- FlawBOT
- Igor Nikitin
- en-CA
-
-
-
- false
- AnyCPU
-
-
-
-
-
-
-
-
- PreserveNewest
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ..\FlawBOT.Framework\Resources\PokemonTcgSdk.dll
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
diff --git a/src/FlawBOT.Core/FlawBOT.cs b/src/FlawBOT.Core/FlawBOT.cs
deleted file mode 100644
index 8ff20a7d..00000000
--- a/src/FlawBOT.Core/FlawBOT.cs
+++ /dev/null
@@ -1,266 +0,0 @@
-using System;
-using System.IO;
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.CommandsNext.Exceptions;
-using DSharpPlus.Entities;
-using DSharpPlus.EventArgs;
-using DSharpPlus.Interactivity;
-using DSharpPlus.Interactivity.Enums;
-using DSharpPlus.Lavalink;
-using DSharpPlus.VoiceNext;
-using FlawBOT.Common;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-using FlawBOT.Modules;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-
-namespace FlawBOT
-{
- internal sealed class FlawBOT
- {
- internal static EventId EventId { get; } = new EventId(1000, "FlawBot");
- public DiscordClient Client { get; set; }
- private CommandsNextExtension Commands { get; }
- private InteractivityExtension Interactivity { get; }
- private VoiceNextExtension Voice { get; }
- private LavalinkExtension LavaLink { get; }
-
- public FlawBOT(int shardId = 0)
- {
- var depot = new ServiceCollection();
-
- // Setup Client
- Client = new DiscordClient(new DiscordConfiguration
- {
- Token = TokenHandler.Tokens.DiscordToken,
- TokenType = TokenType.Bot,
- AutoReconnect = true,
- MinimumLogLevel = LogLevel.Information,
- GatewayCompressionLevel = GatewayCompressionLevel.Stream,
- LargeThreshold = 250,
- MessageCacheSize = 2048,
- LogTimestampFormat = "yyyy-MM-dd HH:mm:ss zzz",
- ShardId = shardId,
- //ShardCount = 0
- });
- Client.Ready += Client_Ready;
- //Client.GuildAvailable += Client_GuildAvailable;
- Client.ClientErrored += Client_Error;
- //Client.SocketErrored += Client_SocketError;
- //Client.GuildCreated += Client_GuildCreated;
- //Client.VoiceStateUpdated += Client_VoiceStateUpdated;
- //Client.GuildDownloadCompleted += Client_GuildDownloadCompleted;
- //Client.GuildUpdated += Client_GuildUpdated;
- //Client.ChannelDeleted += Client_ChannelDeleted;
-
- // Setup Commands
- Commands = Client.UseCommandsNext(new CommandsNextConfiguration
- {
- PrefixResolver = PrefixResolverAsync, // Set the command prefix that will be used by the bot
- EnableDms = false, // Set the boolean for responding to direct messages
- EnableMentionPrefix = true, // Set the boolean for mentioning the bot as a command prefix
- CaseSensitive = false,
- //StringPrefixes = null,
- //Services = depot.BuildServiceProvider(true),
- //IgnoreExtraArguments = false,
- //UseDefaultCommandHandler = false
- });
- Commands.CommandExecuted += Commands_Executed;
- Commands.CommandErrored += Commands_Error;
- Commands.SetHelpFormatter();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
- Commands.RegisterCommands();
-
- // Setup Interactivity
- Interactivity = Client.UseInteractivity(new InteractivityConfiguration
- {
- PaginationBehaviour = PaginationBehaviour.Ignore,
- Timeout = TimeSpan.FromMinutes(2)
- });
-
- // Setup Voice
- Voice = Client.UseVoiceNext(new VoiceNextConfiguration
- {
- AudioFormat = AudioFormat.Default,
- EnableIncoming = false
- });
-
- // Setup LavaLink
- LavaLink = Client.UseLavalink();
-
- // Start the uptime counter
- Console.Title = $"{SharedData.Name}-{SharedData.Version}";
- SharedData.ProcessStarted = DateTime.Now;
- }
-
- public async Task RunAsync()
- {
- // Update any other services that are being used.
- await TeamFortressService.UpdateTf2SchemaAsync().ConfigureAwait(false);
- await PokemonService.UpdatePokemonListAsync().ConfigureAwait(false);
-
- // Set the initial activity and connect the bot to Discord
- var act = new DiscordActivity("Night of Fire", ActivityType.ListeningTo);
- await Client.ConnectAsync(act, UserStatus.DoNotDisturb).ConfigureAwait(false);
- }
-
- public async Task StopAsync()
- {
- await Client.DisconnectAsync().ConfigureAwait(false);
- }
-
- private Task Client_Ready(DiscordClient sender, ReadyEventArgs e)
- {
- sender.Logger.LogInformation(EventId, $"{SharedData.Name}, version: {SharedData.Version}");
- return Task.CompletedTask;
- }
-
- private Task Client_Error(DiscordClient sender, ClientErrorEventArgs e)
- {
- sender.Logger.LogError(EventId, $"Exception occurred: {e.Exception.GetType()}: {e.Exception.Message}");
- return Task.CompletedTask;
- }
-
- private Task Commands_Executed(CommandsNextExtension sender, CommandExecutionEventArgs e)
- {
- e.Context.Client.Logger.LogInformation(EventId, $"'{e.Command.QualifiedName}' executed by {e.Context.User.Username} from {e.Context.Guild.Name} : {e.Context.Channel.Name}");
- return Task.CompletedTask;
- }
-
- private async Task Commands_Error(CommandsNextExtension sender, CommandErrorEventArgs e)
- {
- if (e.Exception is CommandNotFoundException && (e.Command == null || e.Command.QualifiedName != "help")) return;
-
- e.Context.Client.Logger.LogError(EventId, e.Exception, "Exception occurred during {0}'s invocation of '{1}'", e.Context.User.Username, e.Context.Command.QualifiedName);
-
- // TO-DO: Refactor this error handler.
- switch (e.Exception)
- {
- case ChecksFailedException cfe:
- switch (cfe.FailedChecks[0])
- {
- case CooldownAttribute _:
- return;
-
- default:
- await BotServices.SendEmbedAsync(e.Context,
- $"Command **{e.Command.QualifiedName}** could not be executed.", EmbedType.Error)
- .ConfigureAwait(false);
- foreach (var check in cfe.FailedChecks)
- switch (check)
- {
- case RequirePermissionsAttribute perms:
- await BotServices.SendEmbedAsync(e.Context,
- $"- One of us does not have the required permissions ({perms.Permissions.ToPermissionString()})!",
- EmbedType.Error).ConfigureAwait(false);
- break;
-
- case RequireUserPermissionsAttribute perms:
- await BotServices.SendEmbedAsync(e.Context,
- $"- You do not have sufficient permissions ({perms.Permissions.ToPermissionString()})!",
- EmbedType.Error).ConfigureAwait(false);
- break;
-
- case RequireBotPermissionsAttribute perms:
- await BotServices.SendEmbedAsync(e.Context,
- $"- I do not have sufficient permissions ({perms.Permissions.ToPermissionString()})!",
- EmbedType.Error).ConfigureAwait(false);
- break;
-
- case RequireOwnerAttribute _:
- await BotServices.SendEmbedAsync(e.Context,
- "- This command is reserved only for the bot owner.", EmbedType.Error)
- .ConfigureAwait(false);
- break;
-
- case RequirePrefixesAttribute pa:
- await BotServices.SendEmbedAsync(e.Context,
- $"- This command can only be invoked with the following prefixes: {string.Join(" ", pa.Prefixes)}.",
- EmbedType.Error).ConfigureAwait(false);
- break;
-
- default:
- await BotServices.SendEmbedAsync(e.Context,
- "Unknown check triggered. Please notify the developer using the command *.bot report*",
- EmbedType.Error).ConfigureAwait(false);
- break;
- }
-
- break;
- }
-
- break;
-
- case CommandNotFoundException _:
- //await BotServices.SendEmbedAsync(e.Context, "This command does not exist!", EmbedType.Error);
- break;
-
- case NullReferenceException _:
- //await BotServices.SendEmbedAsync(e.Context, Resources.NOT_FOUND_GENERIC, EmbedType.Missing);
- break;
-
- case ArgumentNullException _:
- await BotServices
- .SendEmbedAsync(e.Context, "Not enough arguments supplied to the command!", EmbedType.Error)
- .ConfigureAwait(false);
- break;
-
- case ArgumentException _:
- if (e.Exception.Message.Contains("Not enough arguments supplied to the command"))
- await BotServices
- .SendEmbedAsync(e.Context, "Not enough arguments supplied to the command!", EmbedType.Error)
- .ConfigureAwait(false);
- break;
-
- case InvalidDataException _:
- if (e.Exception.Message.Contains("The data within the stream was not valid image data"))
- await BotServices
- .SendEmbedAsync(e.Context, "Provided URL is not an image type!", EmbedType.Error)
- .ConfigureAwait(false);
- break;
-
- default:
- if (e.Exception.Message.Contains("Given emote was not found"))
- await BotServices.SendEmbedAsync(e.Context, "Suggested emote was not found!", EmbedType.Error)
- .ConfigureAwait(false);
- if (e.Exception.Message.Contains("Unauthorized: 403"))
- await BotServices.SendEmbedAsync(e.Context, "Insufficient Permissions", EmbedType.Error)
- .ConfigureAwait(false);
- else
- e.Context.Client.Logger.LogError(EventId, $"{e.Context.User.Username} tried executing '{e.Command?.QualifiedName ?? ""}' but it errored: {e.Exception.GetType()}: {e.Exception.Message}"); // DEBUG ONLY
- break;
- }
- }
-
- private static Task PrefixResolverAsync(DiscordMessage m)
- {
- return Task.FromResult(m.GetStringPrefixLength(TokenHandler.Tokens.CommandPrefix));
- }
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Games/PokemonModule.cs b/src/FlawBOT.Core/Modules/Games/PokemonModule.cs
deleted file mode 100644
index a868ed1a..00000000
--- a/src/FlawBOT.Core/Modules/Games/PokemonModule.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class PokemonModule : BaseCommandModule
- {
- #region COMMAND_POKEMON
-
- [Command("pokemon")]
- [Aliases("poke", "pk")]
- [Description("Retrieve a Pokémon card")]
- public async Task Pokemon(CommandContext ctx,
- [Description("Name of the Pokémon")] [RemainingText] string query)
- {
- var results = await PokemonService.GetPokemonCardsAsync(query).ConfigureAwait(false);
- if (results.Cards.Count == 0)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- foreach (var dex in results.Cards)
- {
- var card = PokemonService.GetExactPokemon(dex.Id);
- var output = new DiscordEmbedBuilder()
- .WithTitle(card.Name + $" (#{card.NationalPokedexNumber})")
- .AddField("Series", card.Series ?? "Unknown", true)
- .AddField("Rarity", card.Rarity ?? "Unknown", true)
- .AddField("HP", card.Hp ?? "Unknown", true)
- .AddField("Ability", card.Ability != null ? card.Ability.Name : "Unknown", true)
- .WithImageUrl(card.ImageUrlHiRes ?? card.ImageUrl)
- .WithFooter(!string.Equals(card.Id, results.Cards.Last().Id)
- ? "Type 'next' within 10 seconds for the next Pokémon"
- : "This is the last found Pokémon on the list.")
- .WithColor(DiscordColor.Gold);
-
- var types = new StringBuilder();
- foreach (var type in card.Types)
- types.Append(type);
- output.AddField("Types", types.ToString() ?? "Unknown", true);
-
- var weaknesses = new StringBuilder();
- foreach (var weakness in card.Weaknesses)
- weaknesses.Append(weakness.Type);
- output.AddField("Weaknesses", weaknesses.ToString() ?? "Unknown", true);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.Cards.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- if (!string.Equals(card.Id, results.Cards.Last().Id))
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_POKEMON
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Games/SpeedrunModule.cs b/src/FlawBOT.Core/Modules/Games/SpeedrunModule.cs
deleted file mode 100644
index 3f1b5730..00000000
--- a/src/FlawBOT.Core/Modules/Games/SpeedrunModule.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class SpeedrunModule : BaseCommandModule
- {
- #region COMMAND_SPEEDRUN
-
- [Command("speedrun")]
- [Aliases("game", "run")]
- [Description("Retrieve a game from Speedrun.com")]
- public async Task Speedrun(CommandContext ctx,
- [Description("Game to search on Speedrun.com")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = SpeedrunService.GetSpeedrunGameAsync(query).Result.Data;
- if (results is null || results.Count == 0)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- foreach (var game in results)
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(game.Names.International)
- .AddField("Release Date", game.ReleaseDate ?? "Unknown", true)
- .AddField("Developers", SpeedrunService.GetSpeedrunExtraAsync(game.Developers, SpeedrunExtras.Developers).Result ?? "Unknown", true)
- .AddField("Publishers", SpeedrunService.GetSpeedrunExtraAsync(game.Publishers, SpeedrunExtras.Publishers).Result ?? "Unknown", true)
- .AddField("Platforms", SpeedrunService.GetSpeedrunExtraAsync(game.Platforms, SpeedrunExtras.Platforms).Result ?? "Unknown")
- .WithFooter($"ID: {game.Id} - Abbreviation: {game.Abbreviation}")
- .WithThumbnail(game.Assets.CoverLarge.Url ?? game.Assets.Icon.Url)
- .WithUrl(game.WebLink)
- .WithColor(new DiscordColor("#0F7A4D"));
-
- var link = game.Links.First(x => x.Rel == "categories").Url;
- var categories = SpeedrunService.GetSpeedrunCategoryAsync(link).Result.Data;
- var category = new StringBuilder();
- if (categories != null || categories.Count > 0)
- foreach (var x in categories)
- category.Append($"[{x.Name}]({x.Weblink}) **|** ");
- output.AddField("Categories", category.ToString() ?? "Unknown", true);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- if (!game.Equals(results.Last()))
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_SPEEDRUN
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Games/SteamModule.cs b/src/FlawBOT.Core/Modules/Games/SteamModule.cs
deleted file mode 100644
index 7157d0c4..00000000
--- a/src/FlawBOT.Core/Modules/Games/SteamModule.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-using Steam.Models.SteamCommunity;
-using UserStatus = Steam.Models.SteamCommunity.UserStatus;
-
-namespace FlawBOT.Modules
-{
- [Group("steam")]
- [Description("Commands finding Steam games and users")]
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class SteamModule : BaseCommandModule
- {
- #region COMMAND_GAME
-
- [Command("game")]
- [Description("Retrieve Steam game information")]
- public async Task SteamGame(CommandContext ctx,
- [Description("Game to find on Steam")] [RemainingText] string query = "Team Fortress 2")
- {
- try
- {
- var app = SteamService.GetSteamAppAsync(query).Result;
- if (app is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(app.Name)
- .WithDescription(
- Regex.Replace(
- app.DetailedDescription.Length <= 500
- ? app.DetailedDescription
- : app.DetailedDescription.Substring(0, 250) + "...", "<[^>]*>", "") ?? "Unknown")
- .AddField("Release Date", app.ReleaseDate.Date ?? "Unknown", true)
- .AddField("Developers", app.Developers[0] ?? "Unknown", true)
- .AddField("Publisher", app.Publishers[0] ?? "Unknown", true)
- .AddField("Price", app.IsFree ? "Free" : app.PriceOverview.FinalFormatted ?? "Unknown", true)
- .AddField("Metacritic", app.Metacritic != null ? app.Metacritic.Score.ToString() : "Unknown", true)
- .WithThumbnail(app.HeaderImage)
- .WithUrl("http://store.steampowered.com/app/" + app.SteamAppId)
- .WithFooter("App ID: " + app.SteamAppId)
- .WithColor(new DiscordColor("#1B2838"));
-
- var genres = new StringBuilder();
- foreach (var genre in app.Genres.Take(3))
- genres.Append(genre.Description).Append(!genre.Equals(app.Genres.Last()) ? ", " : string.Empty);
- output.AddField("Genres", genres.ToString() ?? "Unknown", true);
-
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
- catch
- {
- await ctx.RespondAsync("Unable to retrieve game information from the Steam API.").ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_GAME
-
- #region COMMAND_USER
-
- [Command("user")]
- [Aliases("player")]
- [Description("Retrieve Steam user information")]
- public async Task SteamUser(CommandContext ctx,
- [Description("User to find on Steam")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var profile = SteamService.GetSteamProfileAsync(query).Result;
- var summary = SteamService.GetSteamSummaryAsync(query).Result;
- if (profile is null && summary is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- if (summary.Data.ProfileVisibility != ProfileVisibility.Public)
- {
- await BotServices.SendEmbedAsync(ctx, "This profile is private...", EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(summary.Data.Nickname)
- .WithDescription(Regex.Replace(profile?.Summary ?? string.Empty, "<[^>]*>", "") ?? string.Empty)
- .AddField("Member since", summary.Data.AccountCreatedDate.ToUniversalTime().ToString(CultureInfo.CurrentCulture), true)
- .WithThumbnail(profile?.AvatarFull.ToString() ?? profile.Avatar.ToString())
- .WithColor(new DiscordColor("#1B2838"))
- .WithUrl("http://steamcommunity.com/profiles/" + profile.SteamID)
- .WithFooter("Steam ID: " + profile.SteamID);
-
- if (summary.Data.UserStatus != UserStatus.Offline)
- output.AddField("Status", summary.Data.UserStatus.ToString(), true);
- else
- output.AddField("Last seen", summary.Data.LastLoggedOffDate.ToUniversalTime().ToString(CultureInfo.CurrentCulture), true);
-
- if (!string.IsNullOrWhiteSpace(profile.Location))
- output.AddField("Location", profile.Location);
-
- if (profile.InGameInfo != null)
- {
- output.AddField("In-Game", $"[{profile.InGameInfo.GameName}]({profile.InGameInfo.GameLink})", true);
- output.AddField("Game Server IP", profile.InGameServerIP, true);
- output.WithImageUrl(profile.InGameInfo.GameLogoSmall);
- }
-
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
- }
-
- #endregion COMMAND_USER
-
- #region COMMAND_CONNECT
-
- [Command("connect")]
- [Aliases("link")]
- [Description("Format a game connection string into a link")]
- public async Task SteamServerLink(CommandContext ctx,
- [Description("Connection string")] [RemainingText] string link)
- {
- var regex = new Regex(@"\s*(?'ip'\S+)\s*", RegexOptions.Compiled).Match(link);
- if (regex.Success)
- await ctx.RespondAsync(string.Format($"steam://connect/{regex.Groups["ip"].Value}/{regex.Groups["pw"].Value}"))
- .ConfigureAwait(false);
- else
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_STEAM_CONNECT_FORMAT, EmbedType.Warning)
- .ConfigureAwait(false);
- }
-
- #endregion COMMAND_CONNECT
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Games/TeamFortressModule.cs b/src/FlawBOT.Core/Modules/Games/TeamFortressModule.cs
deleted file mode 100644
index 163ca7aa..00000000
--- a/src/FlawBOT.Core/Modules/Games/TeamFortressModule.cs
+++ /dev/null
@@ -1,306 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-using TeamworkTF.Sharp;
-
-namespace FlawBOT.Modules
-{
- [Group("tf2")]
- [Description("Commands related to Team Fortress 2")]
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class TeamFortressModule : BaseCommandModule
- {
- #region COMMAND_SCHEMA
-
- [Command("item")]
- [Aliases("schema", "hat")]
- [Description("Retrieve an item from the latest TF2 item schema")]
- public async Task Tf2Item(CommandContext ctx,
- [Description("Item to find in the TF2 schema")] [RemainingText] string query = "The Scattergun")
- {
- var item = TeamFortressService.GetSchemaItem(query);
- if (item is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- var textInfo = new CultureInfo("en-US", false).TextInfo;
- var output = new DiscordEmbedBuilder()
- .WithTitle(item.ItemName)
- .WithDescription(item.ItemDescription ?? string.Empty)
- .WithImageUrl(item.ImageUrlLarge ?? item.ImageUrl)
- .WithUrl("https://wiki.teamfortress.com/wiki/" + item.ItemName.Replace(' ', '_'))
- .WithFooter("ID: " + item.DefIndex)
- .WithColor(new DiscordColor("#E7B53B"));
-
- var classes = new StringBuilder();
- foreach (var className in item.UsedByClasses)
- classes.Append(className).Append(!className.Equals(item.UsedByClasses.Last()) ? ", " : string.Empty);
- output.AddField("Used by:", classes.ToString() ?? "Unknown", true);
- output.AddField("Item Slot:", textInfo.ToTitleCase(item.ItemSlot) ?? "Unknown", true);
- output.AddField("Item Type:", item.ItemTypeName ?? "Unknown", true);
- output.AddField("Giftable:", item.Capabilities.CanGiftWrap == true ? "Yes" : "No", true);
- output.AddField("Nameable:", item.Capabilities.Nameable ? "Yes" : "No", true);
- output.AddField("Restriction:", item.HolidayRestriction ?? "None", true);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_SCHEMA
-
- #region COMMAND_MAP
-
- [Command("map")]
- [Aliases("maps")]
- [Description("Retrieve map information from teamwork.tf")]
- public async Task Tf2Map(CommandContext ctx,
- [Description("Normalized map name, like pl_upward")] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = await TeamFortressService.GetMapStatsAsync(query.ToLowerInvariant()).ConfigureAwait(false);
- if (results is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- double.TryParse(results.AllTimeAvgPlayers, out var avgPlayers);
- var output = new DiscordEmbedBuilder()
- .WithTitle(results.MapName)
- .AddField("Highest Server Count", results.HighestServers.ToString() ?? "Unknown", true)
- .AddField("Highest Player Count", results.HighestPlayers.ToString() ?? "Unknown", true)
- .AddField("Avg. Players", Math.Round(avgPlayers, 2).ToString(CultureInfo.InvariantCulture) ?? "Unknown", true)
- .WithFooter("Statistics retrieved from teamwork.tf - refreshed every 5 minutes")
- .WithImageUrl(results.Thumbnail)
- .WithUrl("https://wiki.teamfortress.com/wiki/" + results.MapName)
- .WithColor(new DiscordColor("#E7B53B"));
-
- if (results.RelatedMaps.Count > 0)
- {
- var maps = new StringBuilder();
- foreach (var map in results.RelatedMaps.Take(4))
- maps.Append(map + "\n");
- output.AddField("Related Map(s)", maps.ToString(), true);
- }
-
- if (results.ExtraInfo != null)
- {
- var links = new StringBuilder();
- if (results.ExtraInfo.SteamWorkshopUrl != null)
- links.Append($"[Steam Workshop]({results.ExtraInfo.SteamWorkshopUrl}) **|**");
- if (results.ExtraInfo.TF2MapsUrl != null)
- links.Append($"[TF2Maps]({results.ExtraInfo.TF2MapsUrl}) **|**");
- if (results.ExtraInfo.GameBananaUrl != null)
- links.Append($"[GameBanana]({results.ExtraInfo.GameBananaUrl}) **|**");
- output.AddField("Links", links.ToString(), true);
- }
-
- if (results.GameModes.Count > 0)
- {
- var desc = TeamFortressService.GetGameModeAsync(results.GameModes.FirstOrDefault()).Result;
- output.WithDescription(desc.Title + " - " + desc.Description);
- output.WithColor(new DiscordColor($"#{desc.Color}"));
- }
-
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_MAP
-
- #region COMMAND_NEWS
-
- [Command("news")]
- [Description("Retrieve the latest news article from teamwork.tf")]
- public async Task Tf2News(CommandContext ctx,
- [Description("Page number from which to retrieve the news")] int query = 0)
- {
- var results = await TeamFortressService.GetNewsOverviewAsync(query).ConfigureAwait(false);
- if (results is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder().WithColor(new DiscordColor("#E7B53B"));
- foreach (var result in results.Take(5))
- output.AddField(result.CreatedAt.Date.ToString(), $"{result.Type}: [{result.Title}]({result.Link.AbsoluteUri})");
- await ctx.RespondAsync("Latest news articles from teamwork.tf", embed: output.Build())
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_NEWS
-
- #region COMMAND_CREATORS
-
- [Command("creator")]
- [Aliases("creators", "youtuber")]
- [Description("Retrieve a community creator profile from teamwork.tf")]
- public async Task Tf2Creators(CommandContext ctx,
- [Description("Name of the community creator to find")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var steamId = SteamService.GetSteamUserId(query).Result.Data;
- var results = await TeamFortressService.GetCreatorByIdAsync(steamId).ConfigureAwait(false);
- if (results is null)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- foreach (var creator in results)
- {
- var user = results.FirstOrDefault();
- var output = new DiscordEmbedBuilder()
- .WithTitle(user?.Name)
- .WithDescription("Main Class: " + user?.Main.ToString()?.ToUpper())
- .WithThumbnail(user?.ThumbnailUrl)
- .WithUrl(user?.Link)
- .WithColor(new DiscordColor("#E7B53B"))
- .WithFooter(!creator.Equals(results.Last())
- ? "Type 'next' within 10 seconds for the next creator"
- : "Data retrieved from teamwork.tf");
-
- var links = new StringBuilder();
- if (creator.DiscordGroup != null)
- links.Append($"[Discord]({Resources.URL_DISCORD}{creator.DiscordGroup}) **|** ");
- if (!string.IsNullOrWhiteSpace(creator.Steam))
- links.Append($"[Steam]({Resources.URL_STEAM_USER}{creator.Steam}) **|** ");
- if (creator.SteamGroup != null)
- links.Append($"[Steam Group]({Resources.URL_STEAM_GROUP}{creator.SteamGroup}) **|** ");
- if (creator.Twitch != null)
- links.Append($"[Twitch]({Resources.URL_TWITCH_CHANNEL}{creator.Twitch}) **|** ");
- if (!string.IsNullOrWhiteSpace(creator.Twitter))
- links.Append($"[Twitter]({Resources.URL_YOUTUBE_CHANNEL}{creator.Twitter}) **|** ");
- if (!string.IsNullOrWhiteSpace(creator.Youtube))
- links.Append($"[YouTube]({Resources.URL_YOUTUBE_CHANNEL}{creator.Youtube})");
- output.AddField("Links", links.ToString(), true);
- var message = await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- if (!creator.Equals(results.Last()))
- await BotServices.RemoveMessage(message).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_CREATORS
-
- #region COMMAND_SERVERS
-
- [Command("server")]
- [Aliases("servers")]
- [Description("Retrieve a list of servers with given game-mode")]
- public async Task Tf2ServerByMode(CommandContext ctx,
- [Description("Name of the game-mode, like payload")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = await TeamFortressService.GetGameModeServerAsync(query.Trim().Replace(' ', '-'))
- .ConfigureAwait(false);
- if (results is null)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- await OutputServerInfo(ctx, results.OrderBy(_ => new Random().Next()).ToList()).ConfigureAwait(false);
- }
-
- [Command("ip")]
- [Aliases("find")]
- [Description("Retrieve a game server with given ip address")]
- public async Task Tf2ServerByIp(CommandContext ctx,
- [Description("Game server IP address, like 164.132.233.16")] string ip,
- [Description("Game server port, like 27022")] int port = 0)
- {
- if (!BotServices.CheckUserInput(ip)) return;
- var regex = new Regex(@"\s*(?'ip'\S+)\s*", RegexOptions.Compiled).Match(ip);
- if (!regex.Success) return;
- var results = await TeamFortressService.GetGameServerInfoAsync(ip, port).ConfigureAwait(false);
- if (results is null || results.Count <= 0)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- await OutputServerInfo(ctx, results.OrderBy(_ => new Random().Next()).ToList()).ConfigureAwait(false);
- }
-
- public async Task OutputServerInfo(CommandContext ctx, List results)
- {
- foreach (var server in results)
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(server.Name)
- .WithDescription("steam://connect/" + server.Ip + ":" + server.Port)
- .AddField("Provider", server.Provider != null ? server.Provider.Name : "Unknown", true)
- .AddField("Player Count", (server.Players.ToString() ?? "Unknown") + "/" + (server.MaxPlayers.ToString() ?? "Unknown"), true)
- .AddField("Password Lock", server.HasPassword ? "Yes" : "No", true)
- .AddField("Random Crits", server.HasRandomCrits == true ? "Yes" : "No", true)
- .AddField("Instant Respawn", server.HasNoRespawnTime ? "Yes" : "No", true)
- .AddField("All Talk", server.HasAllTalk ? "Yes" : "No", true)
- .AddField("Current Map", server.MapName ?? "Unknown", true)
- .AddField("Next Map", server.MapNameNext ?? "Unknown", true)
- .WithFooter("Type 'next' within 10 seconds for the next server")
- .WithColor(new DiscordColor("#E7B53B"));
-
- var thumbnailUrl = await TeamFortressService.GetMapThumbnailAsync(server.MapName).ConfigureAwait(false);
- output.WithImageUrl(thumbnailUrl.Name);
-
- var message = await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- if (!server.Equals(results.Last()))
- await BotServices.RemoveMessage(message).ConfigureAwait(false);
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- }
- }
-
- [Command("server-list")]
- [Aliases("serverList")]
- [Description("Retrieve a curated list of servers")]
- public async Task Tf2ServerList(CommandContext ctx)
- {
- var results = await TeamFortressService.GetCustomServerListsAsync().ConfigureAwait(false);
- results = results.OrderBy(_ => new Random().Next()).ToList();
- foreach (var server in results)
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(server.Name)
- .WithDescription(
- Regex.Replace(
- server.DescriptionLarge.Length <= 500
- ? server.DescriptionLarge
- : server.DescriptionLarge.Substring(0, 250) + "...", "<[^>]*>", "") ?? "Unknown")
- .AddField("Created by", server.Creator.Name ?? "Unknown", true)
- .AddField("Subscribers", server.Subscribed.ToString() ?? "Unknown", true)
- .WithUrl(Resources.URL_TEAMWORK_SERVERS + server.Id)
- .WithFooter("Type 'next' within 10 seconds for the next server list")
- .WithColor(new DiscordColor("#E7B53B"));
- var message = await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- if (!server.Equals(results.Last()))
- await BotServices.RemoveMessage(message).ConfigureAwait(false);
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_SERVERS
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Misc/MiscModule.cs b/src/FlawBOT.Core/Modules/Misc/MiscModule.cs
deleted file mode 100644
index 2351cf59..00000000
--- a/src/FlawBOT.Core/Modules/Misc/MiscModule.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-using System;
-using System.Net;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Common;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-using Newtonsoft.Json.Linq;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class MiscModule : BaseCommandModule
- {
- #region COMMAND_8BALL
-
- [Command("ask")]
- [Aliases("8b", "8ball", "ball")]
- [Description("Ask an 8-ball a question")]
- public Task EightBall(CommandContext ctx,
- [Description("Question to ask the 8-Ball")] [RemainingText] string question = "")
- {
- if (string.IsNullOrWhiteSpace(question)) return null;
- var output = new DiscordEmbedBuilder()
- .WithDescription(":8ball: " + EightBallService.GetRandomAnswer() + " (" + ctx.User.Mention + ")")
- .WithColor(DiscordColor.Black);
- return ctx.RespondAsync(embed: output.Build());
- }
-
- #endregion COMMAND_8BALL
-
- #region COMMAND_CATFACT
-
- [Command("cat")]
- [Aliases("catfact")]
- [Description("Retrieve a random cat fact")]
- public async Task CatFact(CommandContext ctx)
- {
- var results = CatService.GetCatFactAsync().Result;
- var output = new DiscordEmbedBuilder()
- .WithDescription($":cat: {JObject.Parse(results)["fact"]}")
- .WithColor(DiscordColor.Orange);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
-
- #endregion COMMAND_CATFACT
-
- #region COMMAND_CATPIC
-
- [Command("randomcat")]
- [Aliases("meow")]
- [Description("Retrieve a random cat photo")]
- public async Task CatPic(CommandContext ctx)
- {
- var results = CatService.GetCatPhotoAsync().Result;
- if (string.IsNullOrWhiteSpace(results))
- await BotServices.SendEmbedAsync(ctx, "Connection to random.cat failed!", EmbedType.Warning)
- .ConfigureAwait(false);
- var output = new DiscordEmbedBuilder()
- .WithImageUrl(results)
- .WithColor(DiscordColor.Orange);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
-
- #endregion COMMAND_CATPIC
-
- #region COMMAND_COINFLIP
-
- [Command("coinflip")]
- [Aliases("coin", "flip")]
- [Description("Flip a coin")]
- public Task CoinFlip(CommandContext ctx)
- {
- var random = new Random();
- var output = new DiscordEmbedBuilder()
- .WithDescription(ctx.User.Username + " flipped a coin and got " + Formatter.Bold(Convert.ToBoolean(random.Next(0, 2)) ? "Heads" : "Tails"))
- .WithColor(SharedData.DefaultColor);
- return ctx.RespondAsync(embed: output.Build());
- }
-
- #endregion COMMAND_COINFLIP
-
- #region COMMAND_COLOR
-
- [Command("color")]
- [Aliases("clr")]
- [Description("Retrieve color values for a given HEX code")]
- public async Task GetColor(CommandContext ctx,
- [Description("HEX color code to process")] DiscordColor color)
- {
- var regex = new Regex(@"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", RegexOptions.Compiled).Match(color.ToString());
- if (!regex.Success)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_COLOR_INVALID, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .AddField("HEX:", $"#{color.Value:X}")
- .AddField("RGB:", $"{color.R} {color.G} {color.B}")
- .AddField("Decimal:", color.Value.ToString())
- .WithColor(color);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_COLOR
-
- #region COMMAND_DICEROLL
-
- [Command("diceroll")]
- [Aliases("dice", "roll", "rolldice", "die")]
- [Description("Roll a six-sided die")]
- public Task RollDice(CommandContext ctx)
- {
- var random = new Random();
- var output = new DiscordEmbedBuilder()
- .WithDescription(ctx.User.Username + " rolled a die and got " + Formatter.Bold(random.Next(1, 7).ToString()))
- .WithColor(SharedData.DefaultColor);
- return ctx.RespondAsync(embed: output.Build());
- }
-
- #endregion COMMAND_DICEROLL
-
- #region COMMAND_DOGPIC
-
- [Command("randomdog")]
- [Aliases("woof", "dog", "bark")]
- [Description("Retrieve a random dog photo")]
- public async Task DogPic(CommandContext ctx)
- {
- var results = DogService.GetDogPhotoAsync().Result;
- if (results.Status != "success")
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_DOG_PHOTO, EmbedType.Warning).ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .WithImageUrl(results.Message)
- .WithColor(DiscordColor.Brown);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_DOGPIC
-
- #region COMMAND_HELLO
-
- [Command("hello")]
- [Aliases("hi", "howdy")]
- [Description("Welcome another user to the server")]
- public async Task Greet(CommandContext ctx,
- [Description("User to say hello to")] [RemainingText] DiscordMember member)
- {
- if (member is null)
- await ctx.RespondAsync(":wave: Hello, " + ctx.User.Mention).ConfigureAwait(false);
- else
- await ctx.RespondAsync(":wave: Welcome " + member.Mention + " to " + ctx.Guild.Name + ". Enjoy your stay!").ConfigureAwait(false);
- }
-
- #endregion COMMAND_HELLO
-
- #region COMMAND_IP
-
- [Command("ip")]
- [Aliases("ipstack", "track")]
- [Description("Retrieve IP address geolocation information")]
- public async Task IpLocation(CommandContext ctx,
- [Description("IP Address")] string address)
- {
- if (string.IsNullOrWhiteSpace(address) || !IPAddress.TryParse(address, out var ip)) return;
- var results = GoogleService.GetIpLocationAsync(ip).Result;
- if (results.Status != "success")
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_LOCATION, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .AddField("Location", $"{results.City}, {results.Region}, {results.Country}")
- .AddField("ISP", results.Isp)
- .AddField("Coordinates", $"{results.Latitude}°N, {results.Longitude}°W")
- .WithFooter($"IP: {results.Query}")
- .WithColor(new DiscordColor("#4d2f63"));
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_IP
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Misc/PollModule.cs b/src/FlawBOT.Core/Modules/Misc/PollModule.cs
deleted file mode 100644
index 797b792b..00000000
--- a/src/FlawBOT.Core/Modules/Misc/PollModule.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using DSharpPlus.Interactivity;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class PollModule : BaseCommandModule
- {
- #region COMMAND_POLL
-
- [Command("poll")]
- [Description("Run a Yay or Nay poll in the current channel")]
- public async Task Poll(CommandContext ctx,
- [Description("Question to be polled")] [RemainingText] string question)
- {
- if (!BotServices.CheckUserInput(question))
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_POLL_QUESTION, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- var interactivity = ctx.Client.GetInteractivity();
- var pollOptions = new List
- {
- DiscordEmoji.FromName(ctx.Client, ":thumbsup:"),
- DiscordEmoji.FromName(ctx.Client, ":thumbsdown:")
- };
- var duration = new TimeSpan(0, 0, 3, 0, 0);
- var output = new DiscordEmbedBuilder().WithDescription(ctx.User.Mention + "asked: " + question + "\nThis poll ends in 3 minutes.");
- var message = await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- foreach (var react in pollOptions)
- await message.CreateReactionAsync(react).ConfigureAwait(false);
- var pollResult = await interactivity.CollectReactionsAsync(message, duration).ConfigureAwait(false);
- var results = pollResult.Where(x => pollOptions.Contains(x.Emoji))
- .Select(x => $"{x.Emoji} wins the poll with **{x.Total}** votes");
- await ctx.RespondAsync(string.Join("\n", results)).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_POLL
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/AmiiboModule.cs b/src/FlawBOT.Core/Modules/Search/AmiiboModule.cs
deleted file mode 100644
index a86a6507..00000000
--- a/src/FlawBOT.Core/Modules/Search/AmiiboModule.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System.Linq;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class AmiiboModule : BaseCommandModule
- {
- #region COMMAND_AMIIBO
-
- [Command("amiibo")]
- [Aliases("amib")]
- [Description("Retrieve Amiibo figurine information")]
- public async Task GetAmiibo(CommandContext ctx,
- [Description("Name of the Amiibo figurine")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = await AmiiboService.GetAmiiboDataAsync(query).ConfigureAwait(false);
- if (results is null)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- foreach (var amiibo in results.Amiibo)
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(amiibo.Name)
- .AddField("Amiibo Series", amiibo.AmiiboSeries, true)
- .AddField("Game Series", amiibo.GameSeries, true)
- .AddField(":flag_us: Release:", amiibo.ReleaseDate.American, true)
- .AddField(":flag_jp: Release:", amiibo.ReleaseDate.Japanese, true)
- .AddField(":flag_eu: Release:", amiibo.ReleaseDate.European, true)
- .AddField(":flag_au: Release:", amiibo.ReleaseDate.Australian, true)
- .WithImageUrl(amiibo.Image)
- .WithFooter(!amiibo.Equals(results.Amiibo.Last())
- ? "Type 'next' within 10 seconds for the next amiibo"
- : "This is the last found amiibo on the list.")
- .WithColor(new DiscordColor("#E70009"));
- var message = await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.Amiibo.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- if (!amiibo.Equals(results.Amiibo.Last()))
- await BotServices.RemoveMessage(message).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_AMIIBO
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/DictionaryModule.cs b/src/FlawBOT.Core/Modules/Search/DictionaryModule.cs
deleted file mode 100644
index 50d28f40..00000000
--- a/src/FlawBOT.Core/Modules/Search/DictionaryModule.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System.Linq;
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class DictionaryModule : BaseCommandModule
- {
- #region COMMAND_DICTIONARY
-
- [Command("dictionary")]
- [Aliases("define", "def", "dic")]
- [Description("Retrieve an Urban Dictionary definition of a word or phrase")]
- public async Task UrbanDictionary(CommandContext ctx,
- [Description("Query to pass to Urban Dictionary")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = await DictionaryService.GetDictionaryDefinitionAsync(query).ConfigureAwait(false);
- if (results.ResultType == "no_results" || results.List.Count == 0)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- foreach (var definition in results.List)
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle("Urban Dictionary definition for " + Formatter.Bold(query))
- .WithDescription(!string.IsNullOrWhiteSpace(definition.Author)
- ? "Submitted by: " + definition.Author
- : string.Empty)
- .AddField("Definition", definition.Definition.Length < 500
- ? definition.Definition
- : definition.Definition.Take(500) + "...")
- .AddField("Example", definition.Example ?? "None")
- .AddField(":thumbsup:", definition.ThumbsUp.ToString(), true)
- .AddField(":thumbsdown:", definition.ThumbsDown.ToString(), true)
- .WithUrl(definition.Permalink)
- .WithFooter(!definition.Equals(results.List.Last())
- ? "Type 'next' within 10 seconds for the next definition"
- : "This is the last found definition on the list.")
- .WithColor(new DiscordColor("#1F2439"));
- var message = await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
-
- if (results.List.Count == 1) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- if (!definition.Equals(results.List.Last()))
- await BotServices.RemoveMessage(message).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_DICTIONARY
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/GoogleModule.cs b/src/FlawBOT.Core/Modules/Search/GoogleModule.cs
deleted file mode 100644
index d2099998..00000000
--- a/src/FlawBOT.Core/Modules/Search/GoogleModule.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-using System;
-using System.Globalization;
-using System.Linq;
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Common;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class GoogleModule : BaseCommandModule
- {
- #region COMMAND_TIME
-
- [Command("time")]
- [Aliases("clock")]
- [Description("Retrieve the time for specified location")]
- public async Task GetTime(CommandContext ctx,
- [Description("Location to retrieve time data from")] [RemainingText] string location)
- {
- if (!BotServices.CheckUserInput(location)) return;
- var results = GoogleService.GetTimeDataAsync(location).Result;
- if (results == null || results.Status != "OK")
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(":clock1: Current time in " + results.Results[0].FormattedAddress)
- .WithDescription(Formatter.Bold(results.Time.ToShortTimeString()) + " " + results.Timezone.TimeZoneName)
- .WithColor(SharedData.DefaultColor);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_TIME
-
- #region COMMAND_NEWS
-
- [Command("news")]
- [Description("Retrieve the latest news articles from NewsAPI.org")]
- public async Task News(CommandContext ctx,
- [Description("Article topic to find on Google News")] [RemainingText] string query)
- {
- var results = await GoogleService.GetNewsDataAsync(query).ConfigureAwait(false);
- if (results.Status != "ok")
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- while (results.Articles.Count > 0)
- {
- var output = new DiscordEmbedBuilder()
- .WithFooter("Type 'next' within 10 seconds for the next five articles.")
- .WithColor(new DiscordColor("#253B80"));
-
- foreach (var result in results.Articles.Take(5))
- {
- output.AddField(result.PublishDate.ToString(CultureInfo.InvariantCulture), $"[{result.Title}]({result.Url})");
- results.Articles.Remove(result);
- }
-
- var message = await ctx
- .RespondAsync("Latest Google News articles from News API", embed: output.Build())
- .ConfigureAwait(false);
-
- if (results.Articles.Count == 5) continue;
- var interactivity = await BotServices.GetUserInteractivity(ctx, "next", 10).ConfigureAwait(false);
- if (interactivity.Result is null) break;
- await BotServices.RemoveMessage(interactivity.Result).ConfigureAwait(false);
- await BotServices.RemoveMessage(message).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_NEWS
-
- #region COMMAND_WEATHER
-
- [Command("weather")]
- [Description("Retrieve the weather for specified location")]
- public async Task Weather(CommandContext ctx,
- [Description("Location to retrieve weather data from")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = await GoogleService.GetWeatherDataAsync(query).ConfigureAwait(false);
- if (results == null || results.Cod == 404)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_LOCATION, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- Func format = GoogleService.CelsiusToFahrenheit;
- var output = new DiscordEmbedBuilder()
- .WithTitle(":partly_sunny: Current weather in " + results.Name + ", " + results.Sys.Country)
- .AddField("Temperature", $"{results.Main.Temperature:F1}°C / {format(results.Main.Temperature):F1}°F", true)
- .AddField("Humidity", $"{results.Main.Humidity}%", true)
- .AddField("Wind Speed", $"{results.Wind.Speed}m/s", true)
- .WithUrl("https://openweathermap.org/city/" + results.Id)
- .WithColor(SharedData.DefaultColor);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_WEATHER
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/OMDBModule.cs b/src/FlawBOT.Core/Modules/Search/OMDBModule.cs
deleted file mode 100644
index 6a0c9532..00000000
--- a/src/FlawBOT.Core/Modules/Search/OMDBModule.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-using System.Linq;
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class OmdbModule : BaseCommandModule
- {
- #region COMMAND_OMDB
-
- [Command("omdb")]
- [Aliases("imdb", "movie")]
- [Description("Retrieve a movie or TV show from OMDB")]
- public async Task Omdb(CommandContext ctx,
- [Description("Movie or TV show to find on OMDB")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = OmdbService.GetMovieDataAsync(query.Replace(" ", "+")).Result;
- if (results.Response == "False")
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_GENERIC, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(results.Title)
- .WithDescription(results.Plot.Length < 500 ? results.Plot : results.Plot.Take(500) + "...")
- .AddField("Released", results.Released, true)
- .AddField("Runtime", results.Runtime, true)
- .AddField("Genre", results.Genre, true)
- .AddField("Rating", results.Rated, true)
- .AddField("Country", results.Country, true)
- .AddField("Box Office", results.BoxOffice, true)
- .AddField("Production", results.Production, true)
- .AddField("IMDb Rating", results.IMDbRating, true)
- .AddField("Metacritic", results.Metascore, true)
- .AddField("Directors", results.Director)
- .AddField("Actors", results.Actors)
- .WithColor(DiscordColor.Goldenrod);
- if (results.Poster != "N/A") output.WithImageUrl(results.Poster);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_OMDB
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/TwitchModule.cs b/src/FlawBOT.Core/Modules/Search/TwitchModule.cs
deleted file mode 100644
index 3e99fcb2..00000000
--- a/src/FlawBOT.Core/Modules/Search/TwitchModule.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class TwitchModule : BaseCommandModule
- {
- #region COMMAND_TWITCH
-
- [Command("twitch")]
- [Aliases("stream")]
- [Description("Retrieve Twitch stream information")]
- public async Task Twitch(CommandContext ctx,
- [Description("Channel to find on Twitch")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = await TwitchService.GetTwitchDataAsync(query).ConfigureAwait(false);
- if (results.Stream.Count == 0)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_TWITCH, EmbedType.Missing)
- .ConfigureAwait(false);
- }
- else
- {
- var stream = results.Stream[0];
- var output = new DiscordEmbedBuilder()
- .WithTitle(stream.UserName + " is live on Twitch!")
- .WithDescription(stream.Title)
- .AddField("Start Time:", stream.StartTime, true)
- .AddField("View Count:", stream.ViewCount.ToString(), true)
- .WithImageUrl(stream.ThumbnailUrl.Replace("{width}", "500").Replace("{height}", "300"))
- .WithUrl("https://www.twitch.tv/" + stream.UserName)
- .WithColor(new DiscordColor("#6441A5"));
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_TWITCH
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/WikipediaModule.cs b/src/FlawBOT.Core/Modules/Search/WikipediaModule.cs
deleted file mode 100644
index 02e71de2..00000000
--- a/src/FlawBOT.Core/Modules/Search/WikipediaModule.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Threading.Tasks;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class WikipediaModule : BaseCommandModule
- {
- #region COMMAND_WIKIPEDIA
-
- [Command("wiki")]
- [Aliases("wikipedia")]
- [Description("Search Wikipedia for a given query")]
- public async Task Wikipedia(CommandContext ctx,
- [Description("Query to search on Wikipedia")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var results = WikipediaService.GetWikipediaDataAsync(query).Result;
- if (results.Missing)
- await BotServices.SendEmbedAsync(ctx, Resources.NOT_FOUND_WIKIPEDIA, EmbedType.Missing)
- .ConfigureAwait(false);
- else
- await ctx.Channel.SendMessageAsync(results.FullUrl).ConfigureAwait(false);
- }
-
- #endregion COMMAND_WIKIPEDIA
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Search/YoutubeModule.cs b/src/FlawBOT.Core/Modules/Search/YoutubeModule.cs
deleted file mode 100644
index 2352763a..00000000
--- a/src/FlawBOT.Core/Modules/Search/YoutubeModule.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Group("youtube")]
- [Aliases("yt")]
- [Description("Commands for finding YouTube videos, channels and playlists")]
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class YouTubeModule : BaseCommandModule
- {
- #region COMMAND_CHANNEL
-
- [Command("channel")]
- [Aliases("channels", "chn")]
- [Description("Retrieve a list of YouTube channel given a query")]
- public async Task YouTubeChannel(CommandContext ctx,
- [Description("Channels to find on YouTube")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var service = new YoutubeService();
- var results = await service.GetEmbeddedResults(query, 5, "channel").ConfigureAwait(false);
- await ctx.RespondAsync("Search results for " + Formatter.Bold(query), embed: results).ConfigureAwait(false);
- }
-
- #endregion COMMAND_CHANNEL
-
- #region COMMAND_PLAYLIST
-
- [Command("playlist")]
- [Aliases("playlists", "list")]
- [Description("Retrieve a list of YouTube playlists given a query")]
- public async Task YouTubePlaylist(CommandContext ctx,
- [Description("Playlist to find on YouTube")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var service = new YoutubeService();
- var results = await service.GetEmbeddedResults(query, 5, "playlist").ConfigureAwait(false);
- await ctx.RespondAsync("Search results for " + Formatter.Bold(query), embed: results).ConfigureAwait(false);
- }
-
- #endregion COMMAND_PLAYLIST
-
- #region COMMAND_SEARCH
-
- [Command("search")]
- [Aliases("find")]
- [Description("Retrieve the first YouTube search result given a query")]
- public async Task YouTubeVideo(CommandContext ctx,
- [Description("First result video to find on YouTube")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var service = new YoutubeService();
- var results = await service.GetFirstVideoResultAsync(query).ConfigureAwait(false);
- await ctx.RespondAsync(results).ConfigureAwait(false);
- }
-
- #endregion COMMAND_SEARCH
-
- #region COMMAND_VIDEO
-
- [Command("video")]
- [Aliases("videos", "vid")]
- [Description("Retrieve a list of YouTube videos given a query")]
- public async Task YouTubeSearch(CommandContext ctx,
- [Description("Video to find on YouTube")] [RemainingText] string query)
- {
- if (!BotServices.CheckUserInput(query)) return;
- var service = new YoutubeService();
- var results = await service.GetEmbeddedResults(query, 5, "video").ConfigureAwait(false);
- await ctx.RespondAsync("Search results for " + Formatter.Bold(query), embed: results).ConfigureAwait(false);
- }
-
- #endregion COMMAND_VIDEO
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Server/BotModule.cs b/src/FlawBOT.Core/Modules/Server/BotModule.cs
deleted file mode 100644
index 3fd92414..00000000
--- a/src/FlawBOT.Core/Modules/Server/BotModule.cs
+++ /dev/null
@@ -1,320 +0,0 @@
-using System;
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Common;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Group("bot")]
- [Description("Basic commands for interacting with FlawBOT")]
- [Cooldown(3, 5, CooldownBucketType.Channel)]
- public class BotModule : BaseCommandModule
- {
- #region COMMAND_INFO
-
- [Command("info")]
- [Aliases("i", "about")]
- [Description("Retrieve FlawBOT information")]
- public async Task BotInfo(CommandContext ctx)
- {
- var uptime = DateTime.Now - SharedData.ProcessStarted;
- var output = new DiscordEmbedBuilder()
- .WithTitle(SharedData.Name)
- .WithDescription("A multipurpose Discord bot written in C# with [DSharpPlus](https://github.com/DSharpPlus/DSharpPlus/).")
- .AddField(":clock1: Uptime",$"{(int) uptime.TotalDays:00} days {uptime.Hours:00}:{uptime.Minutes:00}:{uptime.Seconds:00}", true)
- .AddField(":link: Links",$"[Commands]({SharedData.GitHubLink}wiki) **|** [Invite]({SharedData.InviteLink}) **|** [GitHub]({SharedData.GitHubLink})", true)
- .WithFooter("Thank you for using " + SharedData.Name + $" (v{SharedData.Version})")
- .WithUrl(SharedData.GitHubLink)
- .WithColor(SharedData.DefaultColor);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
-
- #endregion COMMAND_INFO
-
- #region COMMAND_LEAVE
-
- [Command("leave")]
- [Description("Make FlawBOT leave the current server")]
- [RequireUserPermissions(Permissions.Administrator)]
- public async Task LeaveAsync(CommandContext ctx)
- {
- await ctx.RespondAsync($"Are you sure you want {SharedData.Name} to leave this server?")
- .ConfigureAwait(false);
- var message = await ctx
- .RespondAsync("Respond with **yes** to proceed or wait 10 seconds to cancel this operation.")
- .ConfigureAwait(false);
- var interactivity = await BotServices.GetUserInteractivity(ctx, "yes", 10).ConfigureAwait(false);
- if (interactivity.Result is null)
- {
- await message.ModifyAsync("~~" + message.Content + "~~ " + Resources.REQUEST_TIMEOUT)
- .ConfigureAwait(false);
- }
- else
- {
- await BotServices.SendEmbedAsync(ctx, "Thank you for using " + SharedData.Name).ConfigureAwait(false);
- await ctx.Guild.LeaveAsync().ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_LEAVE
-
- #region COMMAND_PING
-
- [Command("ping")]
- [Aliases("pong")]
- [Description("Ping the FlawBOT client")]
- public async Task Ping(CommandContext ctx)
- {
- await BotServices.SendEmbedAsync(ctx, $":ping_pong: Pong! Ping: **{ctx.Client.Ping}**ms")
- .ConfigureAwait(false);
- }
-
- #endregion COMMAND_PING
-
- #region COMMAND_REPORT
-
- [Command("report")]
- [Hidden]
- [Aliases("issue")]
- [Description("Report a problem with FlawBOT to the developer. Please do not abuse.")]
- public async Task ReportIssue(CommandContext ctx,
- [Description("Detailed description of the issue")] [RemainingText] string report)
- {
- if (string.IsNullOrWhiteSpace(report) || report.Length < 50)
- {
- await ctx.RespondAsync(Resources.ERR_REPORT_CHAR_LENGTH).ConfigureAwait(false);
- }
- else
- {
- await ctx.RespondAsync(
- "The following information will be sent to the developer for investigation: User ID, Server ID, Server Name and Server Owner Name.")
- .ConfigureAwait(false);
- var message = await ctx
- .RespondAsync("Respond with **yes** to proceed or wait 10 seconds to cancel this operation.")
- .ConfigureAwait(false);
- var interactivity = await BotServices.GetUserInteractivity(ctx, "yes", 10).ConfigureAwait(false);
- if (interactivity.Result is null)
- {
- await message.ModifyAsync("~~" + message.Content + "~~ " + Resources.REQUEST_TIMEOUT)
- .ConfigureAwait(false);
- }
- else
- {
- var dm = await ctx.Member.CreateDmChannelAsync().ConfigureAwait(false);
- var output = new DiscordEmbedBuilder()
- .WithAuthor(ctx.Guild.Owner.Username + "#" + ctx.Guild.Owner.Discriminator, iconUrl: ctx.User.AvatarUrl ?? ctx.User.DefaultAvatarUrl)
- .AddField("Issue", report)
- .AddField("Sent By", ctx.User.Username + "#" + ctx.User.Discriminator)
- .AddField("Server", ctx.Guild.Name + $" (ID: {ctx.Guild.Id})")
- .AddField("Owner", ctx.Guild.Owner.Username + "#" + ctx.Guild.Owner.Discriminator)
- .AddField("Confirm", $"[Click here to add this issue to GitHub]({SharedData.GitHubLink}/issues/new)")
- .WithColor(SharedData.DefaultColor);
- await dm.SendMessageAsync(embed: output.Build()).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, "Thank You! Your report has been submitted.", EmbedType.Good)
- .ConfigureAwait(false);
- }
- }
- }
-
- #endregion COMMAND_REPORT
-
- #region COMMAND_SAY
-
- [Command("say")]
- [Hidden]
- [Aliases("echo")]
- [Description("Make FlawBOT repeat a message")]
- public async Task Say(CommandContext ctx,
- [Description("Message for the bot to repeat")] [RemainingText] string message)
- {
- await BotServices.RemoveMessage(ctx.Message).ConfigureAwait(false);
- await ctx.RespondAsync(message ?? ":thinking:").ConfigureAwait(false);
- }
-
- #endregion COMMAND_SAY
-
- #region COMMAND_TTS
-
- [Command("tts")]
- [Aliases("talk")]
- [Description("Make FlawBOT repeat a message in text-to-speech")]
- [RequirePermissions(Permissions.SendTtsMessages)]
- public Task SayTts(CommandContext ctx,
- [Description("Message for the bot to convert to speech")] [RemainingText] string text)
- {
- return string.IsNullOrWhiteSpace(text) ? ctx.RespondAsync("I need something to say...") : ctx.RespondAsync(Formatter.BlockCode(Formatter.Strip(text)), true);
- }
-
- #endregion COMMAND_TTS
-
- #region COMMAND_UPTIME
-
- [Command("uptime")]
- [Aliases("time")]
- [Description("Retrieve the FlawBOT uptime")]
- public async Task Uptime(CommandContext ctx)
- {
- var uptime = DateTime.Now - SharedData.ProcessStarted;
- var days = uptime.Days > 0 ? $"({uptime.Days:00} days)" : string.Empty;
- await BotServices.SendEmbedAsync(ctx,
- $":clock1: {SharedData.Name} has been online for {uptime.Hours:00}:{uptime.Minutes:00}:{uptime.Seconds} {days}")
- .ConfigureAwait(false);
- }
-
- #endregion COMMAND_UPTIME
-
- #region OWNERS-ONLY
-
- #region COMMAND_ACTIVITY
-
- [RequireOwner]
- [Command("activity")]
- [Hidden]
- [Aliases("setactivity")]
- [Description("Set FlawBOT's activity")]
- public async Task SetBotActivity(CommandContext ctx,
- [Description("Name of the activity")] [RemainingText] string activity)
- {
- if (string.IsNullOrWhiteSpace(activity))
- {
- await ctx.Client.UpdateStatusAsync().ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, SharedData.Name + " activity has been changed to Normal")
- .ConfigureAwait(false);
- }
- else
- {
- // TODO: Set the activity type
- var game = new DiscordActivity(activity);
- await ctx.Client.UpdateStatusAsync(game).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx,
- SharedData.Name + " activity has been changed to Playing " + game.Name, EmbedType.Good)
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_ACTIVITY
-
- #region COMMAND_AVATAR
-
- [RequireOwner]
- [Command("avatar")]
- [Hidden]
- [Aliases("setavatar", "pfp", "photo")]
- [Description("Set FlawBOT's avatar")]
- public async Task SetBotAvatar(CommandContext ctx,
- [Description("Image URL. Must be in jpg, png or img format.")] string query)
- {
- var stream = BotServices.CheckImageInput(ctx, query).Result;
- if (stream.Length <= 0) return;
- await ctx.Client.UpdateCurrentUserAsync(avatar: stream).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, SharedData.Name + " avatar has been updated!", EmbedType.Good)
- .ConfigureAwait(false);
- }
-
- #endregion COMMAND_AVATAR
-
- #region COMMAND_STATUS
-
- [RequireOwner]
- [Command("status")]
- [Hidden]
- [Aliases("setstatus", "state")]
- [Description("Set FlawBOT's status")]
- public async Task SetBotStatus(CommandContext ctx,
- [Description("Activity Status. Online, Idle, DND or Offline")] [RemainingText] string status)
- {
- status = status ?? "ONLINE";
- switch (status.Trim().ToUpperInvariant())
- {
- case "OFF":
- case "OFFLINE":
- await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Offline).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, SharedData.Name + " status has been changed to Offline")
- .ConfigureAwait(false);
- break;
-
- case "INVISIBLE":
- await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Invisible).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, SharedData.Name + " status has been changed to Invisible")
- .ConfigureAwait(false);
- break;
-
- case "IDLE":
- await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Idle).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, SharedData.Name + " status has been changed to Idle")
- .ConfigureAwait(false);
- break;
-
- case "DND":
- case "DO NOT DISTURB":
- await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.DoNotDisturb).ConfigureAwait(false);
- await BotServices
- .SendEmbedAsync(ctx, SharedData.Name + " status has been changed to Do Not Disturb")
- .ConfigureAwait(false);
- break;
-
- default:
- await ctx.Client.UpdateStatusAsync(userStatus: UserStatus.Online).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, SharedData.Name + " status has been changed to Online")
- .ConfigureAwait(false);
- break;
- }
- }
-
- #endregion COMMAND_STATUS
-
- #region COMMAND_UPDATE
-
- [RequireOwner]
- [Command("update")]
- [Hidden]
- [Aliases("refresh")]
- [Description("Update FlawBOT libraries")]
- public async Task Update(CommandContext ctx)
- {
- var message = await ctx.RespondAsync("Starting update...").ConfigureAwait(false);
- await TeamFortressService.UpdateTf2SchemaAsync().ConfigureAwait(false);
- await PokemonService.UpdatePokemonListAsync().ConfigureAwait(false);
- await message.ModifyAsync("Starting update...done!").ConfigureAwait(false);
- }
-
- #endregion COMMAND_UPDATE
-
- #region COMMAND_USERNAME
-
- [RequireOwner]
- [Command("username")]
- [Hidden]
- [Aliases("setusername", "name", "setname", "nickname", "nick")]
- [Description("Set FlawBOT's username")]
- public async Task SetBotUsername(CommandContext ctx,
- [Description("New bot username")] [RemainingText] string name)
- {
- var oldUsername = ctx.Client.CurrentUser.Username;
- if (string.IsNullOrWhiteSpace(name))
- {
- await ctx.Client.UpdateCurrentUserAsync(SharedData.Name).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, oldUsername + " username has been changed to " + SharedData.Name)
- .ConfigureAwait(false);
- }
- else
- {
- await ctx.Client.UpdateCurrentUserAsync(name).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx,
- oldUsername + " username has been changed to " + ctx.Client.CurrentUser.Username,
- EmbedType.Good)
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_USERNAME
-
- #endregion OWNERS-ONLY
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Modules/Server/RoleModule.cs b/src/FlawBOT.Core/Modules/Server/RoleModule.cs
deleted file mode 100644
index 2d727244..00000000
--- a/src/FlawBOT.Core/Modules/Server/RoleModule.cs
+++ /dev/null
@@ -1,287 +0,0 @@
-using System;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using DSharpPlus;
-using DSharpPlus.CommandsNext;
-using DSharpPlus.CommandsNext.Attributes;
-using DSharpPlus.Entities;
-using FlawBOT.Core.Properties;
-using FlawBOT.Framework.Models;
-using FlawBOT.Framework.Services;
-
-namespace FlawBOT.Modules
-{
- [Group("role")]
- [Aliases("roles", "rl")]
- [Description("Commands for controlling server roles")]
- [Cooldown(3, 5, CooldownBucketType.Guild)]
- public class RoleModule : BaseCommandModule
- {
- #region COMMAND_COLOR
-
- [Command("color")]
- [Aliases("clr")]
- [Description("Set the role color")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task ColorRole(CommandContext ctx,
- [Description("HEX color code to set for the role")] DiscordColor color,
- [Description("Server role to recolor")] [RemainingText] DiscordRole role)
- {
- var regex = new Regex(@"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", RegexOptions.Compiled).Match(color.ToString());
- if (regex.Success)
- {
- await role.ModifyAsync(color: color).ConfigureAwait(false);
- var output = new DiscordEmbedBuilder()
- .WithTitle("Successfully set the color for the role " + Formatter.Bold(role.Name) + " to " + Formatter.InlineCode(role.Color.ToString()))
- .WithColor(color);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- else
- {
- await BotServices.SendEmbedAsync(ctx, "Invalid color code. Please enter a HEX color code like #E7B53B", EmbedType.Warning).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_COLOR
-
- #region COMMAND_CREATE
-
- [Command("create")]
- [Aliases("new")]
- [Description("Create a server role")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task CreateRole(CommandContext ctx,
- [Description("New role name")] [RemainingText] string role = "")
- {
- if (string.IsNullOrWhiteSpace(role))
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_NAME, EmbedType.Warning).ConfigureAwait(false);
- }
- else
- {
- await ctx.Guild.CreateRoleAsync(role).ConfigureAwait(false);
- await BotServices
- .SendEmbedAsync(ctx, "Successfully created the server role " + Formatter.Bold(role), EmbedType.Good)
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_CREATE
-
- #region COMMAND_DELETE
-
- [Command("delete")]
- [Aliases("remove")]
- [Description("Delete a server role")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task DeleteRole(CommandContext ctx,
- [Description("Server role to delete")] [RemainingText] DiscordRole role = null)
- {
- if (role is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- await role.DeleteAsync().ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, "Successfully removed the server role " + Formatter.Bold(role.Name), EmbedType.Good)
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_DELETE
-
- #region COMMAND_INFO
-
- [Command("info")]
- [Aliases("i")]
- [Description("Retrieve role information")]
- public async Task GetRole(CommandContext ctx,
- [Description("Server role information to retrieve")] [RemainingText] DiscordRole role = null)
- {
- if (role is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- var output = new DiscordEmbedBuilder()
- .WithTitle(role.Name)
- .WithDescription("ID: " + role.Id)
- .AddField("Creation Date", role.CreationTimestamp.DateTime.ToString(CultureInfo.InvariantCulture), true)
- .AddField("Hoisted", role.IsHoisted ? "Yes" : "No", true)
- .AddField("Mentionable", role.IsMentionable ? "Yes" : "No", true)
- .AddField("Permissions", role.Permissions.ToPermissionString())
- .WithThumbnail(ctx.Guild.IconUrl)
- .WithFooter($"{ctx.Guild.Name} / #{ctx.Channel.Name} / {DateTime.Now}")
- .WithColor(role.Color);
- await ctx.RespondAsync(embed: output.Build()).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_INFO
-
- #region COMMAND_INROLE
-
- [Command("inrole")]
- [Description("Retrieve a list of users in a given role")]
- public async Task UsersInRole(CommandContext ctx,
- [Description("Server role")] [RemainingText] DiscordRole role = null)
- {
- if (role is null)
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_EXISTING, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- var userCount = 0;
- var usersList = new StringBuilder();
- var users = (await ctx.Guild.GetAllMembersAsync().ConfigureAwait(false)).ToArray();
- foreach (var user in users)
- if (user.Roles.Contains(role))
- {
- userCount++;
- if (user.Equals(users.Last()))
- usersList.Append(user.DisplayName);
- else
- usersList.Append(user.DisplayName).Append(", ");
- }
-
- if (usersList.Length == 0)
- await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " has no members")
- .ConfigureAwait(false);
- else
- await BotServices
- .SendEmbedAsync(ctx, Formatter.Bold(role.Name) + $" has **{userCount}** member(s): {usersList}")
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_INROLE
-
- #region COMMAND_MENTION
-
- [Command("mention")]
- [Description("Toggle whether this role can be mentioned by others")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task MentionRole(CommandContext ctx,
- [Description("Server role to toggle")] [RemainingText] DiscordRole role)
- {
- if (role is null) return;
- if (role.IsMentionable)
- {
- await role.ModifyAsync(mentionable: false).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **not-mentionable**")
- .ConfigureAwait(false);
- }
- else
- {
- await role.ModifyAsync(mentionable: true).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **mentionable**")
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_MENTION
-
- #region COMMAND_REVOKEROLE
-
- [Command("revoke")]
- [Description("Remove a role from server user")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task RemoveUserRole(CommandContext ctx,
- [Description("Server user to get revoked")] DiscordMember member,
- [Description("Server role to revoke from user")] [RemainingText] DiscordRole role)
- {
- if (role != null)
- {
- member = member ?? ctx.Member;
- await member.RevokeRoleAsync(role).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx,
- Formatter.Bold(member.DisplayName) + " has been removed from the role " + Formatter.Bold(role.Name),
- EmbedType.Good).ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_REVOKEROLE
-
- #region COMMAND_REVOKEROLES
-
- [Command("revokeall")]
- [Description("Remove all role from server user")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task RemoveUserRoles(CommandContext ctx,
- [Description("Server user to get revoked")] DiscordMember member)
- {
- if (!member.Roles.Any())
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_NONE, EmbedType.Warning).ConfigureAwait(false);
- }
- else if (member.Roles.Max(r => r.Position) >= ctx.Member.Roles.Max(r => r.Position))
- {
- await BotServices.SendEmbedAsync(ctx, Resources.ERR_ROLE_NOT_ALLOWED, EmbedType.Warning)
- .ConfigureAwait(false);
- }
- else
- {
- await member.ReplaceRolesAsync(Enumerable.Empty()).ConfigureAwait(false);
- await BotServices
- .SendEmbedAsync(ctx, "Removed all roles from " + Formatter.Bold(member.DisplayName), EmbedType.Good)
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_REVOKEROLES
-
- #region COMMAND_SETROLE
-
- [Command("setrole")]
- [Aliases("addrole", "sr")]
- [Description("Assign a role to server user")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task SetUserRole(CommandContext ctx,
- [Description("Server user to get role assigned")] DiscordMember member,
- [Description("Server role to assign to the user")] [RemainingText] DiscordRole role)
- {
- member = member ?? ctx.Member;
- await member.GrantRoleAsync(role).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, member.DisplayName + " been granted the role " + Formatter.Bold(role.Name), EmbedType.Good)
- .ConfigureAwait(false);
- }
-
- #endregion COMMAND_SETROLE
-
- #region COMMAND_SHOW
-
- [Command("show")]
- [Aliases("display", "hide")]
- [Description("Toggle whether this role is seen or not")]
- [RequirePermissions(Permissions.ManageRoles)]
- public async Task SidebarRole(CommandContext ctx,
- [Description("Server role to toggle")] [RemainingText] DiscordRole role)
- {
- if (role is null) return;
-
- if (role.IsHoisted)
- {
- await role.ModifyAsync(hoist: false).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **hidden**")
- .ConfigureAwait(false);
- }
- else
- {
- await role.ModifyAsync(hoist: true).ConfigureAwait(false);
- await BotServices.SendEmbedAsync(ctx, Formatter.Bold(role.Name) + " is now **displayed**")
- .ConfigureAwait(false);
- }
- }
-
- #endregion COMMAND_SHOW
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Core/NuGet.Config b/src/FlawBOT.Core/NuGet.Config
deleted file mode 100644
index a9c2d32f..00000000
--- a/src/FlawBOT.Core/NuGet.Config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/FlawBOT.Core/Properties/Resources.Designer.cs b/src/FlawBOT.Core/Properties/Resources.Designer.cs
deleted file mode 100644
index 58e4f504..00000000
--- a/src/FlawBOT.Core/Properties/Resources.Designer.cs
+++ /dev/null
@@ -1,398 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FlawBOT.Core.Properties {
- using System;
-
-
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- internal class Resources {
-
- private static global::System.Resources.ResourceManager resourceMan;
-
- private static global::System.Globalization.CultureInfo resourceCulture;
-
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
- internal Resources() {
- }
-
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
- get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FlawBOT.Core.Properties.Resources", typeof(Resources).Assembly);
- resourceMan = temp;
- }
- return resourceMan;
- }
- }
-
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
- get {
- return resourceCulture;
- }
- set {
- resourceCulture = value;
- }
- }
-
- ///
- /// Looks up a localized string similar to Channel with the same name already exists..
- ///
- internal static string ERR_CHANNEL_EXISTS {
- get {
- return ResourceManager.GetString("ERR_CHANNEL_EXISTS", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to The name cannot be blank or over 100 characters..
- ///
- internal static string ERR_CHANNEL_NAME {
- get {
- return ResourceManager.GetString("ERR_CHANNEL_NAME", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Channel topic must be less than 1024 characters long..
- ///
- internal static string ERR_CHANNEL_TOPIC {
- get {
- return ResourceManager.GetString("ERR_CHANNEL_TOPIC", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Invalid color code. Please enter a HEX color code like #E7B53B..
- ///
- internal static string ERR_COLOR_INVALID {
- get {
- return ResourceManager.GetString("ERR_COLOR_INVALID", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Unable to reach the Dog.CEO API..
- ///
- internal static string ERR_DOG_PHOTO {
- get {
- return ResourceManager.GetString("ERR_DOG_PHOTO", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Unable to create the server emoji. Either the HTTP request failed or Discord prevented the operation from completing..
- ///
- internal static string ERR_EMOJI_ADD {
- get {
- return ResourceManager.GetString("ERR_EMOJI_ADD", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Please provide a URL pointing to an emoji image or attach an image..
- ///
- internal static string ERR_EMOJI_IMAGE {
- get {
- return ResourceManager.GetString("ERR_EMOJI_IMAGE", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Server emoji name is invalid..
- ///
- internal static string ERR_EMOJI_NAME {
- get {
- return ResourceManager.GetString("ERR_EMOJI_NAME", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Unable to create the server emoji. Either the image size was too large..
- ///
- internal static string ERR_EMOJI_SIZE {
- get {
- return ResourceManager.GetString("ERR_EMOJI_SIZE", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Exception occurred: {0} :
- ///{1}.
- ///
- internal static string ERR_EXCEPTION {
- get {
- return ResourceManager.GetString("ERR_EXCEPTION", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Inner exception: {0} :
- ///{1}.
- ///
- internal static string ERR_EXCEPTION_INNER {
- get {
- return ResourceManager.GetString("ERR_EXCEPTION_INNER", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Error calculating math equation, make sure your values are integers and the operation is valid!.
- ///
- internal static string ERR_MATH_EQUATION {
- get {
- return ResourceManager.GetString("ERR_MATH_EQUATION", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Unable to reach the NASA API..
- ///
- internal static string ERR_NASA_API {
- get {
- return ResourceManager.GetString("ERR_NASA_API", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Please provide a poll question..
- ///
- internal static string ERR_POLL_QUESTION {
- get {
- return ResourceManager.GetString("ERR_POLL_QUESTION", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Please provide more information on the issue (50 characters minimum)..
- ///
- internal static string ERR_REPORT_CHAR_LENGTH {
- get {
- return ResourceManager.GetString("ERR_REPORT_CHAR_LENGTH", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Please provide an existing server role..
- ///
- internal static string ERR_ROLE_EXISTING {
- get {
- return ResourceManager.GetString("ERR_ROLE_EXISTING", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Role name cannot be blank..
- ///
- internal static string ERR_ROLE_NAME {
- get {
- return ResourceManager.GetString("ERR_ROLE_NAME", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to This user doesn't have any roles..
- ///
- internal static string ERR_ROLE_NONE {
- get {
- return ResourceManager.GetString("ERR_ROLE_NONE", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to You are unauthorized to remove roles from this user..
- ///
- internal static string ERR_ROLE_NOT_ALLOWED {
- get {
- return ResourceManager.GetString("ERR_ROLE_NOT_ALLOWED", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Invalid connection info, follow the format: 123.345.56.789:000; password hello.
- ///
- internal static string ERR_STEAM_CONNECT_FORMAT {
- get {
- return ResourceManager.GetString("ERR_STEAM_CONNECT_FORMAT", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Shutting Down.
- ///
- internal static string INFO_SHUTDOWN {
- get {
- return ResourceManager.GetString("INFO_SHUTDOWN", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Emoji not found in the server list..
- ///
- internal static string NOT_FOUND_EMOJI {
- get {
- return ResourceManager.GetString("NOT_FOUND_EMOJI", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to No results found..
- ///
- internal static string NOT_FOUND_GENERIC {
- get {
- return ResourceManager.GetString("NOT_FOUND_GENERIC", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Location not found..
- ///
- internal static string NOT_FOUND_LOCATION {
- get {
- return ResourceManager.GetString("NOT_FOUND_LOCATION", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Reddit post not found..
- ///
- internal static string NOT_FOUND_REDDIT {
- get {
- return ResourceManager.GetString("NOT_FOUND_REDDIT", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Subreddit not found..
- ///
- internal static string NOT_FOUND_SUBREDDIT {
- get {
- return ResourceManager.GetString("NOT_FOUND_SUBREDDIT", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Twitch channel is offline or was not found..
- ///
- internal static string NOT_FOUND_TWITCH {
- get {
- return ResourceManager.GetString("NOT_FOUND_TWITCH", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Wikipedia page not found..
- ///
- internal static string NOT_FOUND_WIKIPEDIA {
- get {
- return ResourceManager.GetString("NOT_FOUND_WIKIPEDIA", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Request timed out....
- ///
- internal static string REQUEST_TIMEOUT {
- get {
- return ResourceManager.GetString("REQUEST_TIMEOUT", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to Note: First time gifs take a few minutes to properly generate..
- ///
- internal static string SIMPSONS_GIF_WARNING {
- get {
- return ResourceManager.GetString("SIMPSONS_GIF_WARNING", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://discord.gg/.
- ///
- internal static string URL_DISCORD {
- get {
- return ResourceManager.GetString("URL_DISCORD", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://steamcommunity.com/groups/.
- ///
- internal static string URL_STEAM_GROUP {
- get {
- return ResourceManager.GetString("URL_STEAM_GROUP", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://steamcommunity.com/id/.
- ///
- internal static string URL_STEAM_USER {
- get {
- return ResourceManager.GetString("URL_STEAM_USER", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://teamwork.tf/community/customserverlist/.
- ///
- internal static string URL_TEAMWORK_SERVERS {
- get {
- return ResourceManager.GetString("URL_TEAMWORK_SERVERS", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://www.twitch.tv/.
- ///
- internal static string URL_TWITCH_CHANNEL {
- get {
- return ResourceManager.GetString("URL_TWITCH_CHANNEL", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://twitter.com/.
- ///
- internal static string URL_TWITTER {
- get {
- return ResourceManager.GetString("URL_TWITTER", resourceCulture);
- }
- }
-
- ///
- /// Looks up a localized string similar to https://www.youtube.com/channel/.
- ///
- internal static string URL_YOUTUBE_CHANNEL {
- get {
- return ResourceManager.GetString("URL_YOUTUBE_CHANNEL", resourceCulture);
- }
- }
- }
-}
diff --git a/src/FlawBOT.Framework/FlawBOT.Framework.csproj b/src/FlawBOT.Framework/FlawBOT.Framework.csproj
deleted file mode 100644
index f8724e49..00000000
--- a/src/FlawBOT.Framework/FlawBOT.Framework.csproj
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
- netcoreapp3.1
- 2.6.1.0
- 2.6.1
- 2.6.1.0
- Igor Nikitin
- CriticalFlaw
- FlawBOT
- Multipurpose Discord bot written in C# using DSharpPlus. Application Framework.
- https://discordbots.org/bot/339833029013012483
- https://github.com/CriticalFlaw/FlawBOT
- en-CA
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- Resources.resx
-
-
-
-
-
- ResXFileCodeGenerator
- Resources.Designer.cs
-
-
-
-
diff --git a/src/FlawBOT.Framework/Models/Games/AmiiboData.cs b/src/FlawBOT.Framework/Models/Games/AmiiboData.cs
deleted file mode 100644
index aaa0bccd..00000000
--- a/src/FlawBOT.Framework/Models/Games/AmiiboData.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Newtonsoft.Json;
-using System.Collections.Generic;
-
-namespace FlawBOT.Framework.Models
-{
- public class AmiiboData
- {
- [JsonProperty("amiibo")]
- public List Amiibo { get; set; }
- }
-
- public class Amiibo
- {
- [JsonProperty("amiiboSeries")]
- public string AmiiboSeries { get; set; }
-
- [JsonProperty("gameSeries")]
- public string GameSeries { get; set; }
-
- [JsonProperty("image")]
- public string Image { get; set; }
-
- [JsonProperty("name")]
- public string Name { get; set; }
-
- [JsonProperty("release")]
- public Release ReleaseDate { get; set; }
- }
-
- public class Release
- {
- [JsonProperty("au")]
- public string Australian { get; set; }
-
- [JsonProperty("eu")]
- public string European { get; set; }
-
- [JsonProperty("jp")]
- public string Japanese { get; set; }
-
- [JsonProperty("na")]
- public string American { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Framework/Models/Games/PokemonData.cs b/src/FlawBOT.Framework/Models/Games/PokemonData.cs
deleted file mode 100644
index c89955a7..00000000
--- a/src/FlawBOT.Framework/Models/Games/PokemonData.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-using Newtonsoft.Json;
-using System.Collections.Generic;
-
-namespace FlawBOT.Framework.Models
-{
- public class PokemonCards
- {
- [JsonProperty("cards")]
- public List Cards { get; set; }
- }
-
- public class Card
- {
- [JsonProperty("id")]
- public string Id { get; set; }
- }
-
- public class PokemonData
- {
- [JsonProperty("results")]
- public List Results { get; set; }
- }
-
- public class DataResult
- {
- [JsonProperty("name")]
- public string Name { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/FlawBOT.Framework/Models/Games/SpeedrunData.cs b/src/FlawBOT.Framework/Models/Games/SpeedrunData.cs
deleted file mode 100644
index a63aef59..00000000
--- a/src/FlawBOT.Framework/Models/Games/SpeedrunData.cs
+++ /dev/null
@@ -1,221 +0,0 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-
-namespace FlawBOT.Framework.Models
-{
- #region GAME
-
- public class SpeedrunGame
- {
- [JsonProperty("data")]
- public List Data { get; set; }
- }
-
- public class Data
- {
- [JsonProperty("id")]
- public string Id { get; set; }
-
- [JsonProperty("names")]
- public Names Names { get; set; }
-
- [JsonProperty("abbreviation")]
- public string Abbreviation { get; set; }
-
- [JsonProperty("weblink")]
- public string WebLink { get; set; }
-
- [JsonProperty("release-date")]
- public string ReleaseDate { get; set; }
-
- [JsonProperty("platforms")]
- public List