From 84ee5c62355eab9cd0d8b7952f8a55cc70162e9c Mon Sep 17 00:00:00 2001 From: Wizzy69 <45517207+Wizzy69@users.noreply.github.com> Date: Fri, 7 Jan 2022 20:26:10 +0200 Subject: [PATCH] Add project files. --- BUILDS/net5.0/CMD_LevelingSystem.deps.json | 268 ++++++++++ BUILDS/net5.0/CMD_LevelingSystem.dll | Bin 0 -> 10240 bytes BUILDS/net5.0/CMD_Utils.deps.json | 268 ++++++++++ BUILDS/net5.0/CMD_Utils.dll | Bin 0 -> 9216 bytes BUILDS/net5.0/EVE_LevelingSystem.deps.json | 268 ++++++++++ BUILDS/net5.0/EVE_LevelingSystem.dll | Bin 0 -> 9728 bytes BUILDS/net5.0/PluginManager.dll | Bin 0 -> 36864 bytes BUILDS/net5.0/StartupEvents.deps.json | 268 ++++++++++ BUILDS/net5.0/StartupEvents.dll | Bin 0 -> 12800 bytes BUILDS/net5.0/ref/CMD_LevelingSystem.dll | Bin 0 -> 6656 bytes BUILDS/net5.0/ref/CMD_Utils.dll | Bin 0 -> 6656 bytes BUILDS/net5.0/ref/EVE_LevelingSystem.dll | Bin 0 -> 6144 bytes BUILDS/net5.0/ref/StartupEvents.dll | Bin 0 -> 6144 bytes CMD_LevelingSystem/CMD_LevelingSystem.csproj | 19 + CMD_LevelingSystem/Commands/level.cs | 55 ++ .../Items/Leveling System/Core.cs | 62 +++ .../Items/Leveling System/Data.cs | 24 + CMD_Utils/CMD_Utils.csproj | 15 + CMD_Utils/Echo.cs | 22 + CMD_Utils/FlipCoin.cs | 35 ++ CMD_Utils/Random.cs | 40 ++ DiscordBot.sln | 69 +++ DiscordBot/App.config | 6 + DiscordBot/Discord/Commands/Help.cs | 37 ++ DiscordBot/Discord/Core/Boot.cs | 113 +++++ DiscordBot/Discord/Core/CommandHandler.cs | 85 ++++ DiscordBot/DiscordBot.csproj | 35 ++ DiscordBot/Program.cs | 469 ++++++++++++++++++ EVE_LevelingSystem/Core.cs | 62 +++ EVE_LevelingSystem/Data.cs | 24 + EVE_LevelingSystem/EVE_LevelingSystem.csproj | 17 + EVE_LevelingSystem/LevelingSystem.cs | 36 ++ PluginManager/Interfaces/DBCommand.cs | 19 + PluginManager/Interfaces/DBEvent.cs | 12 + PluginManager/Items/CustomProgressBar.cs | 27 + PluginManager/Items/Spinner.cs | 40 ++ PluginManager/Language System/Language.cs | 69 +++ PluginManager/Loaders/CommandsLoader.cs | 82 +++ PluginManager/Loaders/EventsLoader.cs | 84 ++++ PluginManager/Loaders/PluginLoader.cs | 86 ++++ PluginManager/Online/Downloader.cs | 82 +++ PluginManager/Online/LanguageManager.cs | 75 +++ PluginManager/Online/PluginsManager.cs | 108 ++++ PluginManager/Others/Channels.cs | 15 + PluginManager/Others/Cryptography.cs | 44 ++ PluginManager/Others/Enums.cs | 14 + .../Others/Exceptions/APIException.cs | 37 ++ PluginManager/Others/Functions.cs | 300 +++++++++++ PluginManager/Others/Permissions.cs | 20 + PluginManager/PluginManager.csproj | 12 + StartupEvents/OnUserJoin.cs | 56 +++ StartupEvents/SetGameOnLogin.cs | 48 ++ StartupEvents/StartupEvents.csproj | 17 + 53 files changed, 3544 insertions(+) create mode 100644 BUILDS/net5.0/CMD_LevelingSystem.deps.json create mode 100644 BUILDS/net5.0/CMD_LevelingSystem.dll create mode 100644 BUILDS/net5.0/CMD_Utils.deps.json create mode 100644 BUILDS/net5.0/CMD_Utils.dll create mode 100644 BUILDS/net5.0/EVE_LevelingSystem.deps.json create mode 100644 BUILDS/net5.0/EVE_LevelingSystem.dll create mode 100644 BUILDS/net5.0/PluginManager.dll create mode 100644 BUILDS/net5.0/StartupEvents.deps.json create mode 100644 BUILDS/net5.0/StartupEvents.dll create mode 100644 BUILDS/net5.0/ref/CMD_LevelingSystem.dll create mode 100644 BUILDS/net5.0/ref/CMD_Utils.dll create mode 100644 BUILDS/net5.0/ref/EVE_LevelingSystem.dll create mode 100644 BUILDS/net5.0/ref/StartupEvents.dll create mode 100644 CMD_LevelingSystem/CMD_LevelingSystem.csproj create mode 100644 CMD_LevelingSystem/Commands/level.cs create mode 100644 CMD_LevelingSystem/Items/Leveling System/Core.cs create mode 100644 CMD_LevelingSystem/Items/Leveling System/Data.cs create mode 100644 CMD_Utils/CMD_Utils.csproj create mode 100644 CMD_Utils/Echo.cs create mode 100644 CMD_Utils/FlipCoin.cs create mode 100644 CMD_Utils/Random.cs create mode 100644 DiscordBot.sln create mode 100644 DiscordBot/App.config create mode 100644 DiscordBot/Discord/Commands/Help.cs create mode 100644 DiscordBot/Discord/Core/Boot.cs create mode 100644 DiscordBot/Discord/Core/CommandHandler.cs create mode 100644 DiscordBot/DiscordBot.csproj create mode 100644 DiscordBot/Program.cs create mode 100644 EVE_LevelingSystem/Core.cs create mode 100644 EVE_LevelingSystem/Data.cs create mode 100644 EVE_LevelingSystem/EVE_LevelingSystem.csproj create mode 100644 EVE_LevelingSystem/LevelingSystem.cs create mode 100644 PluginManager/Interfaces/DBCommand.cs create mode 100644 PluginManager/Interfaces/DBEvent.cs create mode 100644 PluginManager/Items/CustomProgressBar.cs create mode 100644 PluginManager/Items/Spinner.cs create mode 100644 PluginManager/Language System/Language.cs create mode 100644 PluginManager/Loaders/CommandsLoader.cs create mode 100644 PluginManager/Loaders/EventsLoader.cs create mode 100644 PluginManager/Loaders/PluginLoader.cs create mode 100644 PluginManager/Online/Downloader.cs create mode 100644 PluginManager/Online/LanguageManager.cs create mode 100644 PluginManager/Online/PluginsManager.cs create mode 100644 PluginManager/Others/Channels.cs create mode 100644 PluginManager/Others/Cryptography.cs create mode 100644 PluginManager/Others/Enums.cs create mode 100644 PluginManager/Others/Exceptions/APIException.cs create mode 100644 PluginManager/Others/Functions.cs create mode 100644 PluginManager/Others/Permissions.cs create mode 100644 PluginManager/PluginManager.csproj create mode 100644 StartupEvents/OnUserJoin.cs create mode 100644 StartupEvents/SetGameOnLogin.cs create mode 100644 StartupEvents/StartupEvents.csproj diff --git a/BUILDS/net5.0/CMD_LevelingSystem.deps.json b/BUILDS/net5.0/CMD_LevelingSystem.deps.json new file mode 100644 index 0000000..85f25c7 --- /dev/null +++ b/BUILDS/net5.0/CMD_LevelingSystem.deps.json @@ -0,0 +1,268 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "CMD_LevelingSystem/1.0.0": { + "dependencies": { + "PluginManager": "1.0.0" + }, + "runtime": { + "CMD_LevelingSystem.dll": {} + } + }, + "Discord.Net/3.1.0": { + "dependencies": { + "Discord.Net.Commands": "3.1.0", + "Discord.Net.Core": "3.1.0", + "Discord.Net.Interactions": "3.1.0", + "Discord.Net.Rest": "3.1.0", + "Discord.Net.WebSocket": "3.1.0", + "Discord.Net.Webhook": "3.1.0" + } + }, + "Discord.Net.Commands/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Commands.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Core/3.1.0": { + "dependencies": { + "Newtonsoft.Json": "13.0.1", + "System.Collections.Immutable": "5.0.0", + "System.Interactive.Async": "5.0.0", + "System.ValueTuple": "4.5.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Core.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Interactions/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0", + "Discord.Net.WebSocket": "3.1.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", + "System.Collections.Immutable": "5.0.0", + "System.Reactive": "5.0.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Interactions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Rest/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Rest.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Webhook/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Webhook.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.WebSocket/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.WebSocket.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "System.Collections.Immutable/5.0.0": {}, + "System.Interactive.Async/5.0.0": { + "dependencies": { + "System.Linq.Async": "5.0.0" + }, + "runtime": { + "lib/netcoreapp3.1/System.Interactive.Async.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.Linq.Async/5.0.0": { + "runtime": { + "lib/netcoreapp3.1/System.Linq.Async.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.Reactive/5.0.0": { + "runtime": { + "lib/net5.0/System.Reactive.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.ValueTuple/4.5.0": {}, + "PluginManager/1.0.0": { + "dependencies": { + "Discord.Net": "3.1.0" + }, + "runtime": { + "PluginManager.dll": {} + } + } + } + }, + "libraries": { + "CMD_LevelingSystem/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Discord.Net/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GAY7d+k8UN5BsObGpysvg7ca6YwTqvesTouM8S8eBWSmwGnK38iceVkURg0QNAG70tlJ4w8S/BOjocRRvXU2MQ==", + "path": "discord.net/3.1.0", + "hashPath": "discord.net.3.1.0.nupkg.sha512" + }, + "Discord.Net.Commands/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EZdtrAqj6Uspyz4CvIwFP/UQ4XUpXjIPG1b5LrfAKOo12ks4k6XO7up2h+UsHexk7mEz4sfZxkEXGrW6PSh+/Q==", + "path": "discord.net.commands/3.1.0", + "hashPath": "discord.net.commands.3.1.0.nupkg.sha512" + }, + "Discord.Net.Core/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Oxz3CiWVvenSaHRYZeCKgRqzcWqdjGYmpxVVN2vPikt6bTN+xHAR4jczk8plKDDdINt7Lac37iLsRaqzUtJZpQ==", + "path": "discord.net.core/3.1.0", + "hashPath": "discord.net.core.3.1.0.nupkg.sha512" + }, + "Discord.Net.Interactions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XzLChVRQGniUU8kdLMDYEOjifzvrcsOiAdKm/pO/PGPpZSMWSzPWlJUWaQlWMtOImrYULzRejOeoc2/3K3R30Q==", + "path": "discord.net.interactions/3.1.0", + "hashPath": "discord.net.interactions.3.1.0.nupkg.sha512" + }, + "Discord.Net.Rest/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-97kdAYjlNuuOnhRQW/OoGK2oBObvpzZlCSPJjIcI4DneEq6k2WIFhG00fvxK7DCVTlB5BgBMAT1BeRUk4/rUxQ==", + "path": "discord.net.rest/3.1.0", + "hashPath": "discord.net.rest.3.1.0.nupkg.sha512" + }, + "Discord.Net.Webhook/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cZFxFf9H3GUBITlx1b7IskglgjJxSYpOIZOtyVW2WnPp7LpnxlOi1piRG22fH9fdhCC/RyDx3gZtYfN6WzacCw==", + "path": "discord.net.webhook/3.1.0", + "hashPath": "discord.net.webhook.3.1.0.nupkg.sha512" + }, + "Discord.Net.WebSocket/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-6OsLNXHNKC/laDKoBD+T0Km0vzqHaCcBOaI/NA8Qsed935MtEOTy7juorF22gF6TYOeoclUgSINrHCY4zWvxpA==", + "path": "discord.net.websocket/3.1.0", + "hashPath": "discord.net.websocket.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", + "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "System.Collections.Immutable/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==", + "path": "system.collections.immutable/5.0.0", + "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512" + }, + "System.Interactive.Async/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QaqhQVDiULcu4vm6o89+iP329HcK44cETHOYgy/jfEjtzeFy0ZxmuM7nel9ocjnKxEM4yh1mli7hgh8Q9o+/Iw==", + "path": "system.interactive.async/5.0.0", + "hashPath": "system.interactive.async.5.0.0.nupkg.sha512" + }, + "System.Linq.Async/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cPtIuuH8TIjVHSi2ewwReWGW1PfChPE0LxPIDlfwVcLuTM9GANFTXiMB7k3aC4sk3f0cQU25LNKzx+jZMxijqw==", + "path": "system.linq.async/5.0.0", + "hashPath": "system.linq.async.5.0.0.nupkg.sha512" + }, + "System.Reactive/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==", + "path": "system.reactive/5.0.0", + "hashPath": "system.reactive.5.0.0.nupkg.sha512" + }, + "System.ValueTuple/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==", + "path": "system.valuetuple/4.5.0", + "hashPath": "system.valuetuple.4.5.0.nupkg.sha512" + }, + "PluginManager/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/BUILDS/net5.0/CMD_LevelingSystem.dll b/BUILDS/net5.0/CMD_LevelingSystem.dll new file mode 100644 index 0000000000000000000000000000000000000000..7fd2b21338f8eaa0499b64693e6c304b90ca9205 GIT binary patch literal 10240 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 literal 0 HcmV?d00001 diff --git a/BUILDS/net5.0/CMD_Utils.deps.json b/BUILDS/net5.0/CMD_Utils.deps.json new file mode 100644 index 0000000..6dd7496 --- /dev/null +++ b/BUILDS/net5.0/CMD_Utils.deps.json @@ -0,0 +1,268 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "CMD_Utils/1.0.0": { + "dependencies": { + "PluginManager": "1.0.0" + }, + "runtime": { + "CMD_Utils.dll": {} + } + }, + "Discord.Net/3.1.0": { + "dependencies": { + "Discord.Net.Commands": "3.1.0", + "Discord.Net.Core": "3.1.0", + "Discord.Net.Interactions": "3.1.0", + "Discord.Net.Rest": "3.1.0", + "Discord.Net.WebSocket": "3.1.0", + "Discord.Net.Webhook": "3.1.0" + } + }, + "Discord.Net.Commands/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Commands.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Core/3.1.0": { + "dependencies": { + "Newtonsoft.Json": "13.0.1", + "System.Collections.Immutable": "5.0.0", + "System.Interactive.Async": "5.0.0", + "System.ValueTuple": "4.5.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Core.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Interactions/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0", + "Discord.Net.WebSocket": "3.1.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", + "System.Collections.Immutable": "5.0.0", + "System.Reactive": "5.0.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Interactions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Rest/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Rest.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Webhook/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Webhook.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.WebSocket/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.WebSocket.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "System.Collections.Immutable/5.0.0": {}, + "System.Interactive.Async/5.0.0": { + "dependencies": { + "System.Linq.Async": "5.0.0" + }, + "runtime": { + "lib/netcoreapp3.1/System.Interactive.Async.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.Linq.Async/5.0.0": { + "runtime": { + "lib/netcoreapp3.1/System.Linq.Async.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.Reactive/5.0.0": { + "runtime": { + "lib/net5.0/System.Reactive.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.ValueTuple/4.5.0": {}, + "PluginManager/1.0.0": { + "dependencies": { + "Discord.Net": "3.1.0" + }, + "runtime": { + "PluginManager.dll": {} + } + } + } + }, + "libraries": { + "CMD_Utils/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Discord.Net/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GAY7d+k8UN5BsObGpysvg7ca6YwTqvesTouM8S8eBWSmwGnK38iceVkURg0QNAG70tlJ4w8S/BOjocRRvXU2MQ==", + "path": "discord.net/3.1.0", + "hashPath": "discord.net.3.1.0.nupkg.sha512" + }, + "Discord.Net.Commands/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EZdtrAqj6Uspyz4CvIwFP/UQ4XUpXjIPG1b5LrfAKOo12ks4k6XO7up2h+UsHexk7mEz4sfZxkEXGrW6PSh+/Q==", + "path": "discord.net.commands/3.1.0", + "hashPath": "discord.net.commands.3.1.0.nupkg.sha512" + }, + "Discord.Net.Core/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Oxz3CiWVvenSaHRYZeCKgRqzcWqdjGYmpxVVN2vPikt6bTN+xHAR4jczk8plKDDdINt7Lac37iLsRaqzUtJZpQ==", + "path": "discord.net.core/3.1.0", + "hashPath": "discord.net.core.3.1.0.nupkg.sha512" + }, + "Discord.Net.Interactions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XzLChVRQGniUU8kdLMDYEOjifzvrcsOiAdKm/pO/PGPpZSMWSzPWlJUWaQlWMtOImrYULzRejOeoc2/3K3R30Q==", + "path": "discord.net.interactions/3.1.0", + "hashPath": "discord.net.interactions.3.1.0.nupkg.sha512" + }, + "Discord.Net.Rest/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-97kdAYjlNuuOnhRQW/OoGK2oBObvpzZlCSPJjIcI4DneEq6k2WIFhG00fvxK7DCVTlB5BgBMAT1BeRUk4/rUxQ==", + "path": "discord.net.rest/3.1.0", + "hashPath": "discord.net.rest.3.1.0.nupkg.sha512" + }, + "Discord.Net.Webhook/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cZFxFf9H3GUBITlx1b7IskglgjJxSYpOIZOtyVW2WnPp7LpnxlOi1piRG22fH9fdhCC/RyDx3gZtYfN6WzacCw==", + "path": "discord.net.webhook/3.1.0", + "hashPath": "discord.net.webhook.3.1.0.nupkg.sha512" + }, + "Discord.Net.WebSocket/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-6OsLNXHNKC/laDKoBD+T0Km0vzqHaCcBOaI/NA8Qsed935MtEOTy7juorF22gF6TYOeoclUgSINrHCY4zWvxpA==", + "path": "discord.net.websocket/3.1.0", + "hashPath": "discord.net.websocket.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", + "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "System.Collections.Immutable/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==", + "path": "system.collections.immutable/5.0.0", + "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512" + }, + "System.Interactive.Async/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QaqhQVDiULcu4vm6o89+iP329HcK44cETHOYgy/jfEjtzeFy0ZxmuM7nel9ocjnKxEM4yh1mli7hgh8Q9o+/Iw==", + "path": "system.interactive.async/5.0.0", + "hashPath": "system.interactive.async.5.0.0.nupkg.sha512" + }, + "System.Linq.Async/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cPtIuuH8TIjVHSi2ewwReWGW1PfChPE0LxPIDlfwVcLuTM9GANFTXiMB7k3aC4sk3f0cQU25LNKzx+jZMxijqw==", + "path": "system.linq.async/5.0.0", + "hashPath": "system.linq.async.5.0.0.nupkg.sha512" + }, + "System.Reactive/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==", + "path": "system.reactive/5.0.0", + "hashPath": "system.reactive.5.0.0.nupkg.sha512" + }, + "System.ValueTuple/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==", + "path": "system.valuetuple/4.5.0", + "hashPath": "system.valuetuple.4.5.0.nupkg.sha512" + }, + "PluginManager/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/BUILDS/net5.0/CMD_Utils.dll b/BUILDS/net5.0/CMD_Utils.dll new file mode 100644 index 0000000000000000000000000000000000000000..bb1fc45da4d98ef81753075b94e494ead8de6550 GIT binary patch literal 9216 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 Y$MW~+g0uV^NYl~ZBcK1^Y9#{y3y!{LYXATM literal 0 HcmV?d00001 diff --git a/BUILDS/net5.0/EVE_LevelingSystem.deps.json b/BUILDS/net5.0/EVE_LevelingSystem.deps.json new file mode 100644 index 0000000..21334b2 --- /dev/null +++ b/BUILDS/net5.0/EVE_LevelingSystem.deps.json @@ -0,0 +1,268 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v5.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v5.0": { + "EVE_LevelingSystem/1.0.0": { + "dependencies": { + "PluginManager": "1.0.0" + }, + "runtime": { + "EVE_LevelingSystem.dll": {} + } + }, + "Discord.Net/3.1.0": { + "dependencies": { + "Discord.Net.Commands": "3.1.0", + "Discord.Net.Core": "3.1.0", + "Discord.Net.Interactions": "3.1.0", + "Discord.Net.Rest": "3.1.0", + "Discord.Net.WebSocket": "3.1.0", + "Discord.Net.Webhook": "3.1.0" + } + }, + "Discord.Net.Commands/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Commands.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Core/3.1.0": { + "dependencies": { + "Newtonsoft.Json": "13.0.1", + "System.Collections.Immutable": "5.0.0", + "System.Interactive.Async": "5.0.0", + "System.ValueTuple": "4.5.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Core.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Interactions/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0", + "Discord.Net.WebSocket": "3.1.0", + "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", + "System.Collections.Immutable": "5.0.0", + "System.Reactive": "5.0.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Interactions.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Rest/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Rest.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.Webhook/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.Webhook.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Discord.Net.WebSocket/3.1.0": { + "dependencies": { + "Discord.Net.Core": "3.1.0", + "Discord.Net.Rest": "3.1.0" + }, + "runtime": { + "lib/net5.0/Discord.Net.WebSocket.dll": { + "assemblyVersion": "3.1.0.0", + "fileVersion": "3.1.0.0" + } + } + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "runtime": { + "lib/netstandard2.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.20.51904" + } + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "System.Collections.Immutable/5.0.0": {}, + "System.Interactive.Async/5.0.0": { + "dependencies": { + "System.Linq.Async": "5.0.0" + }, + "runtime": { + "lib/netcoreapp3.1/System.Interactive.Async.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.Linq.Async/5.0.0": { + "runtime": { + "lib/netcoreapp3.1/System.Linq.Async.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.Reactive/5.0.0": { + "runtime": { + "lib/net5.0/System.Reactive.dll": { + "assemblyVersion": "5.0.0.0", + "fileVersion": "5.0.0.1" + } + } + }, + "System.ValueTuple/4.5.0": {}, + "PluginManager/1.0.0": { + "dependencies": { + "Discord.Net": "3.1.0" + }, + "runtime": { + "PluginManager.dll": {} + } + } + } + }, + "libraries": { + "EVE_LevelingSystem/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Discord.Net/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-GAY7d+k8UN5BsObGpysvg7ca6YwTqvesTouM8S8eBWSmwGnK38iceVkURg0QNAG70tlJ4w8S/BOjocRRvXU2MQ==", + "path": "discord.net/3.1.0", + "hashPath": "discord.net.3.1.0.nupkg.sha512" + }, + "Discord.Net.Commands/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-EZdtrAqj6Uspyz4CvIwFP/UQ4XUpXjIPG1b5LrfAKOo12ks4k6XO7up2h+UsHexk7mEz4sfZxkEXGrW6PSh+/Q==", + "path": "discord.net.commands/3.1.0", + "hashPath": "discord.net.commands.3.1.0.nupkg.sha512" + }, + "Discord.Net.Core/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-Oxz3CiWVvenSaHRYZeCKgRqzcWqdjGYmpxVVN2vPikt6bTN+xHAR4jczk8plKDDdINt7Lac37iLsRaqzUtJZpQ==", + "path": "discord.net.core/3.1.0", + "hashPath": "discord.net.core.3.1.0.nupkg.sha512" + }, + "Discord.Net.Interactions/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-XzLChVRQGniUU8kdLMDYEOjifzvrcsOiAdKm/pO/PGPpZSMWSzPWlJUWaQlWMtOImrYULzRejOeoc2/3K3R30Q==", + "path": "discord.net.interactions/3.1.0", + "hashPath": "discord.net.interactions.3.1.0.nupkg.sha512" + }, + "Discord.Net.Rest/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-97kdAYjlNuuOnhRQW/OoGK2oBObvpzZlCSPJjIcI4DneEq6k2WIFhG00fvxK7DCVTlB5BgBMAT1BeRUk4/rUxQ==", + "path": "discord.net.rest/3.1.0", + "hashPath": "discord.net.rest.3.1.0.nupkg.sha512" + }, + "Discord.Net.Webhook/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cZFxFf9H3GUBITlx1b7IskglgjJxSYpOIZOtyVW2WnPp7LpnxlOi1piRG22fH9fdhCC/RyDx3gZtYfN6WzacCw==", + "path": "discord.net.webhook/3.1.0", + "hashPath": "discord.net.webhook.3.1.0.nupkg.sha512" + }, + "Discord.Net.WebSocket/3.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-6OsLNXHNKC/laDKoBD+T0Km0vzqHaCcBOaI/NA8Qsed935MtEOTy7juorF22gF6TYOeoclUgSINrHCY4zWvxpA==", + "path": "discord.net.websocket/3.1.0", + "hashPath": "discord.net.websocket.3.1.0.nupkg.sha512" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ORj7Zh81gC69TyvmcUm9tSzytcy8AVousi+IVRAI8nLieQjOFryRusSFh7+aLk16FN9pQNqJAiMd7BTKINK0kA==", + "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", + "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "System.Collections.Immutable/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-FXkLXiK0sVVewcso0imKQoOxjoPAj42R8HtjjbSjVPAzwDfzoyoznWxgA3c38LDbN9SJux1xXoXYAhz98j7r2g==", + "path": "system.collections.immutable/5.0.0", + "hashPath": "system.collections.immutable.5.0.0.nupkg.sha512" + }, + "System.Interactive.Async/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-QaqhQVDiULcu4vm6o89+iP329HcK44cETHOYgy/jfEjtzeFy0ZxmuM7nel9ocjnKxEM4yh1mli7hgh8Q9o+/Iw==", + "path": "system.interactive.async/5.0.0", + "hashPath": "system.interactive.async.5.0.0.nupkg.sha512" + }, + "System.Linq.Async/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-cPtIuuH8TIjVHSi2ewwReWGW1PfChPE0LxPIDlfwVcLuTM9GANFTXiMB7k3aC4sk3f0cQU25LNKzx+jZMxijqw==", + "path": "system.linq.async/5.0.0", + "hashPath": "system.linq.async.5.0.0.nupkg.sha512" + }, + "System.Reactive/5.0.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-erBZjkQHWL9jpasCE/0qKAryzVBJFxGHVBAvgRN1bzM0q2s1S4oYREEEL0Vb+1kA/6BKb5FjUZMp5VXmy+gzkQ==", + "path": "system.reactive/5.0.0", + "hashPath": "system.reactive.5.0.0.nupkg.sha512" + }, + "System.ValueTuple/4.5.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==", + "path": "system.valuetuple/4.5.0", + "hashPath": "system.valuetuple.4.5.0.nupkg.sha512" + }, + "PluginManager/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/BUILDS/net5.0/EVE_LevelingSystem.dll b/BUILDS/net5.0/EVE_LevelingSystem.dll new file mode 100644 index 0000000000000000000000000000000000000000..5c2caaa8a0c76f34509cf68a45cf8e9d95b34fc0 GIT binary patch literal 9728 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 literal 0 HcmV?d00001 diff --git a/BUILDS/net5.0/PluginManager.dll b/BUILDS/net5.0/PluginManager.dll new file mode 100644 index 0000000000000000000000000000000000000000..b24bd2d94ccfae79ccb2c152fe5383be1ae57422 GIT binary patch literal 36864 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 M9L4-F)J6vW3$8Fp(EtDd literal 0 HcmV?d00001 diff --git a/BUILDS/net5.0/ref/EVE_LevelingSystem.dll b/BUILDS/net5.0/ref/EVE_LevelingSystem.dll new file mode 100644 index 0000000000000000000000000000000000000000..1317ae75ced4d3b2c8f11eb356c5fbc0c37a3264 GIT binary patch literal 6144 zcmeHLU2Ggz6+Sbw-Z<-IYr9PoNY$?EP=y9Yc4JEoanrTE>%`RSINps@Qla(i?Dcxc z?96s%b{kVcjVR@(FMz6+6eJvw-~oh!+DfGoQY0Rz1d(`vhe}kUJb*+WDrg^Q9~!=M zXJ&trG%Y-!s>-$Rne%tgJ?Gqe&)nI<>2H%pL<#iEmx*4)lUr88>w`^*(|5d-rsua` z8hKG!xHM8)xBN`Qb8DVa&zOeexIv~OGG5ckSWYH)yqKxGRiW?Pnc5ebUdj_KC<#hV zocnn^+h6F;%z!dRv;&;}ko&I(@XVrT(1`}+Qw{xQ2Kz7D7GOkZwE8tx<^RqzBAJD@ z1-r)?StZ)!L|oZ6LpL6W-fdUPu19Cvu1l?c(8s#;^?J*yf|jmjfFPFGZ(y=ziDvXb zoDD$zdjJ3onUf@*T`dFeb?HU>QBiB_lu1zZSQ7KC_hFYUA^M7cm zTfRs$#m~+tkp-?ZtqFZhKR9-9{16-LBOCAss86F`Mvd$vy2yAj@GPh1v&PHY!}2wH zvPi!N&NXuM=*jsUo__{if^(xYwp(FkG?Xyq)b1^9JJ+&zl!IK)*#EugTq-eycA;}Q z5^t(0N>dAC6?zkz|Bx`Ru>Dn7PSRy!{3QuLtug*I_!y%dP7Kqx z5*LBHiNlE`Q1!v4hFz}}*J03Xtr`yDz2_?*U^m_G&l1vLw}JCUQMEDX@o^jq~9=8CD? zv;yXfDU%9Vg_x?-GIAeNX5uuwjH&M>1f?SCi9OFE7dzUrC$%$O6wkM_E#vvpZHni+ zDWd+i{YS{gV4K>Zby3Q96V0|PoNp-7?4@2)o=5&;*=x!r?6jB)HHV{dp=O6-&0%Cn zK`yTaRr)nnQ=?JruLSJ}3^i5y6;>_ApOgG2+R|QYUxfvQUX}J=g%txQ?gZB71kS;; zngUNblOF?2(I+K74mgOlWjHP2yo4tt{G5b_gx>_*1>f1iISJ1b=i)qZWWSUgod)PJ z(y@oW0l1fb3OGs^01wa$fCuSyz{A*YI?YlV@B!KjSd{#S0DnwA^e>W0cPSU?4DjDb zPF8&q_?CnT#7OiLdK7R_do-%*7XEU9T_i|r3`evVcEiyv%^w#IzWxD zGy_37QEAp{M#UB#-n8$Fdd1!-SwS!R3QsyCLMy^62BJ|~_uOV}y(26c9-^DWhlqH@ z_0Dtz@u*`~wJMwrKc0UMKCcMR$68%2oOjk-uWrbNwBJ)})^*mbTGNwy9V1~vBy(BV z##xE^9eM1*l84nbgN|TXtO-vzrie8RA>kFB(%usG7-(nSE#Zm&3-^~F8~Rh~Gux88h7YL&X*JoeC5KL`$pJhpEje6AA4L7`9{@-V zY@>uS(4R`BNZmDbpQ`o`;7+K5)km=Uc}x}B7utSG_ba#`aJ!u^IwkeiQ=ZXSbe;TJ zQ^<|Qb>IWdeEU)mr45xLcv& ztG7H+N})cv!uX2DG~>A3;xFV&g6M!kckyHg-oKQ~XgWat9?&7_<>-FStiLjzW$fw} z-{V6`8I$L1yI@!j)p;igq4QDYcKH*qapg4OFr<_Pdx$n8Mw`!RM2uJQS%JSD9$Y2b zC*Oa}VSEB`1#k5-V4jwN&EuDrMbPtrbK$QpxbM92ZunM?-=*R6erYAVm#YyTKXO16 zST)Fl9Sh$Rcw>=6Yvf9mee&&Fg46)lhuok5dM>E2T}V6*qY8Wqpk;wyyN0DzsWXPS z!@mita1Nk(Gse!sUY#0pjtxX)fD+PtUPfG|1<);YJDQ;D;E=#cM!mB278FWQM z*oC|k-+x`kaDT(sOOKr^v)Rcd;TwwcK8;-aa&0S!W&@GF_ZVJ>4@t|0zXiT^_(S5) K4LAO;8Tb#Fm2$}d literal 0 HcmV?d00001 diff --git a/BUILDS/net5.0/ref/StartupEvents.dll b/BUILDS/net5.0/ref/StartupEvents.dll new file mode 100644 index 0000000000000000000000000000000000000000..ce85f385a9bf3b0f81d0756222be4f85c3ac0dd5 GIT binary patch literal 6144 zcmeHLU2Ggz6+Sa#uYZyl+q9`6RlTWGsSp^gWk*Va>#pr}k`4aNZk)CVt!HM21E^rNT@w&eCOVoon1SQ zfX66zeZM(>_uO;O+&Oc{i%&gA1`&0k-?~L~6IX6oiFbw_s0T)WIY2+}d+Yd3ZQ-rs z#Z5a%H+-+=TlI9sa$PS>mqprdx@p@@=aviUx>ptEkt6*lBG)VPL_GW#{u7a1Lr9ogVaonI}%M#6+p|}=;d$%6| zfy_w?*S3~M^rj#970Bco)d|Be_m~ntU(pf&K9R~gk5{~U* z2E@z1LHarta;n8S5!X$IHVCQG^+}Ek{VA-wzl}>FKWuqY>iXd?MQ7==z#r1*fq&66 zz&DLaV9hvvfPAV=o&~KLIca}^Rpc3S1}RaiMSo7B}uBMJC?rB z#Q-t2OJCp+alcg@ykmM)ZJ3&_lu9`}XgJpPoMQ#SWGO>ah0yZD>1wGoNmGknwdsgy znu?_5QYkZCr8&>tuxsaRM^H_KCD*D8Dr^U#sGFCXZfJwe&jj0U1-?SDXjL|C7ZxJy z;DdH$al0XCYI?j>l449zZ@|BQUbw=Clj=-}%35xQf^wqVtktZtBNEw65Quu&*)G~) zr+7~g$q3~|_=Qk3ikrUItZgRBqUB>@=WzTNPka8=L=lg=U{|ZcP2}8VWPMsHiR$Siil%ORI!A8 zTkdwEi0-14hj!U^?66JSd8^H6C3x)-?yny<8}nPj4Fj|4IMKG?dw(9uTy__{n(flE zdpQvPMGs``Ol&x!!b_H0sw#qtZ#N__chZ_?R~JRN=~ZW&wo?^8NpaB%u6By2ro&RH z9NDZmO-#3FxmFD$3SQ+Z;$R(5PfZ515_(Xn-J7$mn(GCjT?wdTteJO1;cr+K5yZAp zj?8$c7KFcLvtI2HqytY6*s1BsQYpk2WoLG1x%?F@nDG2nJilsQ5oHx$OR^-w{ZeH! z=h(F zvwCVkPxTt9AK(7{k<37Z1^P+zAif=WRJa_(D zMacWe582a!2D=_vox0>ZU850mX}&n;`C_Kg_*}G?9@{!)X5eMuzSc7s)u|<}HNzSm z>DX#S{Tg-4#N*tD8OCu`!%xX2Lv&1|qshiQ*qRHILK?$J&?SJ1f0Z{3)|^{3I< zlSQvFon>l&i_fS^Q^JySjKM zdF+aPa<=1dhbPvFKG2y{?E`%h#2QWvCEz?=0+q*qT9&})f#=kJUFg?cAAYRf*zucJ zT_2D9@L9agt(4|~8oXNM!;g*c3A{GRr490={)Bu>7ooKv4WPFugq;UYwHsX*;8a6Q zA*^i3Yq#-qLfT{~{!LODG|?0dVC)?H)p4fcIkvGP3!ISd*(=8uQWN@l+Jf8##~(L2 zIW~?u2Tg#p635VhMH1tkd}L5Cv{t-p@ZrNtGIks%wM?t?oWro^429CxMRZPE#0Sr1 zQWci`z4j>Xf`*eg4lZ&uufBnGbL2JJglD2O`huKmIg)c`d9HZ9%&9E>H*=~yufUgw zIGV^)*cLUu(7+#*XZ~iv*G9+Ky_rh#gl|fj(;4J3z#8kg(+*ab#xCp3ZZd{*d>6E= T`d{EXXYYcw+*`u`oPqxUM&SD0 literal 0 HcmV?d00001 diff --git a/CMD_LevelingSystem/CMD_LevelingSystem.csproj b/CMD_LevelingSystem/CMD_LevelingSystem.csproj new file mode 100644 index 0000000..8495526 --- /dev/null +++ b/CMD_LevelingSystem/CMD_LevelingSystem.csproj @@ -0,0 +1,19 @@ + + + + net5.0 + + + + E:\DiscordBot\BUILDS\ + DEBUG;TRACE + prompt + none + false + + + + + + + diff --git a/CMD_LevelingSystem/Commands/level.cs b/CMD_LevelingSystem/Commands/level.cs new file mode 100644 index 0000000..ef5f8dc --- /dev/null +++ b/CMD_LevelingSystem/Commands/level.cs @@ -0,0 +1,55 @@ +using Discord; +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Interfaces; +using PluginManager.LanguageSystem; + +using System; + + +public class level : DBCommand +{ + public string Command => "rank"; + + public string Description => "Display your current level"; + + public string Usage => "rank"; + + public bool canUseDM => false; + + public bool canUseServer => true; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + + try + { + int cLv = Data.GetLevel(message.Author.Id); + Int64 cEXP = Data.GetExp(message.Author.Id); + Int64 rEXP = Data.GetReqEXP(message.Author.Id); + + var embed = new EmbedBuilder() + { + Title = "Leveling System", + Description = message.Author.Mention + }; + embed.WithColor(Color.Blue); + embed.AddField("Level", cLv); + embed.AddField("Current EXP", cEXP); + embed.AddField("Required Exp to Level up", rEXP); + embed.WithCurrentTimestamp(); + await message.Channel.SendMessageAsync(embed: embed.Build()); + } + catch + { + if (Language.ActiveLanguage != null) + await message.Channel.SendMessageAsync(Language.ActiveLanguage.LanguageWords["DB_COMMAND_RANK_NO_RANK"]); + else await message.Channel.SendMessageAsync("You are unranked now. Please type a message in chat that is not a command and try again this command"); + return; + } + + + } +} + diff --git a/CMD_LevelingSystem/Items/Leveling System/Core.cs b/CMD_LevelingSystem/Items/Leveling System/Core.cs new file mode 100644 index 0000000..10314f4 --- /dev/null +++ b/CMD_LevelingSystem/Items/Leveling System/Core.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +public class Core +{ + + public static Dictionary playerMessages = new Dictionary(); + + private static readonly string folder = @".\Data\Resources\LevelingSystem\"; + + public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); + + + public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); + + + public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); + public static void SaveData(ulong id, int lv, Int64 cexp, Int64 rexp) + { + Directory.CreateDirectory(folder); + File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), $"Level={lv},EXP={cexp},REXP={rexp}"); + } + private static Int64 NextLevelXP(int level) + { + return (level * level) + 2 * level + 75; + } + + public static (bool, int) MessageSent(ulong id, int messageLength) + { + WaitForTimeToRemoveFromList(id, 60); + + if (!File.Exists(Path.Combine(folder, id.ToString() + ".data"))) + { + SaveData(id, 0, 0, 0); + } + Int64 cEXp = GetExp(id); + Int64 rExp = GetReqEXP(id); + int random = new System.Random().Next(3, 6) + messageLength; + cEXp += random; + if (cEXp >= rExp) + { + cEXp = cEXp - rExp; + int lv = GetLevel(id); + rExp = NextLevelXP(lv); + lv++; + SaveData(id, lv, cEXp, rExp); + return (true, lv); + } + + SaveData(id, GetLevel(id), cEXp, rExp); + return (false, -1); + } + + public static async void WaitForTimeToRemoveFromList(ulong id, int time_seconds) + { + await Task.Delay(time_seconds * 1000); + playerMessages.Remove(id); + } + +} \ No newline at end of file diff --git a/CMD_LevelingSystem/Items/Leveling System/Data.cs b/CMD_LevelingSystem/Items/Leveling System/Data.cs new file mode 100644 index 0000000..44ffb76 --- /dev/null +++ b/CMD_LevelingSystem/Items/Leveling System/Data.cs @@ -0,0 +1,24 @@ +using Discord.WebSocket; + +using System; +using System.IO; +public static class Data +{ + private static readonly string folder = @".\Data\Resources\LevelingSystem\"; + public static void registerPlayer(SocketGuildUser user) + { + ulong id = user.Id; + Directory.CreateDirectory(folder); + File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), "Level=0,EXP=0,REXP=100"); + } + + public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); + + + public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); + + + public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); + + +} diff --git a/CMD_Utils/CMD_Utils.csproj b/CMD_Utils/CMD_Utils.csproj new file mode 100644 index 0000000..6d89c4e --- /dev/null +++ b/CMD_Utils/CMD_Utils.csproj @@ -0,0 +1,15 @@ + + + + net5.0 + + + + E:\DiscordBot\BUILDS\ + + + + + + + diff --git a/CMD_Utils/Echo.cs b/CMD_Utils/Echo.cs new file mode 100644 index 0000000..90286a8 --- /dev/null +++ b/CMD_Utils/Echo.cs @@ -0,0 +1,22 @@ +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Interfaces; + +internal class Echo : DBCommand +{ + public string Command => "echo"; + + public string Description => "Replay with the same message"; + + public string Usage => "echo [message]"; + + public bool canUseDM => true; + public bool canUseServer => true; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + string m = message.Content.Substring(6); + await message.Channel.SendMessageAsync(m); + } +} diff --git a/CMD_Utils/FlipCoin.cs b/CMD_Utils/FlipCoin.cs new file mode 100644 index 0000000..04446f4 --- /dev/null +++ b/CMD_Utils/FlipCoin.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Interfaces; + +namespace CMD_Utils +{ + class FlipCoin : DBCommand + { + public string Command => "flip"; + + public string Description => "Flip a coin"; + + public string Usage => "flip"; + + public bool canUseDM => true; + + public bool canUseServer => true; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + System.Random random = new System.Random(); + int r = random.Next(1, 3); + if (r == 1) + await message.Channel.SendMessageAsync("Heads"); + else await message.Channel.SendMessageAsync("Tails"); + } + } +} diff --git a/CMD_Utils/Random.cs b/CMD_Utils/Random.cs new file mode 100644 index 0000000..4794634 --- /dev/null +++ b/CMD_Utils/Random.cs @@ -0,0 +1,40 @@ +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Interfaces; + +public class Random : DBCommand +{ + public string Command => "random"; + + public string Description => "random number between number1 and number2"; + + public string Usage => "random [number1] [number2]"; + + public bool canUseDM => true; + public bool canUseServer => true; + + public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + try + { + string msg = message.Content; + int a = int.Parse(msg.Split(' ')[1]); + int b = int.Parse(msg.Split(' ')[2]); + + if (a > b) + { + int x = a; + a = b; + b = x; + } + + await message.Channel.SendMessageAsync("Your random generated number is " + new System.Random().Next(a, b)); + + } + catch + { + await message.Channel.SendMessageAsync("Invalid numbers or no numbers:\nUsage: " + Usage); + } + } +} diff --git a/DiscordBot.sln b/DiscordBot.sln new file mode 100644 index 0000000..6ae28f2 --- /dev/null +++ b/DiscordBot.sln @@ -0,0 +1,69 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31729.503 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{087E64F4-1E1C-4899-8223-295356C9894A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginManager", "PluginManager\PluginManager.csproj", "{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Plugins", "Plugins", "{1862ABD5-7C30-4F15-A561-45AC8A9CA10E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Events", "Events", "{A290C028-77C4-4D1D-AB43-DDFE6ABD9012}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Commands", "Commands", "{449FA364-0B72-43FF-B3A3-806E2916200E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CMD_LevelingSystem", "CMD_LevelingSystem\CMD_LevelingSystem.csproj", "{A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EVE_LevelingSystem", "EVE_LevelingSystem\EVE_LevelingSystem.csproj", "{1C1E7F3D-E05A-4A87-9789-62D98904C200}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StartupEvents", "StartupEvents\StartupEvents.csproj", "{CE9DBF06-38A0-4192-8B3E-4009210D040D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CMD_Utils", "CMD_Utils\CMD_Utils.csproj", "{E26C87A4-3DD6-4B58-B14B-C8E086B852F9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {087E64F4-1E1C-4899-8223-295356C9894A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {087E64F4-1E1C-4899-8223-295356C9894A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {087E64F4-1E1C-4899-8223-295356C9894A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {087E64F4-1E1C-4899-8223-295356C9894A}.Release|Any CPU.Build.0 = Release|Any CPU + {EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 + {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC}.Release|Any CPU.Build.0 = Release|Any CPU + {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C1E7F3D-E05A-4A87-9789-62D98904C200}.Release|Any CPU.Build.0 = Release|Any CPU + {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE9DBF06-38A0-4192-8B3E-4009210D040D}.Release|Any CPU.Build.0 = Release|Any CPU + {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E26C87A4-3DD6-4B58-B14B-C8E086B852F9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} = {1862ABD5-7C30-4F15-A561-45AC8A9CA10E} + {449FA364-0B72-43FF-B3A3-806E2916200E} = {1862ABD5-7C30-4F15-A561-45AC8A9CA10E} + {A48E8DC6-DBA2-4B47-9D59-46F4835F82CC} = {449FA364-0B72-43FF-B3A3-806E2916200E} + {1C1E7F3D-E05A-4A87-9789-62D98904C200} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} + {CE9DBF06-38A0-4192-8B3E-4009210D040D} = {A290C028-77C4-4D1D-AB43-DDFE6ABD9012} + {E26C87A4-3DD6-4B58-B14B-C8E086B852F9} = {449FA364-0B72-43FF-B3A3-806E2916200E} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF} + EndGlobalSection +EndGlobal diff --git a/DiscordBot/App.config b/DiscordBot/App.config new file mode 100644 index 0000000..ffaf540 --- /dev/null +++ b/DiscordBot/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DiscordBot/Discord/Commands/Help.cs b/DiscordBot/Discord/Commands/Help.cs new file mode 100644 index 0000000..593b9f5 --- /dev/null +++ b/DiscordBot/Discord/Commands/Help.cs @@ -0,0 +1,37 @@ +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Loaders; +using PluginManager.Interfaces; + +namespace PluginManager.Commands +{ + internal class Help : DBCommand + { + public string Command => "help"; + + public string Description => "This command allows you to check all loadded commands"; + + public string Usage => "help"; + + public bool canUseDM => true; + public bool canUseServer => true; + + public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) + { + if (isDM) + { + foreach (DBCommand p in PluginLoader.Plugins!) + if (p.canUseDM) + context.Channel.SendMessageAsync(p.Usage + "\t" + p.Description); + } + else + { + foreach (DBCommand p in PluginLoader.Plugins!) + if (p.canUseServer) + context.Channel.SendMessageAsync(p.Usage + "\t" + p.Description); + } + + } + } +} \ No newline at end of file diff --git a/DiscordBot/Discord/Core/Boot.cs b/DiscordBot/Discord/Core/Boot.cs new file mode 100644 index 0000000..a55bd41 --- /dev/null +++ b/DiscordBot/Discord/Core/Boot.cs @@ -0,0 +1,113 @@ +using Discord; +using Discord.Commands; +using Discord.WebSocket; + +using System; +using System.Threading.Tasks; + +using static PluginManager.Others.Functions; + +namespace PluginManager.Core +{ + internal class Boot + { + private readonly string botPrefix; + private readonly string botToken; + + private bool isReady = false; + + public DiscordSocketClient? client; + private CommandHandler? commandServiceHandler; + private CommandService? service; + + public Boot(string botToken, string botPrefix) + { + this.botPrefix = botPrefix; + this.botToken = botToken; + } + + public async Task Awake() + { + client = new DiscordSocketClient(); + service = new CommandService(); + + CommonTasks(); + + await client.LoginAsync(TokenType.Bot, botToken); + await client.StartAsync(); + + commandServiceHandler = new CommandHandler(client, service, botPrefix); + await commandServiceHandler.InstallCommandsAsync(); + + while (!isReady) ; + + } + + public async Task ShutDown() + { + if (client == null) return; + await client.StopAsync(); + } + + private void CommonTasks() + { + if (client == null) + return; + client.LoggedOut += Client_LoggedOut; + client.Log += Log; + client.LoggedIn += LoggedIn; + client.Ready += Ready; + } + + private Task Client_LoggedOut() + { + WriteLogFile("Successfully Logged Out"); + Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !")); + return Task.CompletedTask; + } + + private Task Ready() + { + Console.Title = "ONLINE"; + isReady = true; + return Task.CompletedTask; + } + + private Task LoggedIn() + { + Console.Title = "CONNECTED"; + WriteLogFile("The bot has been logged in at " + DateTime.Now.ToShortDateString() + " (" + + DateTime.Now.ToShortTimeString() + ")"); + return Task.CompletedTask; + } + + private Task Log(LogMessage message) + { + switch (message.Severity) + { + case LogSeverity.Error: + case LogSeverity.Critical: + WriteErrFile(message.Message); + + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("[ERROR] " + message.Message); + Console.ForegroundColor = ConsoleColor.White; + + break; + + case LogSeverity.Info: + case LogSeverity.Debug: + WriteLogFile(message.Message); + + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine("[INFO] " + message.Message); + Console.ForegroundColor = ConsoleColor.White; + + + break; + } + + return Task.CompletedTask; + } + } +} diff --git a/DiscordBot/Discord/Core/CommandHandler.cs b/DiscordBot/Discord/Core/CommandHandler.cs new file mode 100644 index 0000000..b141584 --- /dev/null +++ b/DiscordBot/Discord/Core/CommandHandler.cs @@ -0,0 +1,85 @@ +using Discord.Commands; +using Discord.WebSocket; + +using PluginManager.Interfaces; + +using System.Reflection; +using PluginManager.Others; +using PluginManager.Loaders; + +using System.Threading.Tasks; +using System.Linq; + +namespace PluginManager.Core +{ + internal class CommandHandler + { + private readonly DiscordSocketClient client; + private readonly CommandService commandService; + private readonly string botPrefix; + + public CommandHandler(DiscordSocketClient client, CommandService commandService, string botPrefix) + { + this.client = client; + this.commandService = commandService; + this.botPrefix = botPrefix; + } + + public async Task InstallCommandsAsync() + { + client.MessageReceived += MessageHandler; + await commandService.AddModulesAsync(assembly: Assembly.GetEntryAssembly(), services: null); + } + + private async Task MessageHandler(SocketMessage Message) + { + try + { + if (Message as SocketUserMessage == null) + return; + + var message = Message as SocketUserMessage; + + if (message == null) return; + + int argPos = 0; + + if (message.HasMentionPrefix(client.CurrentUser, ref argPos)) + { + await message.Channel.SendMessageAsync("Can not exec mentioned commands !"); + return; + } + + if (!(message.HasStringPrefix(botPrefix, ref argPos) || message.Author.IsBot)) + return; + + var context = new SocketCommandContext(client, message); + + await commandService.ExecuteAsync( + context: context, + argPos: argPos, + services: null + ); + + DBCommand? plugin = PluginLoader.Plugins!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); + + if (plugin != null) + { + if (message.Channel == await message.Author.CreateDMChannelAsync()) + { + if (plugin.canUseDM) + { + plugin.Execute(context, message, client, true); + Functions.WriteLogFile("Executed command (DM) : " + plugin.Command); + } + return; + } + plugin.Execute(context, message, client, false); + Functions.WriteLogFile("Executed command : " + plugin.Command); + } + } + catch { } + + } + } +} \ No newline at end of file diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj new file mode 100644 index 0000000..46319c7 --- /dev/null +++ b/DiscordBot/DiscordBot.csproj @@ -0,0 +1,35 @@ + + + + Exe + net5.0 + enable + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs new file mode 100644 index 0000000..93698e0 --- /dev/null +++ b/DiscordBot/Program.cs @@ -0,0 +1,469 @@ +using Discord; +using System; +using System.IO; +using System.Threading.Tasks; + +using PluginManager.Core; +using PluginManager.Others; + +using PluginManager.Loaders; +using PluginManager.LanguageSystem; +using PluginManager.Online; +namespace DiscordBot +{ + public class Program + { + private static PluginsManager manager = new PluginsManager("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Plugins"); + private static LanguageManager languageManager = new LanguageManager("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Languages"); + + private static bool loadPluginsOnStartup = false; + + /// + /// The main entry point for the application. + /// + [STAThread] + [Obsolete] + + public static void Main(string[] args) + { + AppDomain.CurrentDomain.AppendPrivatePath(".\\Requirements"); + Console.Clear(); + Directory.CreateDirectory("./Data/Resources"); + Directory.CreateDirectory("./Data/Languages"); + Directory.CreateDirectory("./Data/Plugins/Commands"); + Directory.CreateDirectory("./Data/Plugins/Events"); + if (!File.Exists("./Data/Resources/DiscordBotCore.data") || Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '\t').Length != 59) + { + File.WriteAllText("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN\ttoken\nBOT_PREFIX\t!\n"); + while (true) + { + Console.WriteLine("Please insert your token: "); + Console.Write("TOKEN: "); + string botToken = Console.ReadLine(); + if (botToken.Length == 59) + { + string prefix = Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_PREFIX", + '\t'); + if (prefix == String.Empty || prefix == null) + prefix = "!"; + File.WriteAllText("./Data/Resources/DiscordBotCore.data", $"BOT_TOKEN\t{botToken}\nBOT_PREFIX\t{prefix}\n"); + break; + } + else Console.WriteLine("Invalid Token !"); + } + } + + HandleInput(args).Wait(); + } + + /// + /// Reset all settings for the bot + /// + private static Task ResetSettings() + { + string[] files = Directory.GetFiles(@"./Data/Resources"); + foreach (string file in files) File.Delete(file); + return Task.CompletedTask; + } + + /// + /// The main loop for the discord bot + /// + /// The discord booter used to start the application + private static async Task NoGUI(Boot discordbooter) + { + LoadLanguage(); + if (loadPluginsOnStartup) LoadPlugins(discordbooter); + while (true) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Write('$'); + string[] data = Console.ReadLine().Split(' '); + if (data[0].Length < 2) continue; + switch (data[0]) + { + case "shutdown": + case "sd": + if (discordbooter.client.ConnectionState == ConnectionState.Connected) + await discordbooter.ShutDown().ContinueWith(t => { Environment.Exit(0); }); + break; + + case "listplugs": + await manager.ListAvailablePlugins(); + break; + + case "dwplug": + string name = data.MergeStrings(1); + string[] info = await manager.GetPluginLinkByName(name); + if (info[1] == null) // link is null + { + if (name == "") + { + Functions.WriteColorText($"Name is invalid"); + break; + } + Functions.WriteColorText($"Failed to find plugin &b{name} &c! Use &glistplugs &ccommand to display all available plugins !"); + break; + + } + Downloader dw = new Downloader(name + ".dll", info[1]); + await dw.DownloadFileAsync("./Data/Plugins/", info[0]); + break; + case "setlang": + if (data.Length == 2) + SetLanguage(data[1]); + break; + case "set-setting": + if (data.Length >= 3) + Functions.WriteToSettingsFast(data[1], Functions.MergeStrings(data, 2)); + else Console.WriteLine("Failed to write to settings. Invalid params"); + break; + case "listlang": + await languageManager.ListAllLanguages(); + break; + case "dwlang": + string Lname = data.MergeStrings(1); + string[] link = await languageManager.GetDownloadLink(Lname); + if (link[0] == null) + { + if (Lname == "") + { + Functions.WriteColorText($"Name is invalid"); + break; + } + Functions.WriteColorText("Failed to find language &b" + Lname + " &c! Use &glistlang &ccommand to display all available languages !"); + break; + } + if (link[1].Contains("CrossPlatform") || link[1].Contains("cp")) + { + Downloader dwn = new Downloader(Lname + ".lng", link[0]); + await dwn.DownloadFileAsync(Functions.langFolder); + } + else Functions.WriteColorText("The language you are trying to download (&b" + Lname + "&c) is not compatible with the version of this bot. User &glistlang &ccommand in order to see all available languages for your current version !\n" + link[1]); + break; + case "loadplugins": + case "lp": + LoadPlugins(discordbooter); + break; + case "help": + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine( + "lp | loadplugins -> load all plugins\n" + + "sd | shutdown->close connection to the server(stop bot)\n" + + "token -> display the current token\n" + + "listplugs -> list all available plugins\n" + + "dwplug [name] -> download plugin by name\n" + + "listlang -> list all available languages\n" + + "dwlang -> download language by name\n" + + "setlang [name] -> set language from the downloaded languages\n" + + "set-setting [setting.path] [value] -> set setting value" + ); + Console.ForegroundColor = ConsoleColor.White; + break; + case "token": + if (File.Exists("./Data/Resources/DiscordBotCore.data")) + Console.WriteLine("Token: " + Functions.readCodeFromFile("./Data/Resources/DiscordBotCore.data", "BOT_TOKEN", '\t')); + else Console.WriteLine("File could not be found. Please register token"); + break; + default: + goto case "help"; + } + } + } + + private static void LoadPlugins(Boot discordbooter) + { + var loader = new PluginLoader(discordbooter.client); + loader.onCMDLoad += (name, typeName, success, exception) => + { + Console.ForegroundColor = ConsoleColor.Green; + if (name == null || name.Length < 2) + name = typeName; + if (success) + if (Language.ActiveLanguage == null) + Console.WriteLine("[CMD] Successfully loaded command : " + name); + else Console.WriteLine(Language.ActiveLanguage.FormatText(Language.ActiveLanguage.LanguageWords["COMMAND_LOAD_SUCCESS"], name)); + else + if (Language.ActiveLanguage == null) + Console.WriteLine("[CMD] Failed to load command : " + name + " because " + exception.Message); + else + Console.WriteLine(Language.ActiveLanguage.FormatText(Language.ActiveLanguage.LanguageWords["COMMAND_LOAD_FAIL"], name, exception.Message)); + Console.ForegroundColor = ConsoleColor.Red; + }; + loader.onEVELoad += (name, typeName, success, exception) => + { + if (name == null || name.Length < 2) + name = typeName; + Console.ForegroundColor = ConsoleColor.Green; + if (success) + if (Language.ActiveLanguage == null) + Console.WriteLine("[EVENT] Successfully loaded event : " + name); + else + Console.WriteLine(Language.ActiveLanguage.FormatText(Language.ActiveLanguage.LanguageWords["EVENT_LOAD_SUCCESS"], name)); + else + if (Language.ActiveLanguage == null) + Console.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception.Message); + else + Console.WriteLine(Language.ActiveLanguage.FormatText(Language.ActiveLanguage.LanguageWords["EVENT_LOAD_FAIL"], name, exception.Message)); + Console.ForegroundColor = ConsoleColor.Red; + }; + loader.LoadPlugins(); + } + + /// + /// Load the language from the specified file + /// + private static bool LoadLanguage() + { + string folder = Functions.langFolder; + string langSettings = "./Data/Resources/Language.txt"; + if (!File.Exists(langSettings)) + File.WriteAllText(langSettings, "Language=English"); + //Load language from the specified file ... + Language.ActiveLanguage = null; + + string langname = File.ReadAllText(langSettings).Split('=')[1]; + if (langname == "English") + { + Language.ActiveLanguage = null; + return true; + } + foreach (var file in Directory.GetFiles(folder)) + { + if (Functions.readCodeFromFile(file, "LANGUAGE_NAME", '=') == langname) + { + Language.ActiveLanguage = Language.CreateLanguageFromFile(file); + + return true; + } + } + + if (Language.ActiveLanguage == null) + { + File.WriteAllText(langSettings, "Language=English"); + Functions.WriteColorText($"Failed to find language &r{langname} &c! Check available languages using command: &glistlang"); + + return false; + } + + return false; + } + + public static void SetLanguage(string LanguageName) + { + + string folder = Functions.langFolder; + string langSettings = Functions.dataFolder + "Language.txt"; + File.WriteAllText(langSettings, "Language=" + LanguageName); + + try + { + bool success = LoadLanguage(); + if (success) + { + Functions.WriteColorText($"Language has been setted to: &g{LanguageName}"); + return; + } + } + catch (Exception ex) + { + Functions.WriteColorText($"Could not find language &r{LanguageName}."); + Functions.WriteErrFile(ex.ToString()); + File.WriteAllText(langSettings, "Language=English"); + LoadLanguage(); + } + } + + /// + /// Start the bot without user interface + /// + /// Returns the boot loader for the Discord Bot + private static async Task StartNoGUI() + { + + Console.Clear(); + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine("Discord BOT for Cross Platform\n\nCreated by: Wizzy\nDiscord: Wizzy#9181\nCommands:"); + Console.WriteLine( + "lp | loadplugins -> load all plugins\n" + + "sd | shutdown->close connection to the server(stop bot)\n" + + "token -> display the current token\n" + + "listplugs -> list all available plugins\n" + + "dwplug [name] -> download plugin by name\n" + + "listlang -> list all available languages\n" + + "dwlang -> download language by name\n" + + "setlang [name] -> set language from the downloaded languages\n" + + "set-setting [setting.path] [value] -> set setting value" + ); + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine("============================ Discord BOT - Cross Platform ============================"); + string token = + Functions.readCodeFromFile((Functions.dataFolder + "DiscordBotCore.data"), "BOT_TOKEN", + '\t'); + string prefix = Functions.readCodeFromFile((Functions.dataFolder + "DiscordBotCore.data"), + "BOT_PREFIX", + '\t'); + + Console.WriteLine("Detected prefix: " + prefix); + var discordbooter = new Boot(token, prefix); + await discordbooter.Awake(); + return discordbooter; + } + + /// + /// Clear folder + /// + /// Directory path + private static Task ClearFolder(string d) + { + string[] files = Directory.GetFiles(d); + int fileNumb = files.Length; + for (var i = 0; i < fileNumb; i++) + { + File.Delete(files[i]); + Console.WriteLine("Deleting : " + files[i]); + } + + return Task.CompletedTask; + } + + /// + /// Replace text in the file + /// + /// The file location (path) + /// The setting key code where to replace + /// The new value + /// If the does not exist, then this error is thrown + private static void ReplaceText(string file, string code, string value) + { + try + { + var f = false; + string[] text = File.ReadAllLines(file); + foreach (string line in text) + if (line.StartsWith(code)) + { + line.Replace(line.Split('\t')[1], value); + f = true; + } + + if (f) + File.WriteAllLines(@"./Data/Resources/DiscordBotCore.data", text); + else throw new FileNotFoundException(); + } + catch (FileNotFoundException) + { + File.AppendAllText(file, code + "\t" + value + "\n"); + } + } + + /// + /// Handle user input arguments from the startup of the application + /// + /// The arguments + private static async Task HandleInput(string[] args) + { + int len = args.Length; + if (len == 1 && args[0] == "--help") + { + Console.WriteLine("Available commands:\n--exec -> start the bot with tools enabled"); + return; + } + + if (len == 1 && args[0] == "--logout") + { + File.Delete(Functions.dataFolder + "Login.dat"); + Console.WriteLine("Logged out. Please restart the application !"); + return; + } + + if (len == 2 && args[0] == "--encrypt") + { + Console.WriteLine("MD5: " + await Cryptography.CreateMD5(args[1])); + System.Console.WriteLine("SHA356: " + await Cryptography.CreateSHA256(args[1])); + return; + } + + if (len == 1 && args[0] == "--execute:lp") + { + loadPluginsOnStartup = true; + len = 0; + } + + + + + if (len == 0 || args[0] != "--exec" && args[0] != "--execute") + { + Boot b = await StartNoGUI(); + await NoGUI(b); + return; + } + + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine("Execute command interface noGUI\n\n"); + Console.WriteLine( + "\tCommand name\t\t\t\tDescription\n" + + "-- help | -help\t\t ------ \tDisplay the help message\n" + + "--reset-full\t\t ------ \tReset all files (clear files)\n" + + "--reset-settings\t ------ \tReset only bot settings\n" + + "--reset-logs\t\t ------ \tClear up the output folder\n" + + "--start\t\t ------ \tStart the bot\n" + + "exit\t\t\t ------ \tClose the application" + ); + while (true) + { + Console.ForegroundColor = ConsoleColor.White; + Console.Write("> "); + string[] message = Console.ReadLine().Split(' '); + + switch (message[0]) + { + case "--reset-settings": + await ResetSettings(); + Console.WriteLine("Successfully reseted all settings !"); + break; + case "--help": + case "-help": + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine( + "\tCommand name\t\t\t\tDescription\n" + + "-- help | -help\t\t ------ \tDisplay the help message\n" + + "--reset-full\t\t ------ \tReset all files (clear files)\n" + + "--reset-settings\t ------ \tReset only bot settings\n" + + "--reset-logs\t\t ------ \tClear up the output folder\n" + + "--start\t\t ------ \tStart the bot\n" + + "exit\t\t\t ------ \tClose the application" + ); + break; + case "--reset-full": + await ClearFolder("./Data/Resources/"); + await ClearFolder("./Output/Logs/"); + await ClearFolder("./Output/Errors"); + await ClearFolder("./Data/Languages/"); + await ClearFolder("./Data/Plugins/Addons"); + await ClearFolder("./Data/Plugins/Commands"); + await ClearFolder("./Data/Plugins/Events"); + Console.WriteLine("Successfully cleared all folders"); + break; + case "--reset-logs": + await ClearFolder("./Output/Logs"); + await ClearFolder("./Output/Errors"); + Console.WriteLine("Successfully cleard logs folder"); + break; + case "--exit": + case "exit": + Environment.Exit(0); + break; + case "--start": + Boot booter = await StartNoGUI(); + await NoGUI(booter); + return; + default: + Console.WriteLine("Failed to execute command " + message[0]); + break; + } + } + } + } +} diff --git a/EVE_LevelingSystem/Core.cs b/EVE_LevelingSystem/Core.cs new file mode 100644 index 0000000..10314f4 --- /dev/null +++ b/EVE_LevelingSystem/Core.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +public class Core +{ + + public static Dictionary playerMessages = new Dictionary(); + + private static readonly string folder = @".\Data\Resources\LevelingSystem\"; + + public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); + + + public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); + + + public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); + public static void SaveData(ulong id, int lv, Int64 cexp, Int64 rexp) + { + Directory.CreateDirectory(folder); + File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), $"Level={lv},EXP={cexp},REXP={rexp}"); + } + private static Int64 NextLevelXP(int level) + { + return (level * level) + 2 * level + 75; + } + + public static (bool, int) MessageSent(ulong id, int messageLength) + { + WaitForTimeToRemoveFromList(id, 60); + + if (!File.Exists(Path.Combine(folder, id.ToString() + ".data"))) + { + SaveData(id, 0, 0, 0); + } + Int64 cEXp = GetExp(id); + Int64 rExp = GetReqEXP(id); + int random = new System.Random().Next(3, 6) + messageLength; + cEXp += random; + if (cEXp >= rExp) + { + cEXp = cEXp - rExp; + int lv = GetLevel(id); + rExp = NextLevelXP(lv); + lv++; + SaveData(id, lv, cEXp, rExp); + return (true, lv); + } + + SaveData(id, GetLevel(id), cEXp, rExp); + return (false, -1); + } + + public static async void WaitForTimeToRemoveFromList(ulong id, int time_seconds) + { + await Task.Delay(time_seconds * 1000); + playerMessages.Remove(id); + } + +} \ No newline at end of file diff --git a/EVE_LevelingSystem/Data.cs b/EVE_LevelingSystem/Data.cs new file mode 100644 index 0000000..44ffb76 --- /dev/null +++ b/EVE_LevelingSystem/Data.cs @@ -0,0 +1,24 @@ +using Discord.WebSocket; + +using System; +using System.IO; +public static class Data +{ + private static readonly string folder = @".\Data\Resources\LevelingSystem\"; + public static void registerPlayer(SocketGuildUser user) + { + ulong id = user.Id; + Directory.CreateDirectory(folder); + File.WriteAllText(Path.Combine(folder, id.ToString() + ".data"), "Level=0,EXP=0,REXP=100"); + } + + public static int GetLevel(ulong id) => int.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[0].Split('=')[1]); + + + public static Int64 GetExp(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[1].Split('=')[1]); + + + public static Int64 GetReqEXP(ulong id) => Int64.Parse(File.ReadAllText(Path.Combine(folder, id.ToString() + ".data")).Split(',')[2].Split('=')[1]); + + +} diff --git a/EVE_LevelingSystem/EVE_LevelingSystem.csproj b/EVE_LevelingSystem/EVE_LevelingSystem.csproj new file mode 100644 index 0000000..1eefd33 --- /dev/null +++ b/EVE_LevelingSystem/EVE_LevelingSystem.csproj @@ -0,0 +1,17 @@ + + + + net5.0 + + + + E:\DiscordBot\BUILDS\ + none + false + + + + + + + diff --git a/EVE_LevelingSystem/LevelingSystem.cs b/EVE_LevelingSystem/LevelingSystem.cs new file mode 100644 index 0000000..9b399b0 --- /dev/null +++ b/EVE_LevelingSystem/LevelingSystem.cs @@ -0,0 +1,36 @@ +using System.Threading.Tasks; + +using Discord.WebSocket; + +using PluginManager.Others; +using PluginManager.Interfaces; +using PluginManager.LanguageSystem; +public class LevelingSystem : DBEvent +{ + public string name => "Leveling System"; + + public string description => "Leveling System Event"; + + public void Start(DiscordSocketClient client) + { + client.MessageReceived += Client_MessageReceived; + } + + private async Task Client_MessageReceived(SocketMessage arg) + { + if (arg.Author.IsBot || arg.Attachments.Count > 0 || arg.Content.StartsWith(Functions.readCodeFromFile(System.IO.Path.Combine(Functions.dataFolder, "DiscordBotCore.data"), "BOT_PREFIX", '\t'))) + return; + + if (Core.playerMessages.ContainsKey(arg.Author.Id)) + return; + + (bool x, int lv) = Core.MessageSent(arg.Author.Id, arg.Content.Length); + Core.playerMessages.Add(arg.Author.Id, arg.Content); + if (x) + if (Language.ActiveLanguage != null) + await arg.Channel.SendMessageAsync(Language.ActiveLanguage.LanguageWords["DB_EVENT_LEVEL_SYSTEM_LEVEL_UP"].Replace("{0}", lv.ToString())); + else await arg.Channel.SendMessageAsync("You've successfully leveled up to level " + lv); + + } +} + diff --git a/PluginManager/Interfaces/DBCommand.cs b/PluginManager/Interfaces/DBCommand.cs new file mode 100644 index 0000000..9fce268 --- /dev/null +++ b/PluginManager/Interfaces/DBCommand.cs @@ -0,0 +1,19 @@ +namespace PluginManager.Interfaces +{ + public interface DBCommand + { + string Command { get; } + + string Description { get; } + + string Usage { get; } + + bool canUseDM { get; } + bool canUseServer { get; } + + void Execute(Discord.Commands.SocketCommandContext context, + Discord.WebSocket.SocketMessage message, + Discord.WebSocket.DiscordSocketClient client, + bool isDM); + } +} \ No newline at end of file diff --git a/PluginManager/Interfaces/DBEvent.cs b/PluginManager/Interfaces/DBEvent.cs new file mode 100644 index 0000000..8741e81 --- /dev/null +++ b/PluginManager/Interfaces/DBEvent.cs @@ -0,0 +1,12 @@ +using Discord.WebSocket; + +namespace PluginManager.Interfaces +{ + public interface DBEvent + { + string name { get; } + string description { get; } + + void Start(DiscordSocketClient client); + } +} diff --git a/PluginManager/Items/CustomProgressBar.cs b/PluginManager/Items/CustomProgressBar.cs new file mode 100644 index 0000000..0efdccc --- /dev/null +++ b/PluginManager/Items/CustomProgressBar.cs @@ -0,0 +1,27 @@ +using System; +namespace PluginManager.Items +{ + public class CustomProgressBar + { + private const char _block = '#'; + private const char _emptyBlock = ' '; + private const char _leftMargin = '['; + private const char _rightMargin = ']'; + + const string _back = "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"; + public static void WriteProgressBar(int percent) + { + Console.Write(_back); + Console.Write(_leftMargin); + var p = (int)((percent / 10f) + .5f); + for (var i = 0; i < 10; ++i) + { + if (i >= p) + Console.Write(_emptyBlock); + else + Console.Write(_block); + } + Console.Write($"{_rightMargin} " + percent + " %"); + } + } +} diff --git a/PluginManager/Items/Spinner.cs b/PluginManager/Items/Spinner.cs new file mode 100644 index 0000000..5888eae --- /dev/null +++ b/PluginManager/Items/Spinner.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; + +namespace PluginManager.Items +{ + public class Spinner + { + public bool isSpinning; + + public Spinner() + { + isSpinning = false; + } + + public async void Start() + { + isSpinning = true; + int cnt = 0; + + while (isSpinning) + { + cnt++; + switch (cnt % 4) + { + case 0: Console.Write("/"); break; + case 1: Console.Write("-"); break; + case 2: Console.Write("\\"); break; + case 3: Console.Write("|"); break; + } + Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); + await Task.Delay(500); + } + } + + public void Stop() + { + isSpinning = false; + } + } +} \ No newline at end of file diff --git a/PluginManager/Language System/Language.cs b/PluginManager/Language System/Language.cs new file mode 100644 index 0000000..97a68a6 --- /dev/null +++ b/PluginManager/Language System/Language.cs @@ -0,0 +1,69 @@ +using PluginManager.Others; +using System.Collections.Generic; + +using System; +using System.IO; + +namespace PluginManager.LanguageSystem +{ + public class Language + { + public static Language? ActiveLanguage = null; + + private static readonly string LanguageFileExtension = ".lng"; + + private Language(string fileName, Dictionary words, string LanguageName) + { + this.fileName = fileName; + this.LanguageName = LanguageName; + LanguageWords = words; + } + + public string LanguageName { get; } + + public string fileName { get; } + + public Dictionary LanguageWords { get; } + + public static Language? CreateLanguageFromFile(string LanguageFileLocation) + { + if (!LanguageFileLocation.EndsWith(LanguageFileExtension)) + { + Console.WriteLine("Failed to load Language from file: " + LanguageFileLocation + + "\nFile extension is not .lng"); + return null; + } + + string[] lines = File.ReadAllLines(LanguageFileLocation); + var languageName = "Unknown"; + var words = new Dictionary(); + + foreach (string line in lines) + { + if (line.StartsWith("#") || line.Length < 4) + continue; + string[] sLine = line.Split('='); + + if (sLine[0] == "LANGUAGE_NAME") + { + languageName = sLine[1]; + continue; + } + + words.Add(sLine[0], sLine[1]); + } + + Functions.WriteLogFile("Successfully loaded language: " + languageName + " from file : " + + LanguageFileLocation.Replace('\\', '/')); + return new Language(LanguageFileLocation, words, languageName); + } + + public string FormatText(string text, params string[] args) + { + if (ActiveLanguage == null) return text; + int l = args.Length; + for (var i = 0; i < l; i++) text = text.Replace($"{i}", args[i]); + return text; + } + } +} \ No newline at end of file diff --git a/PluginManager/Loaders/CommandsLoader.cs b/PluginManager/Loaders/CommandsLoader.cs new file mode 100644 index 0000000..b1cea89 --- /dev/null +++ b/PluginManager/Loaders/CommandsLoader.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using PluginManager.Interfaces; + +namespace PluginManager.Loaders +{ + public class CommandsLoader + { + private readonly string CMDPath; + private readonly string CMDExtension; + + public delegate void onCommandLoaded(string name, bool success, DBCommand? command = null, Exception? exception = null); + + public delegate void onCommandFileLoaded(string path); + + public onCommandLoaded? OnCommandLoaded; + public onCommandFileLoaded? OnCommandFileLoaded; + + public CommandsLoader(string CommandPath, string CommandExtension) + { + CMDPath = CommandPath; + CMDExtension = CommandExtension; + } + + public List? LoadCommands() + { + if (!Directory.Exists(CMDPath)) + { + Directory.CreateDirectory(CMDPath); + return null; + } + string[] files = Directory.GetFiles(CMDPath, $"*{CMDExtension}", SearchOption.AllDirectories); + + foreach (var file in files) + { + Assembly.LoadFile(Path.GetFullPath(file)); + if (OnCommandFileLoaded != null) + OnCommandFileLoaded.Invoke(file); + } + + List plugins = new List(); + + try + { + Type interfaceType = typeof(DBCommand); + Type[] types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + foreach (Type type in types) + { + try + { + DBCommand plugin = (DBCommand)Activator.CreateInstance(type)!; + plugins.Add(plugin); + + if (OnCommandLoaded != null) + OnCommandLoaded.Invoke(type.FullName!, true, plugin); + } + catch (Exception e) + { + if (OnCommandLoaded != null) + OnCommandLoaded.Invoke(type.FullName!, false, null, e); + } + + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return null; + } + + return plugins; + + } + } +} diff --git a/PluginManager/Loaders/EventsLoader.cs b/PluginManager/Loaders/EventsLoader.cs new file mode 100644 index 0000000..d7fdc74 --- /dev/null +++ b/PluginManager/Loaders/EventsLoader.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; + +using PluginManager.Interfaces; + +namespace PluginManager.Loaders +{ + public class EventsLoader + { + + private readonly string EVPath; + private readonly string EVExtension; + + public delegate void onEventLoad(string name, bool success, DBEvent? ev = null, Exception? e = null); + public delegate void onEventFileLoaded(string path); + + public onEventLoad? EventLoad; + public onEventFileLoaded? EventFileLoaded; + + public EventsLoader(string path, string ext) + { + EVPath = path; + EVExtension = ext; + } + + public List? LoadEvents() + { + + if (!Directory.Exists(EVPath)) + { + Directory.CreateDirectory(EVPath); + return null; + } + + string[] files = Directory.GetFiles(EVPath, $"*{EVExtension}", SearchOption.AllDirectories); + + foreach (var file in files) + { + Assembly.LoadFile(Path.GetFullPath(file)); + if (EventFileLoaded != null) + EventFileLoaded.Invoke(file); + } + + List events = new List(); + + try + { + Type interfaceType = typeof(DBEvent); + Type[] types = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) + .ToArray(); + foreach (Type type in types) + { + try + { + DBEvent ev = (DBEvent)Activator.CreateInstance(type)!; + events.Add(ev); + + if (EventLoad != null) + EventLoad.Invoke(type.FullName!, true, ev); + } + catch (Exception e) + { + if (EventLoad != null) + EventLoad.Invoke(type.FullName!, false, null, e); + } + + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return null; + } + + return events; + + } + } +} \ No newline at end of file diff --git a/PluginManager/Loaders/PluginLoader.cs b/PluginManager/Loaders/PluginLoader.cs new file mode 100644 index 0000000..d223d58 --- /dev/null +++ b/PluginManager/Loaders/PluginLoader.cs @@ -0,0 +1,86 @@ +using Discord.WebSocket; + +using PluginManager.Interfaces; +using PluginManager.Others; + +using System; +using System.Collections.Generic; +namespace PluginManager.Loaders +{ + public class PluginLoader + { + private DiscordSocketClient client; + public PluginLoader(DiscordSocketClient discordSocketClient) + { + this.client = discordSocketClient; + } + + private const string pluginCMDFolder = @"./Data/Plugins/Commands/"; + private const string pluginEVEFolder = @"./Data/Plugins/Events/"; + + private const string pluginCMDExtension = ".dll"; + private const string pluginEVEExtension = ".dll"; + + + public static List? Plugins { get; set; } + public static List? Events { get; set; } + + public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null); + + public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null); + + public CMDLoaded? onCMDLoad; + public EVELoaded? onEVELoad; + + public void LoadPlugins() + { + + Plugins = new List(); + Events = new List(); + + Functions.WriteLogFile("Starting plugin loader..."); + if (LanguageSystem.Language.ActiveLanguage != null) + Functions.WriteColorText(LanguageSystem.Language.ActiveLanguage.FormatText(LanguageSystem.Language.ActiveLanguage.LanguageWords["PLUGIN_LOADING_START"])); + + //Load commands + CommandsLoader CMDLoader = new CommandsLoader(pluginCMDFolder, pluginCMDExtension); + CMDLoader.OnCommandLoaded += OnCommandLoaded!; + CMDLoader.OnCommandFileLoaded += OnCommandFileLoaded; + Plugins = CMDLoader.LoadCommands(); + + + //Load Events + EventsLoader EVLoader = new EventsLoader(pluginEVEFolder, pluginEVEExtension); + EVLoader.EventLoad += OnEventLoaded!; + EVLoader.EventFileLoaded += EventFileLoaded; + Events = EVLoader.LoadEvents(); + + } + + private void EventFileLoaded(string path) + { + if (path != null) + Functions.WriteLogFile($"[EVENT] Event from file [{path}] has been successfully created !"); + } + + private void OnCommandFileLoaded(string path) + { + if (path != null) + Functions.WriteLogFile($"[CMD] Command from file [{path}] has been successfully loaded !"); + } + + private void OnEventLoaded(string typename, bool success, DBEvent eve, Exception exception) + { + if (eve != null && success) + eve.Start(client); + if (onEVELoad != null) + onEVELoad.Invoke(eve!.name, typename, success, exception); + } + + private void OnCommandLoaded(string name, bool success, DBCommand command, Exception exception) + { + if (onCMDLoad != null) + onCMDLoad.Invoke(command.Command, name, success, exception); + } + } +} diff --git a/PluginManager/Online/Downloader.cs b/PluginManager/Online/Downloader.cs new file mode 100644 index 0000000..5c439a6 --- /dev/null +++ b/PluginManager/Online/Downloader.cs @@ -0,0 +1,82 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; + +using PluginManager.Items; + +namespace PluginManager.Online +{ + public class Downloader + { + public bool isWorking { get; private set; } + + public int percent { get; private set; } + private string fileName; + private string downloadLink; + + public Downloader(string fileName, string fileLink) + { + this.downloadLink = fileLink; + this.fileName = fileName; + } + + + public async Task DownloadFileAsync(string location = @"./Downloads/", string? pluginType = null) + { + Directory.CreateDirectory(location); + if (isWorking) return; + isWorking = true; + percent = 0; + + Spinner s = new Spinner(); + Console.Write("Downloading:\t\t"); + s.Start(); + +#pragma warning disable SYSLIB0014 + WebClient client = new WebClient(); +#pragma warning restore SYSLIB0014 + + client.DownloadFileCompleted += (sender, args) => + { + isWorking = false; + s.Stop(); + var c = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.DarkGreen; + Console.Write("OK"); + Console.ForegroundColor = c; + Console.Write(" !\n"); + //Console.WriteLine("Your plugin has been successfully downloaded !"); + if (pluginType == "Event/Command" || pluginType == "Command/Event") + { + File.Copy(location + fileName, location + "Commands/" + fileName, true); + File.Move(location + fileName, location + "Events/" + fileName, true); + } + + }; + + string l = ""; + if (pluginType == "Command") + l = location + "Commands/" + fileName; + else if (pluginType == "Event") + l = location + "Events/" + fileName; + else l = location + fileName; + try + { + await client.DownloadFileTaskAsync(new Uri(this.downloadLink), l); + } + catch + { + var c = Console.ForegroundColor; + Console.ForegroundColor = ConsoleColor.Red; + Console.Write("FAIL"); + Console.ForegroundColor = c; + Console.Write(" !\n"); + } + + + + } + + } +} diff --git a/PluginManager/Online/LanguageManager.cs b/PluginManager/Online/LanguageManager.cs new file mode 100644 index 0000000..5c97711 --- /dev/null +++ b/PluginManager/Online/LanguageManager.cs @@ -0,0 +1,75 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Net; +using System.Collections.Generic; + +using PluginManager.Others; + +namespace PluginManager.Online +{ + public class LanguageManager + { + private string link; + public LanguageManager(string link) => this.link = link; + + public async Task ListAllLanguages() + { + try + { +#pragma warning disable SYSLIB0014 + WebClient client = new WebClient(); +#pragma warning restore SYSLIB0014 + Stream data = await client.OpenReadTaskAsync(link); + string[] lines = (await new StreamReader(data).ReadToEndAsync()).Split('\n'); + List info = new List(); + info.Add(new string[] { "-", "-" }); + info.Add(new string[] { "Language Name", "File Size" }); + info.Add(new string[] { "-", "-" }); + foreach (var line in lines) + { + if (line.Length <= 2) continue; + string[] d = line.Split(','); + if (d[3].Contains("cp") || d[3].Contains("CrossPlatform")) + info.Add(new string[] { d[0], d[1] }); + } + info.Add(new string[] { "-", "-" }); + Functions.FormatAndAlignTable(info); + } + + catch (Exception exception) + { + Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message); + Others.Functions.WriteErrFile(exception.ToString()); + } + + } + + public async Task GetDownloadLink(string langName) + { + try + { +#pragma warning disable SYSLIB0014 + WebClient client = new WebClient(); +#pragma warning restore SYSLIB0014 + Stream data = await client.OpenReadTaskAsync(link); + string[] lines = (await new StreamReader(data).ReadToEndAsync()).Split('\n'); + foreach (var line in lines) + { + if (line.Length <= 2) continue; + string[] d = line.Split(','); + if (d[0].Equals(langName) && (d[3].Contains("cp") || d[3].Contains("CrossPlatform"))) + return new string[] { d[2], d[3] }; + } + } + catch (Exception exception) + { + Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message); + Others.Functions.WriteErrFile(exception.ToString()); + } + + + return null; + } + } +} \ No newline at end of file diff --git a/PluginManager/Online/PluginsManager.cs b/PluginManager/Online/PluginsManager.cs new file mode 100644 index 0000000..35af46e --- /dev/null +++ b/PluginManager/Online/PluginsManager.cs @@ -0,0 +1,108 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using System.Collections.Generic; + +using PluginManager.Others; + +namespace PluginManager.Online +{ + public class PluginsManager + { + public string PluginsLink { get; private set; } + + public PluginsManager(string link) + { + PluginsLink = link; + } + + public async Task ListAvailablePlugins() + { + try + { +#pragma warning disable SYSLIB0014 + WebClient client = new WebClient(); +#pragma warning restore SYSLIB0014 + Stream s = await client.OpenReadTaskAsync(PluginsLink); + string text = await new StreamReader(s).ReadToEndAsync(); + + + List data = new List(); + var op = Functions.GetOperatinSystem(); + string[] lines = text.Split('\n'); + int len = lines.Length; + string[] titles = { "Name", "Description", "Plugin Type" }; + data.Add(new string[] { "-", "-", "-" }); + data.Add(titles); + data.Add(new string[] { "-", "-", "-" }); + for (int i = 0; i < len; i++) + { + if (lines[i].Length <= 2) continue; + string[] content = lines[i].Split(','); + string[] display = new string[3]; + if (op == PluginManager.Others.OperatingSystem.WINDOWS) + { + if (content[4].Contains("Windows")) + { + display[0] = content[0]; + display[1] = content[1]; + display[2] = content[2]; + data.Add(display); + continue; + } + } + else if (op == PluginManager.Others.OperatingSystem.LINUX) + { + if (content[4].Contains("Linux")) + { + display[0] = content[0]; + display[1] = content[1]; + display[2] = content[2]; + data.Add(display); + continue; + } + } + } + + data.Add(new string[] { "-", "-", "-" }); + + Functions.FormatAndAlignTable(data); + } + catch (Exception exception) + { + Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message); + Others.Functions.WriteErrFile(exception.ToString()); + } + + } + + public async Task GetPluginLinkByName(string name) + { + try + { +#pragma warning disable SYSLIB0014 + WebClient client = new WebClient(); +#pragma warning restore SYSLIB0014 + Stream s = await client.OpenReadTaskAsync(PluginsLink); + string text = await new StreamReader(s).ReadToEndAsync(); + + string[] lines = text.Split('\n'); + int len = lines.Length; + for (int i = 0; i < len; i++) + { + string[] contents = lines[i].Split(','); + if (contents[0] == name) + return new string[] { contents[2], contents[3] }; + } + } + catch (Exception exception) + { + Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message); + Others.Functions.WriteErrFile(exception.ToString()); + } + + return new string[] { null!, null! }; + } + } +} diff --git a/PluginManager/Others/Channels.cs b/PluginManager/Others/Channels.cs new file mode 100644 index 0000000..84682a7 --- /dev/null +++ b/PluginManager/Others/Channels.cs @@ -0,0 +1,15 @@ +using Discord; + +using System.Threading.Tasks; + +namespace PluginManager.Others +{ + public static class ChannelManagement + { + public static IGuildChannel GetTextChannel(this IGuild server, string name) => server.GetTextChannel(name); + public static IGuildChannel GetVoiceChannel(this IGuild server, string name) => server.GetVoiceChannel(name); + public static async Task GetDMChannel(IGuildUser user) => await user.CreateDMChannelAsync(); + public static IChannel GetChannel(IMessage message) => message.Channel; + + } +} \ No newline at end of file diff --git a/PluginManager/Others/Cryptography.cs b/PluginManager/Others/Cryptography.cs new file mode 100644 index 0000000..d9e53e4 --- /dev/null +++ b/PluginManager/Others/Cryptography.cs @@ -0,0 +1,44 @@ +namespace PluginManager.Others +{ + public class Cryptography + { + public static async System.Threading.Tasks.Task CreateMD5(string text) + { + string output = ""; + using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) + { + using (var s = GenerateStreamFromString(text)) + { + byte[] t = await md5.ComputeHashAsync(s); + output = System.Convert.ToBase64String(t); + } + } + + return output; + } + + public static async System.Threading.Tasks.Task CreateSHA256(string text) + { + string output = ""; + using (System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create()) + { + using (var s = GenerateStreamFromString(text)) + { + byte[] t = await sha.ComputeHashAsync(s); + output = System.Convert.ToBase64String(t); + } + } + return output; + } + + public static System.IO.Stream GenerateStreamFromString(string s) + { + var stream = new System.IO.MemoryStream(); + var writer = new System.IO.StreamWriter(stream); + writer.Write(s); + writer.Flush(); + stream.Position = 0; + return stream; + } + } +} \ No newline at end of file diff --git a/PluginManager/Others/Enums.cs b/PluginManager/Others/Enums.cs new file mode 100644 index 0000000..90d89a4 --- /dev/null +++ b/PluginManager/Others/Enums.cs @@ -0,0 +1,14 @@ +namespace PluginManager.Others +{ + + /// + /// A list of operating systems + /// + public enum OperatingSystem + { WINDOWS, LINUX, MAC_OS, UNKNOWN } + + public enum Error + { UNKNOWN_ERROR, GUILD_NOT_FOUND, } + + public enum OutputLogLevel { NONE, INFO, WARNING, ERROR, CRITICAL } +} \ No newline at end of file diff --git a/PluginManager/Others/Exceptions/APIException.cs b/PluginManager/Others/Exceptions/APIException.cs new file mode 100644 index 0000000..34d6b48 --- /dev/null +++ b/PluginManager/Others/Exceptions/APIException.cs @@ -0,0 +1,37 @@ +using System; + +namespace PluginManager.Others.Exceptions +{ + [System.Serializable] + public class APIException : Exception + { + public string? Function { get; } + public Error? ErrorCode { get; } + + public APIException(string message, string? function, Error? errorCode) : base(message) + { + ErrorCode = errorCode; + Function = function; + } + + public APIException(string message, string? function) : base(message) + { + ErrorCode = Error.UNKNOWN_ERROR; + Function = function; + } + + public APIException(string message) : base(message) + { + ErrorCode = Error.UNKNOWN_ERROR; + Function = "Unspecified_Function"; + } + + public void Print() + { + Console.WriteLine("Message Content: " + Message); + Console.WriteLine("Function: " + Function); + Console.WriteLine("Error Code: " + ErrorCode.ToString()); + } + } + +} \ No newline at end of file diff --git a/PluginManager/Others/Functions.cs b/PluginManager/Others/Functions.cs new file mode 100644 index 0000000..d8ba88b --- /dev/null +++ b/PluginManager/Others/Functions.cs @@ -0,0 +1,300 @@ +using System.IO.Compression; +using System.IO; +using System; +using System.Threading.Tasks; +using System.Linq; +using System.Collections.Generic; + + +namespace PluginManager.Others +{ + public static class Functions + { + /// + /// The location for the Resources folder + /// + public static readonly string dataFolder = @"./Data/Resources/"; + + /// + /// The location for all logs + /// + public static readonly string logFolder = @"./Output/Logs/"; + + /// + /// The location for all errors + /// + public static readonly string errFolder = @"./Output/Errors/"; + + /// + /// The location for all languages + /// + public static readonly string langFolder = @"./Data/Languages/"; + + /// + /// Archives folder + /// + public static readonly string pakFolder = @"./Data/Resources/PAKS/"; + + /// + /// The mark that the line is a comment + /// + private static readonly char commentMark = '#'; + + /// + /// Read data from file + /// + /// File name + /// Setting name + /// Separator between setting key code and its value + /// The value of the specified setting key code in the specified file (STRING) + public static string? readCodeFromFile(string fileName, string Code, char separator) + => File.ReadAllLines(fileName) + .Where(p => p.StartsWith(Code) && !p.StartsWith(commentMark.ToString())) + .First().Split(separator)[1] ?? null; + + /// + /// Read data from a file that is inside an archive (ZIP format) + /// + /// The file name that is inside the archive or its full path + /// The archive location from the PAKs folder + /// A string that represents the content of the file or null if the file does not exists or it has no content + public static async Task ReadFromPakAsync(string FileName, string archFile) + { + archFile = pakFolder + archFile; + Directory.CreateDirectory(pakFolder); + if (!File.Exists(archFile)) + { + throw new Exception("Failed to load file !"); + } + + string? textValue = null; + var fs = new FileStream(archFile, FileMode.Open); + var zip = new ZipArchive(fs, ZipArchiveMode.Read); + foreach (var entry in zip.Entries) + { + if (entry.Name == FileName || entry.FullName == FileName) + { + Stream s = entry.Open(); + StreamReader reader = new StreamReader(s); + textValue = await reader.ReadToEndAsync(); + reader.Close(); + s.Close(); + fs.Close(); + break; + } + } + return textValue; + } + + /// + /// Write logs to file + /// + /// The message to be wrote + public static void WriteLogFile(string LogMessage) + { + string logsPath = logFolder + "Log.txt"; + if (!Directory.Exists(logFolder)) + Directory.CreateDirectory(logFolder); + File.AppendAllText(logsPath, LogMessage + " \n"); + } + + /// + /// Write error to file + /// + /// The message to be wrote + public static void WriteErrFile(string ErrMessage) + { + string errPath = errFolder + "Error.txt"; + if (!Directory.Exists(errFolder)) + Directory.CreateDirectory(errFolder); + File.AppendAllText(errPath, ErrMessage + " \n"); + } + + /// + /// Write to settings file + /// + /// The settings file path + /// The Key value of the setting + /// The new value of the settings + /// The separator between the key and the value + public static void WriteToSettings(string file, string Code, string newValue, char separator) + { + + string[] lines = File.ReadAllLines(file); + File.Delete(file); + bool ok = false; + foreach (var line in lines) + if (line.StartsWith(Code)) + { + File.AppendAllText(file, Code + separator + newValue + "\n"); ok = true; + } + else File.AppendAllText(file, line + "\n"); + + if (!ok) + File.AppendAllText(file, Code + separator + newValue + "\n"); + } + + /// + /// Merge one array of strings into one string + /// + /// The array of strings + /// The index from where the merge should start (included) + /// A string built based on the array + public static string MergeStrings(this string[] s, int indexToStart) + { + string r = ""; + int len = s.Length; + if (len <= indexToStart) return ""; + for (int i = indexToStart; i < len - 1; ++i) + { + r += s[i] + " "; + } + + r += s[len - 1]; + + return r; + } + + /// + /// Get the Operating system you are runnin on + /// + /// An Operating system + public static OperatingSystem GetOperatinSystem() + { + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) return OperatingSystem.WINDOWS; + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Linux)) return OperatingSystem.LINUX; + if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.OSX)) return OperatingSystem.MAC_OS; + return OperatingSystem.UNKNOWN; + } + + /// + /// A way to create a table based on input data + /// EpicWings (Pasca Robert) este cel mai bun + /// Special thanks to Kami-sama <3 + /// + /// The List of arrays of strings that represent the rows. + public static void FormatAndAlignTable(List data) + { + int maxLen = 0; + foreach (string[] row in data) + foreach (string s in row) + if (s.Length > maxLen) + maxLen = s.Length; + + int div = (maxLen + 4) / 2; + + foreach (string[] row in data) + { + Console.Write("\t"); + if (row[0] == "-") Console.Write("+"); + else Console.Write("|"); + + foreach (string s in row) + { + if (s == "-") + { + for (int i = 0; i < maxLen + 4; ++i) + Console.Write("-"); + } + else if (s.Length == maxLen) + { + Console.Write(" "); + Console.Write(s); + Console.Write(" "); + } + else + { + int lenHalf = s.Length / 2; + for (int i = 0; i < div - lenHalf; ++i) + Console.Write(" "); + Console.Write(s); + for (int i = div + lenHalf + 1; i < maxLen + 4; ++i) + Console.Write(" "); + if (s.Length % 2 == 0) + Console.Write(" "); + } + + if (s == "-") Console.Write("+"); + else Console.Write("|"); + } + Console.WriteLine(); //end line + } + } + + /// + /// Write the text using color options( &g-green; &b-blue; &r-red; &c-clear; ) + /// + /// The text + public static void WriteColorText(string text) + { + string[] words = text.Split(' '); + Dictionary colors = new Dictionary() + { + {"&g", ConsoleColor.Green }, + {"&b", ConsoleColor.Blue }, + {"&r", ConsoleColor.Red }, + {"&c", Console.ForegroundColor } + }; + foreach (string word in words) + { + if (word.Length >= 2) + { + string prefix = word.Substring(0, 2); + if (colors.ContainsKey(prefix)) + Console.ForegroundColor = colors[prefix]; + } + + string m = word.Replace("&g", "").Replace("&b", "").Replace("&r", "").Replace("&c", ""); + Console.Write(m + " "); + } + Console.Write('\n'); + } + + /// + /// Write setting + /// + /// The full path to the setting + /// The new Value + public static void WriteToSettingsFast(string SettingName, string NewValue) + { + + string path = dataFolder; // Resources/ + + string[] args = SettingName.Split('.'); + + int len = args.Length; + if (len < 2) return; + for (int i = 0; i < len - 2; i++) + path += args[i] + "/"; + path += args[len - 2] + ".txt"; + + + WriteToSettings(path, args[len - 1].Replace('_', ' '), NewValue, '='); + + } + + public static string FromHexToString(string hexString) + { + var bytes = new byte[hexString.Length / 2]; + for (var i = 0; i < bytes.Length; i++) + { + bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + } + + return System.Text.Encoding.Unicode.GetString(bytes); + } + + public static string ToHexString(string str) + { + var sb = new System.Text.StringBuilder(); + + var bytes = System.Text.Encoding.Unicode.GetBytes(str); + foreach (var t in bytes) + { + sb.Append(t.ToString("X2")); + } + + return sb.ToString(); + } + } +} diff --git a/PluginManager/Others/Permissions.cs b/PluginManager/Others/Permissions.cs new file mode 100644 index 0000000..9d1ea87 --- /dev/null +++ b/PluginManager/Others/Permissions.cs @@ -0,0 +1,20 @@ +using Discord; +using Discord.WebSocket; + +using System.Linq; + +namespace PluginManager.Others +{ + public static class Permissions + { + public static bool hasPermission(this IRole role, GuildPermission permission) => role.Permissions.Has(permission); + + public static bool hasRole(this SocketGuildUser user, IRole role) => user.Roles.Contains(role); + + public static bool hasPermission(this SocketGuildUser user, GuildPermission permission) + => user.Roles.Where(role => role.hasPermission(permission)).Any(); + + } + + +} \ No newline at end of file diff --git a/PluginManager/PluginManager.csproj b/PluginManager/PluginManager.csproj new file mode 100644 index 0000000..c084911 --- /dev/null +++ b/PluginManager/PluginManager.csproj @@ -0,0 +1,12 @@ + + + + net5.0 + enable + + + + + + + diff --git a/StartupEvents/OnUserJoin.cs b/StartupEvents/OnUserJoin.cs new file mode 100644 index 0000000..ce5bbf7 --- /dev/null +++ b/StartupEvents/OnUserJoin.cs @@ -0,0 +1,56 @@ +using PluginManager.Others; +using PluginManager.Interfaces; + +public class OnUserJoin : DBEvent +{ + public string name => "OnPlayerJoin"; + + public string description => "An event that is triggered when an user joins the server"; + + public async void Start(Discord.WebSocket.DiscordSocketClient client) + { + + string UtilsPath = Functions.dataFolder + "StartupEvents/"; + string ConfigFile = UtilsPath + "UserJoinEvent.txt"; + + System.IO.Directory.CreateDirectory(UtilsPath); + + if (!System.IO.File.Exists(ConfigFile)) + { + await System.IO.File.WriteAllTextAsync(ConfigFile, + "Enabled=True\nEmbed=True\n" + + "#Available placeholders:\n" + + "#{user.Name} => Username of the user\n" + + "#{time.date} => Current Date\n" + + "#{time.time} => Current time (hh:mm::ss)\n" + + "MessageTitle = Welcome {user.Name}\n" + + "MessageDescription=Embed description\n" + + "MessageField1Title=Custom Title\n" + + "MessageFiled1Text=Custom Filed 1 text\n" + + "MessageField2Title=Custom Title\n" + + "MessageFiled2Text=Custom Filed 2 text\n" + + "MessageFooter=Today: {time.date} at {time.time}"); + } + + if (Functions.readCodeFromFile(ConfigFile, "Enabled", '=') != "True") return; + + client.UserJoined += async (user) => + { + Discord.EmbedBuilder embed = new Discord.EmbedBuilder + { + Title = Functions.readCodeFromFile(ConfigFile, "MessageTitle", '='), + Description = Functions.readCodeFromFile(ConfigFile, "MessageDescription", '=') + }; + + embed + .AddField(Functions.readCodeFromFile(ConfigFile, "MessageField1Title", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString()), Functions.readCodeFromFile(ConfigFile, "MessageField1Text", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString())) + .AddField(Functions.readCodeFromFile(ConfigFile, "MessageField2Title", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString()), Functions.readCodeFromFile(ConfigFile, "MessageField2Text", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString())) + .WithFooter(Functions.readCodeFromFile(ConfigFile, "MessageFooter", '=').Replace("{user.Name}", user.Username).Replace("{time.date}", System.DateTime.Now.ToShortDateString()).Replace("{time.time}", System.DateTime.Now.ToShortTimeString())); + + await user.Guild.DefaultChannel.SendMessageAsync(embed: embed.Build()); + // await (await user.GetOrCreateDMChannelAsync()).SendMessageAsync(embed: embed.Build()); + }; + + + } +} \ No newline at end of file diff --git a/StartupEvents/SetGameOnLogin.cs b/StartupEvents/SetGameOnLogin.cs new file mode 100644 index 0000000..4a2d2d9 --- /dev/null +++ b/StartupEvents/SetGameOnLogin.cs @@ -0,0 +1,48 @@ +public class SetGameOnLogin : PluginManager.Interfaces.DBEvent +{ + public string name => "Set Game on Startup"; + public string description => "Set Custom Game to the bot at initialization"; + public async void Start(Discord.WebSocket.DiscordSocketClient client) + { + string UtilsPath = PluginManager.Others.Functions.dataFolder + "StartupEvents/"; + string ConfigFile = UtilsPath + "LoginEvent.txt"; + + System.IO.Directory.CreateDirectory(UtilsPath); + if (!System.IO.File.Exists(ConfigFile)) + { + System.Console.WriteLine($"First time setup. Open file: {ConfigFile} to change settings or use the following commands\nNote: For space ( ) use underline (_). Example: 'Hello_World' will output 'Hello World'"); + System.Console.WriteLine($"set-setting StartupEvents.LoginEvent.Title [Custom_Title(s)]"); + System.Console.WriteLine($"set-setting StartupEvents.LoginEvent.Dynamic_Title [True/False]"); + System.Console.WriteLine($"set-setting StartupEvents.LoginEvent.Dynamic_Title_Change_Rate [interval in milliseconds]"); + await System.IO.File.WriteAllTextAsync(ConfigFile, "Enabled=True\n\nDynamic Title=False\n#For dynamic title add titles like this:\n#Title=Hello,World,Test,Test2\nTitle=!help\nDynamic Title Change Rate=3500\n"); + } + + if (PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Enabled", '=') != "True") + return; + + bool isDynamic = PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Dynamic Title", '=') == "True"; + string Title = PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Title", '='); + if (Title == null || Title.Length < 2) return; + if (!isDynamic) + await client.SetGameAsync(Title, null, Discord.ActivityType.Playing); + else + { + string[] Titles = Title.Split(','); + int delayMS = 3500; + try + { + delayMS = int.Parse(PluginManager.Others.Functions.readCodeFromFile(ConfigFile, "Dynamic Title Change Rate", '=')); + } + catch { } + while (true) + { + foreach (var title in Titles) + { + await client.SetGameAsync(title, null, Discord.ActivityType.Playing); + await System.Threading.Tasks.Task.Delay(delayMS); + } + } + } + + } +} \ No newline at end of file diff --git a/StartupEvents/StartupEvents.csproj b/StartupEvents/StartupEvents.csproj new file mode 100644 index 0000000..7cb7c93 --- /dev/null +++ b/StartupEvents/StartupEvents.csproj @@ -0,0 +1,17 @@ + + + + net5.0 + + + + E:\DiscordBot\BUILDS\ + none + false + + + + + + +