diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index 2e90dd2..1076a02 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; -using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; @@ -23,7 +22,6 @@ public class Program { private static bool loadPluginsOnStartup; private static ConsoleCommandsHandler consoleCommandsHandler; - //private static bool isUI_ON; /// /// The main entry point for the application. @@ -222,7 +220,14 @@ public class Program var currentVersion = Config.Data["Version"]; if (!newVersion.Equals(currentVersion)) { - + var nVer = new VersionString(newVersion.Substring(2)); + var cVer = new VersionString((Config.Data["Version"]).Substring(2)); + if (cVer > nVer) + { + Config.Data["Version"] = "1." + cVer.ToShortString() + " (Beta)"; + break; + } + if (OperatingSystem.WINDOWS == Functions.GetOperatingSystem()) { Console.Clear(); @@ -237,13 +242,6 @@ public class Program break; } - var nVer = new VersionString(newVersion.Substring(2)); - var cVer = new VersionString((Config.Data["Version"]).Substring(2)); - if (cVer > nVer) - { - Config.Data["version"] = "1." + cVer.ToShortString() + " (Beta)"; - break; - } Console.Clear(); Console.ForegroundColor = ConsoleColor.Red; diff --git a/DiscordBotPlugins/Economy/Commands/Balance.cs b/DiscordBotPlugins/Economy/Commands/Balance.cs new file mode 100644 index 0000000..7653790 --- /dev/null +++ b/DiscordBotPlugins/Economy/Commands/Balance.cs @@ -0,0 +1,72 @@ +using Discord; +using PluginManager.Interfaces; +using Discord.WebSocket; +namespace Economy.Commands; + +public class Balance : DBSlashCommand +{ + public string Name => "balance"; + + public string Description => "Change or view info about your balance"; + + public bool canUseDM => false; // server only + + public List Options => new List() + { + new SlashCommandOptionBuilder(){Name="send", Description="Send money to another user", Type=ApplicationCommandOptionType.SubCommand, Options=new List() + { + new SlashCommandOptionBuilder(){Name="user", Description="The user to send money to", Type=ApplicationCommandOptionType.User, IsRequired=true}, + new SlashCommandOptionBuilder(){Name="amount", Description="The amount of money to send", Type=ApplicationCommandOptionType.Number, IsRequired=true} + }}, + + new SlashCommandOptionBuilder(){Name="info", Description="View info about your balance", Type=ApplicationCommandOptionType.SubCommand} + }; + + public async void ExecuteServer(SocketSlashCommand context) + { + var option = context.Data.Options.FirstOrDefault(); + var guild = context.User.MutualGuilds.FirstOrDefault(g => g.Id == context.GuildId); + if (option.Name == "send") + { + var options = option.Options.ToArray(); + Console.WriteLine(options.Length); + var user = options[0].Value as IUser; + var amount = options[1].Value as float?; + + if (amount == null) + { + await context.RespondAsync("The amount is invalid"); + return; + } + + if (user == null) + { + await context.RespondAsync("The user is invalid"); + return; + } + + if (user.Id == context.User.Id) + { + await context.RespondAsync("You can't send money to yourself"); + return; + } + + var balance = await Engine.GetBalance(context.User.Id); + if (balance < amount) + { + await context.RespondAsync("You don't have enough money to send"); + return; + } + + await Engine.RemoveMoney(context.User.Id, amount.Value); + await Engine.AddMoney(user.Id, amount.Value); + + await context.RespondAsync($"You sent {amount} to {guild.GetUser(user.Id).Mention}"); + } + else if (option.Name == "info") + { + var balance = await Engine.GetBalance(context.User.Id); + await context.RespondAsync($"Your balance is {balance}"); + } + } +} diff --git a/DiscordBotPlugins/Economy/Economy.csproj b/DiscordBotPlugins/Economy/Economy.csproj new file mode 100644 index 0000000..3c7c46a --- /dev/null +++ b/DiscordBotPlugins/Economy/Economy.csproj @@ -0,0 +1,10 @@ + + + + + + net6.0 + enable + enable + + \ No newline at end of file diff --git a/DiscordBotPlugins/Economy/Engine.cs b/DiscordBotPlugins/Economy/Engine.cs new file mode 100644 index 0000000..f22b778 --- /dev/null +++ b/DiscordBotPlugins/Economy/Engine.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; + +using PluginManager.Database; + +namespace Economy; +public static class Engine +{ + public static SqlDatabase Database { get; set; } + + public static async void AddUser(ulong userID) + { + await Database.InsertAsync("UserBank", userID.ToString(), "0"); + } + + public static async void RemoveUser(ulong userID) + { + await Database.RemoveKeyAsync("UserBank", "UserID", userID.ToString()); + } + + public static async Task AddMoney(ulong userID, float amount) + { + var balance = await Database.GetValueAsync("UserBank", "UserID", userID.ToString(), "Balance"); + if (balance == null) + { + AddUser(userID); + balance = "0"; + } + + var float_balance = float.Parse(balance); + float_balance += amount; + await Database.SetValueAsync("UserBank", "UserID", userID.ToString(), "Balance", float_balance.ToString()); + } + + public static async Task RemoveMoney(ulong userID, float amount) + { + var balance = await Database.GetValueAsync("UserBank", "UserID", userID.ToString(), "Balance"); + if (balance == null) + { + AddUser(userID); + balance = "0"; + } + + var float_balance = float.Parse(balance); + float_balance -= amount; + await Database.SetValueAsync("UserBank", "UserID", userID.ToString(), "Balance", float_balance.ToString()); + } + + public static async Task GetBalance(ulong userID) + { + var balance = await Database.GetValueAsync("UserBank", "UserID", userID.ToString(), "Balance"); + if (balance == null) + { + AddUser(userID); + balance = "0"; + } + + return float.Parse(balance); + } + + +} diff --git a/DiscordBotPlugins/Economy/Entry.cs b/DiscordBotPlugins/Economy/Entry.cs new file mode 100644 index 0000000..882c5c7 --- /dev/null +++ b/DiscordBotPlugins/Economy/Entry.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using PluginManager.Interfaces; +using PluginManager.Database; + +namespace Economy +{ + public class EntryEvent : DBEvent + { + public string Name => "Economy Plugin Engine"; + + public string Description => "The economy plugin main engine"; + + public async void Start(global::Discord.WebSocket.DiscordSocketClient client) + { + Console.WriteLine("Economy Plugin Engine Started"); + Directory.CreateDirectory(PluginManager.Others.Functions.dataFolder + "/Economy"); + Engine.Database = new SqlDatabase(PluginManager.Others.Functions.dataFolder + "/Economy/Economy.db"); + await Engine.Database.Open(); + await Engine.Database.CreateTableAsync("UserBank", "UserID INT", "Balance FLOAT"); + + client.Disconnected += (e) => + { + Engine.Database.Stop(); + return Task.CompletedTask; + }; + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 5583792..961919f 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,12 @@ Plugin Types: ### How to create a plugin -First of all, Create a new project (class library) in Visual Studio. -Then import the PluginManager.dll as project to your project. +First of all, create a new project (class library) in Visual Studio. +Then import the PluginManager as reference to your project. ## 1. Commands -Commands are loaded when all plugins are loaded into memory. When an user executes the command, only then the Execute function is called. +Commands are loaded when all plugins are loaded into memory. The Execute method is called whenever any user (that respects the `requireAdmin` propery) calls the command using the bot prefix and the `Command`. Commands are plugins that allow users to interact with them. Here is an example: ```cs @@ -90,7 +90,7 @@ internal class LevelCommand : DBCommand - context - the command context From here on, start coding. When your plugin is done, build it as any DLL project then add it to the following path -`{bot_executable}/Data/Plugins//[your dll name].dll` +`{bot_executable}/Data/Plugins//[plugin name].dll` Then, reload bot and execute command `lp` in bot's console. The plugin should be loaded into memory or an error is thrown if not. If an error is thrown, then there is something wrong in your command's code. @@ -112,8 +112,6 @@ public class OnUserJoin : DBEvent public async void Start(Discord.WebSocket.DiscordSocketClient client) { - Console.WriteLine($"Hello World from {name}"); - client.UserJoined += async (user) => { await (await user.CreateDMChannelAsync()).SendMessageAsync("Welcome to server !"); }; @@ -185,3 +183,10 @@ namespace SlashCommands - context - the command context - ExecuteDM() - this function will be called if the command is invoked in a DM channel (optional) - context - the command context + + +## Note: +You can create multiple commands, events and slash commands into one single plugin (class library). The PluginManager will detect the classes and load them individualy. If there are more commands (normal commands, events or slash commands) into a single project (class library) they can use the same resources (a class for example) that is contained within the plugin. + + +> Updated: 5.04.2023 \ No newline at end of file diff --git a/SethDiscordBot.sln b/SethDiscordBot.sln index 5a6a5b4..5947a59 100644 --- a/SethDiscordBot.sln +++ b/SethDiscordBot.sln @@ -7,6 +7,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBot", "DiscordBot\Di EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginManager", "PluginManager\PluginManager.csproj", "{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DiscordBotPlugins", "DiscordBotPlugins", "{9239AF3F-3349-4924-98DC-7F512DF9AAF3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Economy", "DiscordBotPlugins\Economy\Economy.csproj", "{0B623D5E-2BAC-4B2D-8215-4F9B5A1C6527}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +25,10 @@ Global {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Debug|Any CPU.Build.0 = Debug|Any CPU {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Release|Any CPU.ActiveCfg = Release|Any CPU {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Release|Any CPU.Build.0 = Release|Any CPU + {0B623D5E-2BAC-4B2D-8215-4F9B5A1C6527}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B623D5E-2BAC-4B2D-8215-4F9B5A1C6527}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B623D5E-2BAC-4B2D-8215-4F9B5A1C6527}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B623D5E-2BAC-4B2D-8215-4F9B5A1C6527}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -28,4 +36,7 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF} EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {0B623D5E-2BAC-4B2D-8215-4F9B5A1C6527} = {9239AF3F-3349-4924-98DC-7F512DF9AAF3} + EndGlobalSection EndGlobal