Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e4c60f1606 | |||
| 77f1bef862 | |||
| f16c139362 | |||
| c94cdca6eb | |||
| dcdf80112d | |||
| eb836c5b74 | |||
| de680c6771 | |||
|
|
bcef58a46b | ||
|
|
0dc8cdbce5 | ||
|
|
dbdbaa9802 | ||
|
|
5edcf93371 | ||
|
|
b0be76c62b | ||
| 75a77389a8 | |||
| 0bbced3d58 | |||
| 244209093e | |||
| 54a68d635d | |||
| d7a5cb5a64 | |||
| 6124f89cb0 | |||
| 810a527cc1 | |||
| 0a2dff0c6d | |||
| 382c376c03 | |||
| 84b7d663bc | |||
| 623232b67e | |||
| d5df6cfb9d | |||
| 10b9548c29 | |||
| fa1a136ef1 | |||
| d20cb62139 | |||
| f2418d0395 | |||
| 460a85944a | |||
| 7e2fa02d07 | |||
| 873855937f | |||
| 1cdd2644df | |||
| 532540b74f | |||
| 9ba4ca43e2 | |||
| 8bcaf3f254 | |||
| 0d5c90323a | |||
| 5b01b15216 | |||
| 4f18f505f4 | |||
| 2d3566a01a | |||
| 22f2cd4e59 | |||
| 1683234376 | |||
| 69d99b4189 | |||
| 4a5e0ef2f3 | |||
| 79731a9704 | |||
| bd53d099d1 | |||
| de61f5de88 | |||
| 0527d43dd2 | |||
| e3511cd96b | |||
| d355d3c9b7 | |||
| 5bb13aa4a6 | |||
| 655f5e2ce0 | |||
| 9014d78a7d | |||
| 1c026e7f49 | |||
| d32b3902c9 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -98,6 +98,7 @@ StyleCopReport.xml
|
|||||||
*.pidb
|
*.pidb
|
||||||
*.svclog
|
*.svclog
|
||||||
*.scc
|
*.scc
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
# Chutzpah Test files
|
# Chutzpah Test files
|
||||||
_Chutzpah*
|
_Chutzpah*
|
||||||
@@ -370,3 +371,6 @@ FodyWeavers.xsd
|
|||||||
/DiscordBot.rar
|
/DiscordBot.rar
|
||||||
/DiscordBot/Data/
|
/DiscordBot/Data/
|
||||||
/DiscordBot/Updater/
|
/DiscordBot/Updater/
|
||||||
|
.idea/
|
||||||
|
/DiscordBotWeb/
|
||||||
|
DiscordBot/Launcher.exe
|
||||||
|
|||||||
26
.vscode/launch.json
vendored
Normal file
26
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
// Use IntelliSense to find out which attributes exist for C# debugging
|
||||||
|
// Use hover for the description of the existing attributes
|
||||||
|
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
|
||||||
|
"name": ".NET Core Launch (console)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"preLaunchTask": "build",
|
||||||
|
// If you have changed target frameworks, make sure to update the program path.
|
||||||
|
"program": "${workspaceFolder}/DiscordBot/bin/Debug/net6.0/DiscordBot.dll",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}/DiscordBot/bin/Debug/net6.0/",
|
||||||
|
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||||
|
"console": "externalTerminal",
|
||||||
|
"stopAtEntry": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": ".NET Core Attach",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "attach"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
41
.vscode/tasks.json
vendored
Normal file
41
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"${workspaceFolder}/DiscordBot/DiscordBot.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "publish",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"publish",
|
||||||
|
"${workspaceFolder}/DiscordBot/DiscordBot.csproj",
|
||||||
|
"/property:GenerateFullPaths=true",
|
||||||
|
"/consoleloggerparameters:NoSummary"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "watch",
|
||||||
|
"command": "dotnet",
|
||||||
|
"type": "process",
|
||||||
|
"args": [
|
||||||
|
"watch",
|
||||||
|
"run",
|
||||||
|
"--project",
|
||||||
|
"${workspaceFolder}/DiscordBot/DiscordBot.csproj"
|
||||||
|
],
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Commands;
|
|
||||||
|
|
||||||
using PluginManager;
|
using PluginManager;
|
||||||
using PluginManager.Interfaces;
|
using PluginManager.Interfaces;
|
||||||
@@ -41,19 +40,16 @@ internal class Help : DBCommand
|
|||||||
/// The main body of the command
|
/// The main body of the command
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">The command context</param>
|
/// <param name="context">The command context</param>
|
||||||
public void ExecuteServer(SocketCommandContext context)
|
public void ExecuteServer(DBCommandExecutingArguments args)
|
||||||
{
|
{
|
||||||
var args = Functions.GetArguments(context.Message);
|
if (args.arguments is not null)
|
||||||
if (args.Count != 0)
|
|
||||||
{
|
{
|
||||||
foreach (var item in args)
|
var e = GenerateHelpCommand(args.arguments[0]);
|
||||||
{
|
|
||||||
var e = GenerateHelpCommand(item);
|
|
||||||
if (e is null)
|
if (e is null)
|
||||||
context.Channel.SendMessageAsync("Unknown Command " + item);
|
args.context.Channel.SendMessageAsync("Unknown Command " + args.arguments[0]);
|
||||||
else
|
else
|
||||||
context.Channel.SendMessageAsync(embed: e.Build());
|
args.context.Channel.SendMessageAsync(embed: e.Build());
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -63,25 +59,28 @@ internal class Help : DBCommand
|
|||||||
var adminCommands = "";
|
var adminCommands = "";
|
||||||
var normalCommands = "";
|
var normalCommands = "";
|
||||||
|
|
||||||
foreach (var cmd in PluginLoader.Commands!)
|
foreach (var cmd in PluginLoader.Commands)
|
||||||
if (cmd.requireAdmin)
|
if (cmd.requireAdmin)
|
||||||
adminCommands += cmd.Command + " ";
|
adminCommands += cmd.Command + " ";
|
||||||
else
|
else
|
||||||
normalCommands += cmd.Command + " ";
|
normalCommands += cmd.Command + " ";
|
||||||
|
|
||||||
|
|
||||||
|
if (adminCommands.Length > 0)
|
||||||
embedBuilder.AddField("Admin Commands", adminCommands);
|
embedBuilder.AddField("Admin Commands", adminCommands);
|
||||||
|
if (normalCommands.Length > 0)
|
||||||
embedBuilder.AddField("Normal Commands", normalCommands);
|
embedBuilder.AddField("Normal Commands", normalCommands);
|
||||||
context.Channel.SendMessageAsync(embed: embedBuilder.Build());
|
args.context.Channel.SendMessageAsync(embed: embedBuilder.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
private EmbedBuilder GenerateHelpCommand(string command)
|
private EmbedBuilder GenerateHelpCommand(string command)
|
||||||
{
|
{
|
||||||
var embedBuilder = new EmbedBuilder();
|
var embedBuilder = new EmbedBuilder();
|
||||||
var cmd = PluginLoader.Commands!.Find(p => p.Command == command ||
|
var cmd = PluginLoader.Commands.Find(p => p.Command == command ||
|
||||||
(p.Aliases is not null && p.Aliases.Contains(command)));
|
(p.Aliases is not null && p.Aliases.Contains(command)));
|
||||||
if (cmd == null) return null;
|
if (cmd == null) return null;
|
||||||
|
|
||||||
embedBuilder.AddField("Usage", Config.Variables.GetValue("prefix") + cmd.Usage);
|
embedBuilder.AddField("Usage", Config.Data["prefix"] + cmd.Usage);
|
||||||
embedBuilder.AddField("Description", cmd.Description);
|
embedBuilder.AddField("Description", cmd.Description);
|
||||||
if (cmd.Aliases is null)
|
if (cmd.Aliases is null)
|
||||||
return embedBuilder;
|
return embedBuilder;
|
||||||
|
|||||||
@@ -1,100 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using PluginManager.Interfaces;
|
|
||||||
using PluginManager.Others;
|
|
||||||
using DiscordLibCommands = Discord.Commands;
|
|
||||||
using DiscordLib = Discord;
|
|
||||||
using OperatingSystem = PluginManager.Others.OperatingSystem;
|
|
||||||
|
|
||||||
namespace DiscordBot.Discord.Commands;
|
|
||||||
|
|
||||||
internal class Restart : DBCommand
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Command name
|
|
||||||
/// </summary>
|
|
||||||
public string Command => "restart";
|
|
||||||
|
|
||||||
public List<string> Aliases => null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Command Description
|
|
||||||
/// </summary>
|
|
||||||
public string Description => "Restart the bot";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Command usage
|
|
||||||
/// </summary>
|
|
||||||
public string Usage => "restart [-p | -c | -args | -cmd] <args>";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if the command require administrator to be executed
|
|
||||||
/// </summary>
|
|
||||||
public bool requireAdmin => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The main body of the command
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">The command context</param>
|
|
||||||
public async void ExecuteServer(DiscordLibCommands.SocketCommandContext context)
|
|
||||||
{
|
|
||||||
var args = Functions.GetArguments(context.Message);
|
|
||||||
var OS = Functions.GetOperatingSystem();
|
|
||||||
if (args.Count == 0)
|
|
||||||
{
|
|
||||||
switch (OS)
|
|
||||||
{
|
|
||||||
case OperatingSystem.WINDOWS:
|
|
||||||
Process.Start("./DiscordBot.exe");
|
|
||||||
break;
|
|
||||||
case OperatingSystem.LINUX:
|
|
||||||
case OperatingSystem.MAC_OS:
|
|
||||||
Process.Start("./DiscordBot");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (args[0])
|
|
||||||
{
|
|
||||||
case "-p":
|
|
||||||
case "-poweroff":
|
|
||||||
case "-c":
|
|
||||||
case "-close":
|
|
||||||
Environment.Exit(0);
|
|
||||||
break;
|
|
||||||
case "-cmd":
|
|
||||||
case "-args":
|
|
||||||
var cmd = "--args";
|
|
||||||
|
|
||||||
if (args.Count > 1)
|
|
||||||
for (var i = 1; i < args.Count; i++)
|
|
||||||
cmd += $" {args[i]}";
|
|
||||||
|
|
||||||
|
|
||||||
switch (OS)
|
|
||||||
{
|
|
||||||
case OperatingSystem.WINDOWS:
|
|
||||||
Functions.WriteLogFile("Restarting the bot with the following arguments: \"" + cmd + "\"");
|
|
||||||
Process.Start("./DiscordBot.exe", cmd);
|
|
||||||
break;
|
|
||||||
case OperatingSystem.LINUX:
|
|
||||||
//case PluginManager.Others.OperatingSystem.MAC_OS: ?? - not tested
|
|
||||||
Process.Start("./DiscordBot", cmd);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Environment.Exit(0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
await context.Channel.SendMessageAsync("Invalid argument. Use `help restart` to see the usage.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
|
||||||
<Nullable>disable</Nullable>
|
|
||||||
<ApplicationIcon />
|
|
||||||
<StartupObject />
|
|
||||||
<SignAssembly>False</SignAssembly>
|
|
||||||
<IsPublishable>True</IsPublishable>
|
|
||||||
<AssemblyVersion>1.0.1.0</AssemblyVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<DebugType>none</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="Data\**" />
|
|
||||||
<Compile Remove="obj\**" />
|
|
||||||
<Compile Remove="Output\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Remove="Data\**" />
|
|
||||||
<EmbeddedResource Remove="obj\**" />
|
|
||||||
<EmbeddedResource Remove="Output\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<None Remove="Data\**" />
|
|
||||||
<None Remove="obj\**" />
|
|
||||||
<None Remove="Output\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Discord.Net" Version="3.7.2" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
|
||||||
<Exec Command="xcopy /B /Y "$(TargetDir)*.dll" "$(TargetDir)Libraries"" />
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
@@ -8,41 +7,33 @@
|
|||||||
<StartupObject />
|
<StartupObject />
|
||||||
<SignAssembly>False</SignAssembly>
|
<SignAssembly>False</SignAssembly>
|
||||||
<IsPublishable>True</IsPublishable>
|
<IsPublishable>True</IsPublishable>
|
||||||
<AssemblyVersion>1.0.1.0</AssemblyVersion>
|
<AssemblyVersion>1.0.2.1</AssemblyVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="Data\**" />
|
<Compile Remove="Data\**" />
|
||||||
<Compile Remove="obj\**" />
|
<Compile Remove="obj\**" />
|
||||||
<Compile Remove="Output\**" />
|
<Compile Remove="Output\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Remove="Data\**" />
|
<EmbeddedResource Remove="Data\**" />
|
||||||
<EmbeddedResource Remove="obj\**" />
|
<EmbeddedResource Remove="obj\**" />
|
||||||
<EmbeddedResource Remove="Output\**" />
|
<EmbeddedResource Remove="Output\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Data\**" />
|
<None Remove="Data\**" />
|
||||||
<None Remove="obj\**" />
|
<None Remove="obj\**" />
|
||||||
<None Remove="Output\**" />
|
<None Remove="Output\**" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="3.7.2" />
|
<PackageReference Include="Discord.Net" Version="3.9.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
|
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
using System;
|
using PluginManager.Others;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace DiscordBot
|
namespace DiscordBot
|
||||||
{
|
{
|
||||||
|
|
||||||
public class Entry
|
public class Entry
|
||||||
{
|
{
|
||||||
[STAThread]
|
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
AppDomain currentDomain = AppDomain.CurrentDomain;
|
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||||
|
|||||||
117
DiscordBot/Installer.cs
Normal file
117
DiscordBot/Installer.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PluginManager;
|
||||||
|
using PluginManager.Others;
|
||||||
|
using PluginManager.Online;
|
||||||
|
|
||||||
|
namespace DiscordBot
|
||||||
|
{
|
||||||
|
public static class Installer
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void GenerateStartupConfig()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Welcome to the SethBot installer !");
|
||||||
|
Console.WriteLine("First, we need to configure the bot. Don't worry, it will be quick !");
|
||||||
|
Console.WriteLine("The following information will be stored in the config.json file in the ./Data/Resources folder. You can change it later from there.");
|
||||||
|
Console.WriteLine("The bot tokn is required to run the bot. You can get it from the Discord Developer Portal. (https://discord.com/developers/applications)");
|
||||||
|
Console.WriteLine("Please enter the bot token :");
|
||||||
|
var token = Console.ReadLine();
|
||||||
|
|
||||||
|
Console.WriteLine("Please enter the bot prefix :");
|
||||||
|
var prefix = Console.ReadLine();
|
||||||
|
|
||||||
|
Console.WriteLine("Please enter the Server ID :");
|
||||||
|
var serverId = Console.ReadLine();
|
||||||
|
|
||||||
|
Config.Data.Add("token", token);
|
||||||
|
Config.Data.Add("prefix", prefix);
|
||||||
|
Config.Data.Add("ServerID", serverId);
|
||||||
|
|
||||||
|
Config.Logger.Log("Config Saved", "Installer", LogLevel.INFO);
|
||||||
|
|
||||||
|
Config.Data.Save();
|
||||||
|
|
||||||
|
Console.WriteLine("Config saved !");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task SetupPluginDatabase()
|
||||||
|
{
|
||||||
|
Console.WriteLine("The plugin database is required to run the bot but there is nothing configured yet.");
|
||||||
|
Console.WriteLine("Please select one option : ");
|
||||||
|
Console.WriteLine("1. Download the official database file");
|
||||||
|
Console.WriteLine("2. Create a new (CUSTOM) database file");
|
||||||
|
int choice = 0;
|
||||||
|
Console.Write("Choice : ");
|
||||||
|
choice = int.Parse(Console.ReadLine());
|
||||||
|
if (choice != 1 && choice != 2)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid choice !");
|
||||||
|
Console.WriteLine("Please restart the installer !");
|
||||||
|
Console.ReadKey();
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (choice == 1)
|
||||||
|
await DownloadPluginDatabase();
|
||||||
|
|
||||||
|
if (choice == 2)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Do you have a url to a valid database file ? (y/n)");
|
||||||
|
var answer = Console.ReadLine();
|
||||||
|
if (answer == "y")
|
||||||
|
{
|
||||||
|
Console.WriteLine("Please enter the url :");
|
||||||
|
var url = Console.ReadLine();
|
||||||
|
await DownloadPluginDatabase(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Do you want to create a new database file ? (y/n)");
|
||||||
|
answer = Console.ReadLine();
|
||||||
|
if (answer == "y")
|
||||||
|
{
|
||||||
|
Console.WriteLine("A new file will be generated at ./Data/Resources/URLs.json");
|
||||||
|
System.Console.WriteLine("Please edit the file and restart the bot !");
|
||||||
|
Directory.CreateDirectory("./Data/Resources");
|
||||||
|
await File.WriteAllTextAsync("./Data/Resources/URLs.json",
|
||||||
|
@"
|
||||||
|
{
|
||||||
|
""PluginList"": """",
|
||||||
|
""PluginVersions"": """",
|
||||||
|
""StartupMessage"": """",
|
||||||
|
""SetupKeys"": """",
|
||||||
|
""Versions"": """",
|
||||||
|
""Changelog"": """",
|
||||||
|
""LinuxBot"": """",
|
||||||
|
""WindowsLauncher"": """",
|
||||||
|
}
|
||||||
|
".Replace(" ", ""));
|
||||||
|
Environment.Exit(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task DownloadPluginDatabase(string url = "https://raw.githubusercontent.com/Wizzy69/SethDiscordBot/gh-pages/defaultURLs.json")
|
||||||
|
{
|
||||||
|
string path = "./Data/Resources/URLs.json";
|
||||||
|
|
||||||
|
Directory.CreateDirectory("./Data/Resources");
|
||||||
|
Utilities.Utilities.ProgressBar bar = new Utilities.Utilities.ProgressBar(Utilities.ProgressBarType.NORMAL){
|
||||||
|
Max = 100,
|
||||||
|
Color = ConsoleColor.Green,
|
||||||
|
NoColor = true
|
||||||
|
};
|
||||||
|
IProgress<float> downloadProgress = new Progress<float>(p => bar.Update(p));
|
||||||
|
await ServerCom.DownloadFileAsync(url, path, downloadProgress, null);
|
||||||
|
bar.Update(bar.Max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Linq;
|
||||||
using DiscordBot.Discord.Core;
|
|
||||||
|
|
||||||
using PluginManager;
|
using PluginManager;
|
||||||
using PluginManager.Database;
|
using PluginManager.Bot;
|
||||||
using PluginManager.Items;
|
|
||||||
using PluginManager.Online;
|
using PluginManager.Online;
|
||||||
using PluginManager.Online.Helpers;
|
using PluginManager.Online.Helpers;
|
||||||
using PluginManager.Others;
|
using PluginManager.Others;
|
||||||
|
|
||||||
using Terminal.Gui;
|
using DiscordBot.Utilities;
|
||||||
|
using Microsoft.VisualBasic.CompilerServices;
|
||||||
using OperatingSystem = PluginManager.Others.OperatingSystem;
|
using OperatingSystem = PluginManager.Others.OperatingSystem;
|
||||||
|
using static PluginManager.Config;
|
||||||
|
|
||||||
namespace DiscordBot;
|
namespace DiscordBot;
|
||||||
|
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
private static bool loadPluginsOnStartup;
|
public static Json<string, string> URLs;
|
||||||
private static bool listPluginsAtStartup;
|
private static bool loadPluginsOnStartup = false;
|
||||||
private static ConsoleCommandsHandler consoleCommandsHandler;
|
private static ConsoleCommandsHandler consoleCommandsHandler;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -32,160 +32,19 @@ public class Program
|
|||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Startup(string[] args)
|
public static void Startup(string[] args)
|
||||||
{
|
{
|
||||||
|
PreLoadComponents(args).Wait();
|
||||||
|
|
||||||
PreLoadComponents().Wait();
|
if (!Config.Data.ContainsKey("ServerID") || !Config.Data.ContainsKey("token") ||
|
||||||
|
Config.Data["token"] == null ||
|
||||||
if (!Config.Variables.Exists("ServerID") || !Config.Variables.Exists("token") ||
|
(Config.Data["token"]?.Length != 70 && Config.Data["token"]?.Length != 59) ||
|
||||||
Config.Variables.GetValue("token") == null ||
|
!Config.Data.ContainsKey("prefix") || Config.Data["prefix"] == null ||
|
||||||
(Config.Variables.GetValue("token")?.Length != 70 && Config.Variables.GetValue("token")?.Length != 59) ||
|
Config.Data["prefix"]?.Length != 1 ||
|
||||||
!Config.Variables.Exists("prefix") || Config.Variables.GetValue("prefix") == null ||
|
|
||||||
Config.Variables.GetValue("prefix")?.Length != 1 ||
|
|
||||||
(args.Length == 1 && args[0] == "/reset"))
|
(args.Length == 1 && args[0] == "/reset"))
|
||||||
{
|
{
|
||||||
Application.Init();
|
Installer.GenerateStartupConfig();
|
||||||
var top = Application.Top;
|
|
||||||
var win = new Window("Discord Bot Config - " + Assembly.GetExecutingAssembly().GetName().Version)
|
|
||||||
{
|
|
||||||
X = 0,
|
|
||||||
Y = 1,
|
|
||||||
Width = Dim.Fill(),
|
|
||||||
Height = Dim.Fill()
|
|
||||||
};
|
|
||||||
|
|
||||||
top.Add(win);
|
|
||||||
|
|
||||||
var labelInfo = new Label(
|
|
||||||
"Configuration file not found or invalid. " +
|
|
||||||
"Please fill the following fields to create a new configuration file."
|
|
||||||
)
|
|
||||||
{
|
|
||||||
X = Pos.Center(),
|
|
||||||
Y = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
var labelToken = new Label("Please insert your token here: ")
|
|
||||||
{
|
|
||||||
X = 5,
|
|
||||||
Y = 5
|
|
||||||
};
|
|
||||||
|
|
||||||
var textFiledToken = new TextField("")
|
|
||||||
{
|
|
||||||
X = Pos.Left(labelToken) + labelToken.Text.Length + 2,
|
|
||||||
Y = labelToken.Y,
|
|
||||||
Width = 70
|
|
||||||
};
|
|
||||||
|
|
||||||
var labelPrefix = new Label("Please insert your prefix here: ")
|
|
||||||
{
|
|
||||||
X = 5,
|
|
||||||
Y = 8
|
|
||||||
};
|
|
||||||
var textFiledPrefix = new TextField("")
|
|
||||||
{
|
|
||||||
X = Pos.Left(labelPrefix) + labelPrefix.Text.Length + 2,
|
|
||||||
Y = labelPrefix.Y,
|
|
||||||
Width = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
var labelServerid = new Label("Please insert your server id here (optional): ")
|
|
||||||
{
|
|
||||||
X = 5,
|
|
||||||
Y = 11
|
|
||||||
};
|
|
||||||
var textFiledServerID = new TextField("")
|
|
||||||
{
|
|
||||||
X = Pos.Left(labelServerid) + labelServerid.Text.Length + 2,
|
|
||||||
Y = labelServerid.Y,
|
|
||||||
Width = 18
|
|
||||||
};
|
|
||||||
|
|
||||||
var button = new Button("Submit")
|
|
||||||
{
|
|
||||||
X = Pos.Center() - 10,
|
|
||||||
Y = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
var button2 = new Button("License")
|
|
||||||
{
|
|
||||||
X = Pos.Center() + 10,
|
|
||||||
Y = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
var button3 = new Button("ⓘ")
|
|
||||||
{
|
|
||||||
X = Pos.Left(textFiledServerID) + 20,
|
|
||||||
Y = textFiledServerID.Y
|
|
||||||
};
|
|
||||||
|
|
||||||
Console.CancelKeyPress += (sender, e) => { top.Running = false; };
|
|
||||||
|
|
||||||
button.Clicked += () =>
|
|
||||||
{
|
|
||||||
var passMessage = "";
|
|
||||||
if (textFiledToken.Text.Length != 70 && textFiledToken.Text.Length != 59)
|
|
||||||
passMessage += "Invalid token, ";
|
|
||||||
if (textFiledPrefix.Text.ContainsAny("0123456789/\\ ") || textFiledPrefix.Text.Length != 1)
|
|
||||||
passMessage += "Invalid prefix, ";
|
|
||||||
if (textFiledServerID.Text.Length != 18 && textFiledServerID.Text.Length > 0)
|
|
||||||
passMessage += "Invalid serverID";
|
|
||||||
|
|
||||||
if (passMessage != "")
|
|
||||||
{
|
|
||||||
MessageBox.ErrorQuery("Discord Bot Settings",
|
|
||||||
"Failed to pass check. Invalid information given:\n" + passMessage, "Retry");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HandleInput(args.ToList()).Wait();
|
||||||
Config.Variables.Add("ServerID", (string)textFiledServerID.Text, true);
|
|
||||||
Config.Variables.Add("token", (string)textFiledToken.Text, true);
|
|
||||||
Config.Variables.Add("prefix", (string)textFiledPrefix.Text, true);
|
|
||||||
|
|
||||||
MessageBox.Query("Discord Bot Settings", "Successfully saved config !\nJust start the bot :D",
|
|
||||||
"Start :D");
|
|
||||||
top.Running = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
button2.Clicked += async () =>
|
|
||||||
{
|
|
||||||
var license =
|
|
||||||
await ServerCom.ReadTextFromURL(
|
|
||||||
"https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/LICENSE.txt");
|
|
||||||
var ProductLicense =
|
|
||||||
"Seth Discord Bot\n\nDeveloped by Wizzy#9181\nThis application can be used and modified by anyone. Plugin development for this application is also free and supported";
|
|
||||||
var r = MessageBox.Query("Discord Bot Settings", ProductLicense, "Close", "Read about libraries used");
|
|
||||||
if (r == 1)
|
|
||||||
{
|
|
||||||
var i = 0;
|
|
||||||
while (i < license.Count)
|
|
||||||
{
|
|
||||||
var print_message = license[i++] + "\n";
|
|
||||||
for (; i < license.Count && !license[i].StartsWith("-----------"); i++)
|
|
||||||
print_message += license[i] + "\n";
|
|
||||||
if (print_message.Contains("https://"))
|
|
||||||
print_message += "\n\nCTRL + Click on a link to open it";
|
|
||||||
if (MessageBox.Query("Licenses", print_message, "Next", "Quit") == 1) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
button3.Clicked += () =>
|
|
||||||
{
|
|
||||||
MessageBox.Query("Discord Bot Settings",
|
|
||||||
"Server ID can be found in Server settings => Widget => Server ID",
|
|
||||||
"Close");
|
|
||||||
};
|
|
||||||
|
|
||||||
win.Add(labelInfo, labelPrefix, labelServerid, labelToken);
|
|
||||||
win.Add(textFiledToken, textFiledPrefix, textFiledServerID, button3);
|
|
||||||
win.Add(button, button2);
|
|
||||||
Application.Run();
|
|
||||||
Application.Shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleInput(args).Wait();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -194,12 +53,11 @@ public class Program
|
|||||||
private static void NoGUI()
|
private static void NoGUI()
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Settings.Variables.outputStream.WriteLine();
|
Console.WriteLine("Debug mode enabled");
|
||||||
ConsoleCommandsHandler.ExecuteCommad("lp").Wait();
|
|
||||||
#else
|
|
||||||
if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp");
|
|
||||||
if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs");
|
|
||||||
#endif
|
#endif
|
||||||
|
if (loadPluginsOnStartup)
|
||||||
|
consoleCommandsHandler.HandleCommand("lp");
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@@ -210,7 +68,7 @@ public class Program
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
) && cmd.Length > 0)
|
) && cmd.Length > 0)
|
||||||
Settings.Variables.outputStream.WriteLine("Failed to run command " + cmd);
|
Console.WriteLine("Failed to run command " + cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,49 +82,46 @@ public class Program
|
|||||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||||
|
|
||||||
var startupMessageList =
|
var startupMessageList =
|
||||||
await ServerCom.ReadTextFromURL(
|
await ServerCom.ReadTextFromURL(URLs["StartupMessage"]);
|
||||||
"https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/StartupMessage");
|
|
||||||
|
|
||||||
foreach (var message in startupMessageList)
|
foreach (var message in startupMessageList)
|
||||||
Settings.Variables.outputStream.WriteLine(message);
|
Console.WriteLine(message);
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine(
|
Console.WriteLine(
|
||||||
$"Running on version: {Assembly.GetExecutingAssembly().GetName().Version}");
|
$"Running on version: {Assembly.GetExecutingAssembly().GetName().Version}");
|
||||||
Settings.Variables.outputStream.WriteLine($"Git URL: {Settings.Variables.WebsiteURL}");
|
Console.WriteLine($"Git URL: {Config.Data["GitURL"]}");
|
||||||
|
|
||||||
Utilities.WriteColorText(
|
Utilities.Utilities.WriteColorText(
|
||||||
"&rRemember to close the bot using the ShutDown command (&ysd&r) or some settings won't be saved\n");
|
"&rRemember to close the bot using the ShutDown command (&ysd&r) or some settings won't be saved\n");
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
|
||||||
if (Config.Variables.Exists("LaunchMessage"))
|
if (Config.Data.ContainsKey("LaunchMessage"))
|
||||||
Utilities.WriteColorText(Config.Variables.GetValue("LaunchMessage"));
|
Utilities.Utilities.WriteColorText(Config.Data["LaunchMessage"]);
|
||||||
|
|
||||||
|
|
||||||
Utilities.WriteColorText(
|
Utilities.Utilities.WriteColorText(
|
||||||
"Please note that the bot saves a backup save file every time you are using the shudown command (&ysd&c)");
|
"Please note that the bot saves a backup save file every time you are using the shudown command (&ysd&c)");
|
||||||
Settings.Variables.outputStream.WriteLine("============================ LOG ============================");
|
|
||||||
|
Console.WriteLine("Running on " + Functions.GetOperatingSystem().ToString());
|
||||||
|
Console.WriteLine("============================ LOG ============================");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string token = "";
|
string token = "";
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
if (File.Exists("./Data/Resources/token.txt")) token = File.ReadAllText("./Data/Resources/token.txt");
|
||||||
if (await Settings.sqlDatabase.TableExistsAsync("BetaTest"))
|
else token = Config.Data["token"];
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine("Starting in DEBUG MODE");
|
|
||||||
token = await Settings.sqlDatabase.GetValueAsync("BetaTest", "VariableName", "Token", "Value");
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
token = Config.Variables.GetValue("token");
|
token = Config.Data["token"];
|
||||||
#endif
|
#endif
|
||||||
var prefix = Config.Variables.GetValue("prefix");
|
var prefix = Config.Data["prefix"];
|
||||||
var discordbooter = new Boot(token, prefix);
|
var discordbooter = new Boot(token, prefix);
|
||||||
await discordbooter.Awake();
|
await discordbooter.Awake();
|
||||||
return discordbooter;
|
return discordbooter;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.WriteLine(ex);
|
Config.Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,76 +130,65 @@ public class Program
|
|||||||
/// Handle user input arguments from the startup of the application
|
/// Handle user input arguments from the startup of the application
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="args">The arguments</param>
|
/// <param name="args">The arguments</param>
|
||||||
private static async Task HandleInput(string[] args)
|
private static async Task HandleInput(List<string> args)
|
||||||
{
|
{
|
||||||
var len = args.Length;
|
|
||||||
|
Console.WriteLine("Loading Core ...");
|
||||||
|
|
||||||
var b = await StartNoGui();
|
var b = await StartNoGui();
|
||||||
consoleCommandsHandler = new ConsoleCommandsHandler(b.client);
|
consoleCommandsHandler = new ConsoleCommandsHandler(b.client);
|
||||||
|
|
||||||
if (len > 0 && args[0] == "/remplug")
|
|
||||||
{
|
|
||||||
var plugName = string.Join(' ', args, 1, args.Length - 1);
|
|
||||||
Settings.Variables.outputStream.WriteLine("Starting to remove " + plugName);
|
|
||||||
await ConsoleCommandsHandler.ExecuteCommad("remplug " + plugName);
|
|
||||||
loadPluginsOnStartup = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0 && args[0] == "/lp")
|
|
||||||
loadPluginsOnStartup = true;
|
|
||||||
|
|
||||||
var mainThread = new Thread(() =>
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if(args.Contains("--gui"))
|
||||||
|
{
|
||||||
|
// GUI not implemented yet
|
||||||
|
Console.WriteLine("GUI not implemented yet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
NoGUI();
|
NoGUI();
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9)
|
if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9)
|
||||||
{
|
{
|
||||||
if (Config.Variables.Exists("LaunchMessage"))
|
if (Config.Data.ContainsKey("LaunchMessage"))
|
||||||
Config.Variables.Add("LaunchMessage",
|
Config.Data.Add("LaunchMessage",
|
||||||
"An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !",
|
"An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !");
|
||||||
false);
|
Config.Logger.Log("An error occured while closing the bot last time. Please consider closing the bot using the &rsd&c method !\nThere is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", "Bot", LogLevel.ERROR);
|
||||||
Functions.WriteErrFile(ex.ToString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
return;
|
||||||
mainThread.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task PreLoadComponents()
|
private static async Task PreLoadComponents(string[] args)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream = Console.Out;
|
|
||||||
Settings.Variables.outputStream.WriteLine("Loading resources ...");
|
|
||||||
var main = new Utilities.ProgressBar(ProgressBarType.NO_END);
|
|
||||||
main.Start();
|
|
||||||
Directory.CreateDirectory("./Data/Resources");
|
|
||||||
Directory.CreateDirectory("./Data/Plugins");
|
|
||||||
Directory.CreateDirectory("./Data/PAKS");
|
|
||||||
|
|
||||||
Settings.sqlDatabase = new SqlDatabase(Functions.dataFolder + "SetDB.dat");
|
|
||||||
|
|
||||||
await Settings.sqlDatabase.Open();
|
|
||||||
await Config.Initialize();
|
await Config.Initialize();
|
||||||
|
|
||||||
|
if (!Directory.Exists("./Data/Resources") || !File.Exists("./Data/Resources/URLs.json"))
|
||||||
|
{
|
||||||
|
await Installer.SetupPluginDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (await Config.Variables.ExistsAsync("DeleteLogsAtStartup"))
|
URLs = new Json<string, string>("./Data/Resources/URLs.json");
|
||||||
if (await Config.Variables.GetValueAsync("DeleteLogsAtStartup") == "true")
|
|
||||||
|
Config.Logger.LogEvent += (message, type) => { Console.WriteLine(message); };
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine("Loading resources ...");
|
||||||
|
var main = new Utilities.Utilities.ProgressBar(ProgressBarType.NO_END);
|
||||||
|
main.Start();
|
||||||
|
|
||||||
|
if (Config.Data.ContainsKey("DeleteLogsAtStartup"))
|
||||||
|
if (Config.Data["DeleteLogsAtStartup"] == "true")
|
||||||
foreach (var file in Directory.GetFiles("./Output/Logs/"))
|
foreach (var file in Directory.GetFiles("./Output/Logs/"))
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
var OnlineDefaultKeys =
|
var OnlineDefaultKeys =
|
||||||
await ServerCom.ReadTextFromURL(
|
await ServerCom.ReadTextFromURL(URLs["SetupKeys"]);
|
||||||
"https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/SetupKeys");
|
|
||||||
|
|
||||||
|
|
||||||
if (!await Config.Variables.ExistsAsync("Version"))
|
Config.Data["Version"] = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||||
await Config.Variables.AddAsync("Version", Assembly.GetExecutingAssembly().GetName().Version.ToString(), false);
|
|
||||||
else
|
|
||||||
await Config.Variables.SetValueAsync("Version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
|
||||||
|
|
||||||
|
|
||||||
foreach (var key in OnlineDefaultKeys)
|
foreach (var key in OnlineDefaultKeys)
|
||||||
{
|
{
|
||||||
@@ -352,20 +196,16 @@ public class Program
|
|||||||
var s = key.Split(' ');
|
var s = key.Split(' ');
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (await Config.Variables.ExistsAsync(s[0])) await Config.Variables.SetValueAsync(s[0], s[1]);
|
Config.Data[s[0]] = s[1];
|
||||||
else
|
|
||||||
await Config.Variables.AddAsync(s[0], s[1], s[2].ToLower() == "true");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Functions.WriteErrFile(ex.Message);
|
Config.Logger.Log(ex.ToString(), "Bot", LogLevel.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var onlineSettingsList =
|
var onlineSettingsList = await ServerCom.ReadTextFromURL(URLs["Versions"]);
|
||||||
await ServerCom.ReadTextFromURL(
|
|
||||||
"https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/OnlineData");
|
|
||||||
main.Stop("Loaded online settings. Loading updates ...");
|
main.Stop("Loaded online settings. Loading updates ...");
|
||||||
foreach (var key in onlineSettingsList)
|
foreach (var key in onlineSettingsList)
|
||||||
{
|
{
|
||||||
@@ -376,66 +216,113 @@ public class Program
|
|||||||
{
|
{
|
||||||
case "CurrentVersion":
|
case "CurrentVersion":
|
||||||
var newVersion = s[1];
|
var newVersion = s[1];
|
||||||
if (!newVersion.Equals(await Config.Variables.GetValueAsync("Version")))
|
var currentVersion = Config.Data["Version"];
|
||||||
|
if (!newVersion.Equals(currentVersion))
|
||||||
{
|
{
|
||||||
var nVer = new VersionString(newVersion.Substring(2));
|
var nVer = new VersionString(newVersion.Substring(2));
|
||||||
var cVer = new VersionString((await Config.Variables.GetValueAsync("Version")).Substring(2));
|
var cVer = new VersionString((Config.Data["Version"]).Substring(2));
|
||||||
if (cVer > nVer)
|
if (cVer > nVer)
|
||||||
{
|
{
|
||||||
await Config.Variables.SetValueAsync("Version", "1." + cVer.ToShortString() + " (Beta)");
|
Config.Data["Version"] = "1." + cVer.ToShortString() + " (Beta)";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Functions.GetOperatingSystem() == OperatingSystem.WINDOWS)
|
if (OperatingSystem.WINDOWS == Functions.GetOperatingSystem())
|
||||||
{
|
{
|
||||||
var url =
|
Console.Clear();
|
||||||
$"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}/net6.0.zip";
|
Console.WriteLine("A new update was found !");
|
||||||
Process.Start(".\\Updater\\Updater.exe",
|
Console.WriteLine("Run the launcher to update");
|
||||||
$"{newVersion} {url} {Process.GetCurrentProcess().ProcessName}");
|
Console.WriteLine("Current version: " + currentVersion);
|
||||||
|
Console.WriteLine("Latest version: " + s[1]);
|
||||||
|
|
||||||
|
File.WriteAllText("version.txt", currentVersion);
|
||||||
|
|
||||||
|
await Task.Delay(3000);
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
Console.Clear();
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine("A new version of the bot is available !");
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.WriteLine("Current version : " +
|
||||||
|
Assembly.GetExecutingAssembly().GetName().Version.ToString());
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine("New version : " + newVersion);
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
|
||||||
|
File.WriteAllText("version.txt", newVersion);
|
||||||
|
|
||||||
|
Console.WriteLine("Changelog :");
|
||||||
|
|
||||||
|
List<string> changeLog = await ServerCom.ReadTextFromURL(URLs["Changelog"]);
|
||||||
|
foreach (var item in changeLog)
|
||||||
|
Utilities.Utilities.WriteColorText(item);
|
||||||
|
Console.WriteLine("Do you want to update the bot ? (y/n)");
|
||||||
|
if (Console.ReadKey().Key == ConsoleKey.Y)
|
||||||
{
|
{
|
||||||
var url =
|
var url = URLs["LinuxBot"].Replace("{0}", newVersion);
|
||||||
$"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}/net6.0_linux.zip";
|
Config.Logger.Log($"executing: download_file {url}");
|
||||||
Settings.Variables.outputStream.WriteLine("Downloading update ...");
|
|
||||||
await ServerCom.DownloadFileNoProgressAsync(url, "./update.zip");
|
await ServerCom.DownloadFileAsync(url, "./update.zip", new Progress<float>(percent => { Console.WriteLine($"\rProgress: {percent}% "); }));
|
||||||
await File.WriteAllTextAsync("Install.sh",
|
await File.WriteAllTextAsync("Install.sh",
|
||||||
"#!/bin/bash\nunzip -qq update.zip -d ./\nrm update.zip\nchmod +x SethDiscordBot\n./DiscordBot");
|
"#!/bin/bash\nunzip -qq -o update.zip \nrm update.zip\nchmod a+x DiscordBot");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("executing: chmod a+x Install.sh");
|
||||||
|
Process.Start("chmod", "a+x Install.sh").WaitForExit();
|
||||||
Process.Start("Install.sh").WaitForExit();
|
Process.Start("Install.sh").WaitForExit();
|
||||||
|
|
||||||
|
Console.WriteLine("executing: rm Install.sh");
|
||||||
|
Process.Start("rm", "Install.sh").WaitForExit();
|
||||||
|
|
||||||
|
Config.Logger.Log("The new version of the bot has been installed.");
|
||||||
|
Console.WriteLine("Please restart the bot.");
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Config.Logger.Log(ex.Message, "Updater", LogLevel.ERROR);
|
||||||
|
if (ex.Message.Contains("Access de"))
|
||||||
|
Config.Logger.Log("Please run the bot as root.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "UpdaterVersion":
|
case "LauncherVersion":
|
||||||
var updaternewversion = s[1];
|
var updaternewversion = s[1];
|
||||||
|
//File.WriteAllText(updaternewversion + ".txt", updaternewversion);
|
||||||
if (Functions.GetOperatingSystem() == OperatingSystem.LINUX)
|
if (Functions.GetOperatingSystem() == OperatingSystem.LINUX)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!await Config.Variables.ExistsAsync("UpdaterVersion"))
|
Directory.CreateDirectory(Functions.dataFolder + "Applications");
|
||||||
await Config.Variables.AddAsync("UpdaterVersion", "0.0.0.0", false);
|
if (!Config.Data.ContainsKey("LauncherVersion"))
|
||||||
if (await Config.Variables.GetValueAsync("UpdaterVersion") != updaternewversion ||
|
Config.Data["LauncherVersion"] = "0.0.0.0";
|
||||||
!Directory.Exists("./Updater") ||
|
if (Config.Data["LauncherVersion"] != updaternewversion ||
|
||||||
!File.Exists("./Updater/Updater.exe"))
|
!File.Exists("./Launcher.exe"))
|
||||||
{
|
{
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
Settings.Variables.outputStream.WriteLine("Installing updater ...\nDo NOT close the bot during update !");
|
Console.WriteLine("Installing a new Launcher ...\nDo NOT close the bot during update !");
|
||||||
var bar = new Utilities.ProgressBar(ProgressBarType.NO_END);
|
var bar = new Utilities.Utilities.ProgressBar(ProgressBarType.NO_END);
|
||||||
bar.Start();
|
bar.Start();
|
||||||
await ServerCom.DownloadFileNoProgressAsync(
|
await ServerCom.DownloadFileAsync(URLs["WindowsLauncher"], $"./Launcher.exe", null);
|
||||||
"https://github.com/Wizzy69/installer/releases/download/release-1-discordbot/Updater.zip",
|
//await ArchiveManager.ExtractArchive("./Updater.zip", "./", null,
|
||||||
"./Updater.zip");
|
// UnzipProgressType.PercentageFromTotalSize);
|
||||||
await Functions.ExtractArchive("./Updater.zip", "./", null,
|
Config.Data["LauncherVersion"] = updaternewversion;
|
||||||
UnzipProgressType.PercentageFromTotalSize);
|
// File.Delete("Updater.zip");
|
||||||
await Config.Variables.SetValueAsync("UpdaterVersion", updaternewversion);
|
bar.Stop("The launcher has been updated !");
|
||||||
File.Delete("Updater.zip");
|
|
||||||
bar.Stop("Updater has been updated !");
|
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
DiscordBot/Utilities/Command.cs
Normal file
14
DiscordBot/Utilities/Command.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Discord.Commands;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
namespace DiscordBot.Utilities;
|
||||||
|
|
||||||
|
public class ConsoleCommand
|
||||||
|
{
|
||||||
|
public string? CommandName { get; init; }
|
||||||
|
public string? Description { get; init; }
|
||||||
|
public string? Usage { get; init; }
|
||||||
|
public Action<string[]>? Action { get; init; }
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PluginManager.Others;
|
using PluginManager;
|
||||||
|
|
||||||
|
namespace DiscordBot.Utilities;
|
||||||
|
|
||||||
public static class Utilities
|
public static class Utilities
|
||||||
{
|
{
|
||||||
@@ -46,38 +49,38 @@ public static class Utilities
|
|||||||
foreach (var row in data)
|
foreach (var row in data)
|
||||||
{
|
{
|
||||||
if (row[0][0] == tableLine)
|
if (row[0][0] == tableLine)
|
||||||
Settings.Variables.outputStream.Write(tableCross);
|
Console.Write(tableCross);
|
||||||
else
|
else
|
||||||
Settings.Variables.outputStream.Write(tableWall);
|
Console.Write(tableWall);
|
||||||
for (var l = 0; l < row.Length; l++)
|
for (var l = 0; l < row.Length; l++)
|
||||||
{
|
{
|
||||||
if (row[l][0] == tableLine)
|
if (row[l][0] == tableLine)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < len[l] + 4; ++i)
|
for (var i = 0; i < len[l] + 4; ++i)
|
||||||
Settings.Variables.outputStream.Write(tableLine);
|
Console.Write(tableLine);
|
||||||
}
|
}
|
||||||
else if (row[l].Length == len[l])
|
else if (row[l].Length == len[l])
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write(row[l]);
|
Console.Write(row[l]);
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var lenHalf = row[l].Length / 2;
|
var lenHalf = row[l].Length / 2;
|
||||||
for (var i = 0; i < (len[l] + 4) / 2 - lenHalf; ++i)
|
for (var i = 0; i < (len[l] + 4) / 2 - lenHalf; ++i)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write(row[l]);
|
Console.Write(row[l]);
|
||||||
for (var i = (len[l] + 4) / 2 + lenHalf + 1; i < len[l] + 4; ++i)
|
for (var i = (len[l] + 4) / 2 + lenHalf + 1; i < len[l] + 4; ++i)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
if (row[l].Length % 2 == 0)
|
if (row[l].Length % 2 == 0)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.Variables.outputStream.Write(row[l][0] == tableLine ? tableCross : tableWall);
|
Console.Write(row[l][0] == tableLine ? tableCross : tableWall);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine(); //end line
|
Console.WriteLine(); //end line
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -95,44 +98,44 @@ public static class Utilities
|
|||||||
|
|
||||||
foreach (var row in data)
|
foreach (var row in data)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.Write("\t");
|
Console.Write("\t");
|
||||||
if (row[0] == "-")
|
if (row[0] == "-")
|
||||||
Settings.Variables.outputStream.Write("+");
|
Console.Write("+");
|
||||||
else
|
else
|
||||||
Settings.Variables.outputStream.Write("|");
|
Console.Write("|");
|
||||||
|
|
||||||
foreach (var s in row)
|
foreach (var s in row)
|
||||||
{
|
{
|
||||||
if (s == "-")
|
if (s == "-")
|
||||||
{
|
{
|
||||||
for (var i = 0; i < maxLen + 4; ++i)
|
for (var i = 0; i < maxLen + 4; ++i)
|
||||||
Settings.Variables.outputStream.Write("-");
|
Console.Write("-");
|
||||||
}
|
}
|
||||||
else if (s.Length == maxLen)
|
else if (s.Length == maxLen)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write(s);
|
Console.Write(s);
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var lenHalf = s.Length / 2;
|
var lenHalf = s.Length / 2;
|
||||||
for (var i = 0; i < div - lenHalf; ++i)
|
for (var i = 0; i < div - lenHalf; ++i)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write(s);
|
Console.Write(s);
|
||||||
for (var i = div + lenHalf + 1; i < maxLen + 4; ++i)
|
for (var i = div + lenHalf + 1; i < maxLen + 4; ++i)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
if (s.Length % 2 == 0)
|
if (s.Length % 2 == 0)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s == "-")
|
if (s == "-")
|
||||||
Settings.Variables.outputStream.Write("+");
|
Console.Write("+");
|
||||||
else
|
else
|
||||||
Settings.Variables.outputStream.Write("|");
|
Console.Write("|");
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine(); //end line
|
Console.WriteLine(); //end line
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -153,12 +156,12 @@ public static class Utilities
|
|||||||
{
|
{
|
||||||
if (data[i][j] == "-")
|
if (data[i][j] == "-")
|
||||||
data[i][j] = " ";
|
data[i][j] = " ";
|
||||||
Settings.Variables.outputStream.Write(data[i][j]);
|
Console.Write(data[i][j]);
|
||||||
for (var k = 0; k < widths[j] - data[i][j].Length + 1 + space_between_columns; k++)
|
for (var k = 0; k < widths[j] - data[i][j].Length + 1 + space_between_columns; k++)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -169,13 +172,6 @@ public static class Utilities
|
|||||||
|
|
||||||
public static void WriteColorText(string text, bool appendNewLineAtEnd = true)
|
public static void WriteColorText(string text, bool appendNewLineAtEnd = true)
|
||||||
{
|
{
|
||||||
if (Console.Out != Settings.Variables.outputStream)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.Write(text);
|
|
||||||
if (appendNewLineAtEnd)
|
|
||||||
Settings.Variables.outputStream.WriteLine();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var initialForeGround = Console.ForegroundColor;
|
var initialForeGround = Console.ForegroundColor;
|
||||||
var input = text.ToCharArray();
|
var input = text.ToCharArray();
|
||||||
for (var i = 0; i < input.Length; i++)
|
for (var i = 0; i < input.Length; i++)
|
||||||
@@ -197,12 +193,51 @@ public static class Utilities
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.Write(input[i]);
|
Console.Write(input[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.ForegroundColor = initialForeGround;
|
Console.ForegroundColor = initialForeGround;
|
||||||
if (appendNewLineAtEnd)
|
if (appendNewLineAtEnd)
|
||||||
Settings.Variables.outputStream.WriteLine();
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Spinner
|
||||||
|
{
|
||||||
|
private Thread thread;
|
||||||
|
private bool isRunning;
|
||||||
|
private readonly string[] Sequence;
|
||||||
|
private int position;
|
||||||
|
|
||||||
|
public Spinner()
|
||||||
|
{
|
||||||
|
Sequence = new[] {"|", "/", "-", "\\"};
|
||||||
|
position = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
Console.CursorVisible = false;
|
||||||
|
isRunning=true;
|
||||||
|
thread = new Thread(() => {
|
||||||
|
while (isRunning)
|
||||||
|
{
|
||||||
|
Console.Write("\r" + Sequence[position]);
|
||||||
|
position++;
|
||||||
|
if (position >= Sequence.Length)
|
||||||
|
position = 0;
|
||||||
|
Thread.Sleep(100);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
thread.Start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
isRunning=false;
|
||||||
|
Console.CursorVisible = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -219,8 +254,6 @@ public static class Utilities
|
|||||||
|
|
||||||
public ProgressBar(ProgressBarType type)
|
public ProgressBar(ProgressBarType type)
|
||||||
{
|
{
|
||||||
if (Settings.Variables.outputStream != Console.Out)
|
|
||||||
throw new Exception("This class (or function) can be used with console only. For UI please use another approach.");
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,6 +267,7 @@ public static class Utilities
|
|||||||
|
|
||||||
public async void Start()
|
public async void Start()
|
||||||
{
|
{
|
||||||
|
Console.WriteLine();
|
||||||
if (type != ProgressBarType.NO_END)
|
if (type != ProgressBarType.NO_END)
|
||||||
throw new Exception("Only NO_END progress bar can use this method");
|
throw new Exception("Only NO_END progress bar can use this method");
|
||||||
if (isRunning)
|
if (isRunning)
|
||||||
@@ -281,9 +315,9 @@ public static class Utilities
|
|||||||
{
|
{
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
for (var i = 0; i < BarLength + message.Length + 1; i++)
|
for (var i = 0; i < BarLength + message.Length + 1; i++)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Settings.Variables.outputStream.WriteLine(message);
|
Console.WriteLine(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,14 +332,14 @@ public static class Utilities
|
|||||||
private void UpdateNoEnd(string message)
|
private void UpdateNoEnd(string message)
|
||||||
{
|
{
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Settings.Variables.outputStream.Write("[");
|
Console.Write("[");
|
||||||
for (var i = 1; i <= position; i++)
|
for (var i = 1; i <= position; i++)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write("<==()==>");
|
Console.Write("<==()==>");
|
||||||
position += positive ? 1 : -1;
|
position += positive ? 1 : -1;
|
||||||
for (var i = position; i <= BarLength - 1 - (positive ? 0 : 2); i++)
|
for (var i = position; i <= BarLength - 1 - (positive ? 0 : 2); i++)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write("] " + message);
|
Console.Write("] " + message);
|
||||||
|
|
||||||
|
|
||||||
if (position == BarLength - 1 || position == 1)
|
if (position == BarLength - 1 || position == 1)
|
||||||
@@ -315,14 +349,14 @@ public static class Utilities
|
|||||||
private void UpdateNoEnd()
|
private void UpdateNoEnd()
|
||||||
{
|
{
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Settings.Variables.outputStream.Write("[");
|
Console.Write("[");
|
||||||
for (var i = 1; i <= position; i++)
|
for (var i = 1; i <= position; i++)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write("<==()==>");
|
Console.Write("<==()==>");
|
||||||
position += positive ? 1 : -1;
|
position += positive ? 1 : -1;
|
||||||
for (var i = position; i <= BarLength - 1 - (positive ? 0 : 2); i++)
|
for (var i = position; i <= BarLength - 1 - (positive ? 0 : 2); i++)
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
Settings.Variables.outputStream.Write("]");
|
Console.Write("]");
|
||||||
|
|
||||||
|
|
||||||
if (position == BarLength - 1 || position == 1)
|
if (position == BarLength - 1 || position == 1)
|
||||||
@@ -332,9 +366,9 @@ public static class Utilities
|
|||||||
private void UpdateNormal(float progress)
|
private void UpdateNormal(float progress)
|
||||||
{
|
{
|
||||||
Console.CursorLeft = 0;
|
Console.CursorLeft = 0;
|
||||||
Settings.Variables.outputStream.Write("[");
|
Console.Write("[");
|
||||||
Console.CursorLeft = BarLength;
|
Console.CursorLeft = BarLength;
|
||||||
Settings.Variables.outputStream.Write("]");
|
Console.Write("]");
|
||||||
Console.CursorLeft = 1;
|
Console.CursorLeft = 1;
|
||||||
var onechunk = 30.0f / Max;
|
var onechunk = 30.0f / Max;
|
||||||
|
|
||||||
@@ -344,22 +378,22 @@ public static class Utilities
|
|||||||
{
|
{
|
||||||
Console.BackgroundColor = NoColor ? ConsoleColor.Black : Color;
|
Console.BackgroundColor = NoColor ? ConsoleColor.Black : Color;
|
||||||
Console.CursorLeft = position++;
|
Console.CursorLeft = position++;
|
||||||
Settings.Variables.outputStream.Write("#");
|
Console.Write("#");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = position; i < BarLength; i++)
|
for (var i = position; i < BarLength; i++)
|
||||||
{
|
{
|
||||||
Console.BackgroundColor = NoColor ? ConsoleColor.Black : ConsoleColor.DarkGray;
|
Console.BackgroundColor = NoColor ? ConsoleColor.Black : ConsoleColor.DarkGray;
|
||||||
Console.CursorLeft = position++;
|
Console.CursorLeft = position++;
|
||||||
Settings.Variables.outputStream.Write(" ");
|
Console.Write(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.CursorLeft = BarLength + 4;
|
Console.CursorLeft = BarLength + 4;
|
||||||
Console.BackgroundColor = ConsoleColor.Black;
|
Console.BackgroundColor = ConsoleColor.Black;
|
||||||
if (progress.CanAproximateTo(Max))
|
if (progress.CanAproximateTo(Max))
|
||||||
Settings.Variables.outputStream.Write(progress + " % ✓");
|
Console.Write(progress + " % ✓");
|
||||||
else
|
else
|
||||||
Settings.Variables.outputStream.Write(MathF.Round(progress, 2) + " % ");
|
Console.Write(MathF.Round(progress, 2) + " % ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
439
DiscordBot/Utilities/ConsoleCommandsHandler.cs
Normal file
439
DiscordBot/Utilities/ConsoleCommandsHandler.cs
Normal file
@@ -0,0 +1,439 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
using PluginManager;
|
||||||
|
using PluginManager.Loaders;
|
||||||
|
using PluginManager.Online;
|
||||||
|
using PluginManager.Others;
|
||||||
|
|
||||||
|
using OperatingSystem = PluginManager.Others.OperatingSystem;
|
||||||
|
|
||||||
|
namespace DiscordBot.Utilities;
|
||||||
|
|
||||||
|
public class ConsoleCommandsHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
public static ConsoleCommandsHandler handler;
|
||||||
|
private readonly PluginsManager manager;
|
||||||
|
|
||||||
|
private readonly List<ConsoleCommand> commandList = new();
|
||||||
|
|
||||||
|
|
||||||
|
private bool isDownloading;
|
||||||
|
private bool pluginsLoaded;
|
||||||
|
private DiscordSocketClient client;
|
||||||
|
|
||||||
|
public ConsoleCommandsHandler(DiscordSocketClient client)
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
manager = new PluginsManager(Program.URLs["PluginList"], Program.URLs["PluginVersions"]);
|
||||||
|
InitializeBasicCommands();
|
||||||
|
Console.WriteLine("Done");
|
||||||
|
|
||||||
|
if (handler == null)
|
||||||
|
handler = this;
|
||||||
|
else
|
||||||
|
throw new Exception("ConsoleCommandsHandler already initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeBasicCommands()
|
||||||
|
{
|
||||||
|
commandList.Clear();
|
||||||
|
|
||||||
|
AddCommand("help", "Show help", "help <command>", args =>
|
||||||
|
{
|
||||||
|
if (args.Length <= 1)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Available commands:");
|
||||||
|
var items = new List<string[]>
|
||||||
|
{
|
||||||
|
new[] { "-", "-", "-" },
|
||||||
|
new[] { "Command", "Description", "Usage" },
|
||||||
|
new[] { " ", " ", "Argument type: <optional> [required]" },
|
||||||
|
new[] { "-", "-", "-" }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var command in commandList)
|
||||||
|
{
|
||||||
|
if (!command.CommandName.StartsWith("_"))
|
||||||
|
items.Add(new[] { command.CommandName, command.Description, command.Usage });
|
||||||
|
}
|
||||||
|
|
||||||
|
items.Add(new[] { "-", "-", "-" });
|
||||||
|
Utilities.FormatAndAlignTable(items, TableFormat.DEFAULT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var command in commandList)
|
||||||
|
if (command.CommandName == args[1])
|
||||||
|
{
|
||||||
|
Console.WriteLine("Command description: " + command.Description);
|
||||||
|
Console.WriteLine("Command execution format:" + command.Usage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Command not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AddCommand("lp", "Load plugins", () =>
|
||||||
|
{
|
||||||
|
if (pluginsLoaded)
|
||||||
|
return;
|
||||||
|
var loader = new PluginLoader(client!);
|
||||||
|
var cc = Console.ForegroundColor;
|
||||||
|
loader.onCMDLoad += (name, typeName, success, exception) =>
|
||||||
|
{
|
||||||
|
if (name == null || name.Length < 2)
|
||||||
|
name = typeName;
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine("[CMD] Successfully loaded command : " + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
if (exception is null)
|
||||||
|
Console.WriteLine("An error occured while loading: " + name);
|
||||||
|
else
|
||||||
|
Console.WriteLine("[CMD] Failed to load command : " + name + " because " + exception!.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
};
|
||||||
|
loader.onEVELoad += (name, typeName, success, exception) =>
|
||||||
|
{
|
||||||
|
if (name == null || name.Length < 2)
|
||||||
|
name = typeName;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine("[EVENT] Successfully loaded event : " + name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception!.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
};
|
||||||
|
|
||||||
|
loader.onSLSHLoad += (name, typeName, success, exception) =>
|
||||||
|
{
|
||||||
|
if (name == null || name.Length < 2)
|
||||||
|
name = typeName;
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine("[SLASH] Successfully loaded command : " + name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine("[SLASH] Failed to load command : " + name + " because " + exception!.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
};
|
||||||
|
|
||||||
|
loader.LoadPlugins();
|
||||||
|
Console.ForegroundColor = cc;
|
||||||
|
pluginsLoaded = true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AddCommand("listplugs", "list available plugins", async () => {
|
||||||
|
if(manager == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Plugin manager is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var data = await manager.GetAvailablePlugins();
|
||||||
|
var items = new List<string[]>
|
||||||
|
{
|
||||||
|
new[] { "-", "-", "-", "-" },
|
||||||
|
new[] { "Name", "Type", "Description", "Required" },
|
||||||
|
new[] { "-", "-", "-", "-" }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var plugin in data)
|
||||||
|
{
|
||||||
|
items.Add(new[] { plugin[0], plugin[1], plugin[2], plugin[3] });
|
||||||
|
}
|
||||||
|
|
||||||
|
items.Add(new[] { "-", "-", "-", "-" });
|
||||||
|
Utilities.FormatAndAlignTable(items, TableFormat.DEFAULT);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddCommand("dwplug", "download plugin", "dwplug [name]", async args =>
|
||||||
|
{
|
||||||
|
isDownloading = true;
|
||||||
|
Utilities.Spinner spinner = new Utilities.Spinner();
|
||||||
|
if (args.Length == 1)
|
||||||
|
{
|
||||||
|
isDownloading = false;
|
||||||
|
Console.WriteLine("Please specify plugin name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = string.Join(' ', args, 1, args.Length - 1);
|
||||||
|
// info[0] = plugin type
|
||||||
|
// info[1] = plugin link
|
||||||
|
// info[2] = if others are required, or string.Empty if none
|
||||||
|
var info = await manager.GetPluginLinkByName(name);
|
||||||
|
if (info[1] == null) // link is null
|
||||||
|
{
|
||||||
|
if (name == "")
|
||||||
|
{
|
||||||
|
isDownloading = false;
|
||||||
|
Utilities.WriteColorText("Name is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isDownloading = false;
|
||||||
|
Utilities.WriteColorText($"Failed to find plugin &b{name} &c!" +
|
||||||
|
" Use &glistplugs &ccommand to display all available plugins !");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
spinner.Start();
|
||||||
|
|
||||||
|
string path;
|
||||||
|
if (info[0] == "Plugin")
|
||||||
|
path = "./Data/Plugins/" + name + ".dll";
|
||||||
|
else
|
||||||
|
path = $"./{info[1].Split('/')[info[1].Split('/').Length - 1]}";
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine($"Downloading plugin {name} from {info[1]} to {path}");
|
||||||
|
await ServerCom.DownloadFileAsync(info[1], path, null);
|
||||||
|
|
||||||
|
Console.WriteLine("\n");
|
||||||
|
|
||||||
|
// check requirements if any
|
||||||
|
|
||||||
|
if (info.Length == 3 && info[2] != string.Empty && info[2] != null)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Downloading requirements for plugin : {name}");
|
||||||
|
|
||||||
|
var lines = await ServerCom.ReadTextFromURL(info[2]);
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
if (!(line.Length > 0 && line.Contains(",")))
|
||||||
|
continue;
|
||||||
|
var split = line.Split(',');
|
||||||
|
Console.WriteLine($"\nDownloading item: {split[1]}");
|
||||||
|
if (File.Exists("./" + split[1])) File.Delete("./" + split[1]);
|
||||||
|
await ServerCom.DownloadFileAsync(split[0], "./" + split[1], null);
|
||||||
|
|
||||||
|
Console.WriteLine("Item " + split[1] + " downloaded !");
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
if (split[0].EndsWith(".pak"))
|
||||||
|
{
|
||||||
|
File.Move("./" + split[1], "./Data/PAKS/" + split[1], true);
|
||||||
|
}
|
||||||
|
else if (split[0].EndsWith(".zip") || split[0].EndsWith(".pkg"))
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Extracting {split[1]} ...");
|
||||||
|
await ArchiveManager.ExtractArchive("./" + split[1], "./", null,
|
||||||
|
UnzipProgressType.PERCENTAGE_FROM_TOTAL_SIZE);
|
||||||
|
Console.WriteLine("\n");
|
||||||
|
File.Delete("./" + split[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
}
|
||||||
|
spinner.Stop();
|
||||||
|
|
||||||
|
var ver = await manager.GetVersionOfPackageFromWeb(name);
|
||||||
|
if (ver is null) throw new Exception("Incorrect version");
|
||||||
|
Config.Plugins[name] = ver.ToShortString();
|
||||||
|
|
||||||
|
isDownloading = false;
|
||||||
|
|
||||||
|
|
||||||
|
Config.Logger.Log("Plugin installed !", this, LogLevel.INFO);
|
||||||
|
|
||||||
|
//await ExecuteCommad("localload " + name);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
AddCommand("value", "read value from VariableStack", "value [key]", args =>
|
||||||
|
{
|
||||||
|
if (args.Length != 2)
|
||||||
|
return;
|
||||||
|
if (!Config.Data.ContainsKey(args[1]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var data = Config.Data[args[1]];
|
||||||
|
Console.WriteLine($"{args[1]} => {data}");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AddCommand("add", "add variable to the system variables", "add [key] [value]", args =>
|
||||||
|
{
|
||||||
|
if (args.Length < 4)
|
||||||
|
return;
|
||||||
|
var key = args[1];
|
||||||
|
var value = args[2];
|
||||||
|
var isReadOnly = args[3].Equals("true", StringComparison.CurrentCultureIgnoreCase);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Config.Data[key] = value;
|
||||||
|
Console.WriteLine($"Updated config file with the following command: {args[1]} => {value}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AddCommand("remv", "remove variable from system variables", "remv [key]", args =>
|
||||||
|
{
|
||||||
|
if (args.Length < 2)
|
||||||
|
return;
|
||||||
|
Config.Data.Remove(args[1]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AddCommand("sd", "Shuts down the discord bot", async () =>
|
||||||
|
{
|
||||||
|
if (client is null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await Functions.SaveToJsonFile(Functions.dataFolder + "config.json", Config.Data);
|
||||||
|
await Functions.SaveToJsonFile(Functions.dataFolder + "Plugins.json", Config.Plugins);
|
||||||
|
await client.StopAsync();
|
||||||
|
await client.DisposeAsync();
|
||||||
|
|
||||||
|
Config.Logger.SaveToFile();
|
||||||
|
await Task.Delay(1000);
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
AddCommand("import", "Load an external command", "import [pluginName]", async args =>
|
||||||
|
{
|
||||||
|
if (args.Length <= 1) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var pName = string.Join(' ', args, 1, args.Length - 1);
|
||||||
|
using (var client = new HttpClient())
|
||||||
|
{
|
||||||
|
var url = (await manager.GetPluginLinkByName(pName))[1];
|
||||||
|
if (url is null) throw new Exception($"Invalid plugin name {pName}.");
|
||||||
|
var s = await client.GetStreamAsync(url);
|
||||||
|
var str = new MemoryStream();
|
||||||
|
await s.CopyToAsync(str);
|
||||||
|
var asmb = Assembly.Load(str.ToArray());
|
||||||
|
|
||||||
|
await PluginLoader.LoadPluginFromAssembly(asmb, this.client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddCommand("localload", "Load a local command", "local [pluginName]", async args =>
|
||||||
|
{
|
||||||
|
if (args.Length <= 1) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var pName = string.Join(' ', args, 1, args.Length - 1);
|
||||||
|
var asmb = Assembly.LoadFile(Path.GetFullPath("./Data/Plugins/" + pName + ".dll"));
|
||||||
|
|
||||||
|
await PluginLoader.LoadPluginFromAssembly(asmb, this.client);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
Config.Logger.Log(ex.Message, this, LogLevel.ERROR);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
commandList.Sort((x, y) => x.CommandName.CompareTo(y.CommandName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCommand(string command, string description, string usage, Action<string[]> action)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Adding command {command} ...");
|
||||||
|
commandList.Add(new ConsoleCommand
|
||||||
|
{ CommandName = command, Description = description, Action = action, Usage = usage });
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
Utilities.WriteColorText($"Command &r{command} &cadded to the list of commands");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCommand(string command, string description, Action action)
|
||||||
|
{
|
||||||
|
AddCommand(command, description, command, args => action());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveCommand(string command)
|
||||||
|
{
|
||||||
|
commandList.RemoveAll(x => x.CommandName == command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CommandExists(string command)
|
||||||
|
{
|
||||||
|
return GetCommand(command) is not null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConsoleCommand? GetCommand(string command)
|
||||||
|
{
|
||||||
|
return commandList.FirstOrDefault(t => t.CommandName == command);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HandleCommand(string command, bool removeCommandExecution = true)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.White;
|
||||||
|
var args = command.Split(' ');
|
||||||
|
foreach (var item in commandList.ToList())
|
||||||
|
if (item.CommandName == args[0])
|
||||||
|
{
|
||||||
|
if (args[0].StartsWith("_"))
|
||||||
|
throw new Exception("This command is reserved for internal worker and can not be executed manually !");
|
||||||
|
|
||||||
|
if (removeCommandExecution)
|
||||||
|
{
|
||||||
|
Console.SetCursorPosition(0, Console.CursorTop - 1);
|
||||||
|
for (var i = 0; i < command.Length + 30; i++)
|
||||||
|
Console.Write(" ");
|
||||||
|
Console.SetCursorPosition(0, Console.CursorTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine();
|
||||||
|
item.Action(args);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
DiscordBot/Utilities/Enums.cs
Normal file
21
DiscordBot/Utilities/Enums.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DiscordBot.Utilities
|
||||||
|
{
|
||||||
|
public enum TableFormat
|
||||||
|
{
|
||||||
|
CENTER_EACH_COLUMN_BASED,
|
||||||
|
CENTER_OVERALL_LENGTH,
|
||||||
|
DEFAULT
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ProgressBarType
|
||||||
|
{
|
||||||
|
NORMAL,
|
||||||
|
NO_END
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
using System;
|
using System.Net.Mime;
|
||||||
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
|
||||||
using static PluginManager.Others.Functions;
|
namespace PluginManager.Bot;
|
||||||
|
|
||||||
namespace DiscordBot.Discord.Core;
|
public class Boot
|
||||||
|
|
||||||
internal class Boot
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The bot prefix
|
/// The bot prefix
|
||||||
@@ -57,16 +56,20 @@ internal class Boot
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The start method for the bot. This method is used to load the bot
|
/// The start method for the bot. This method is used to load the bot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="config">The discord socket config. If null then the default one will be applied (AlwaysDownloadUsers=true, UseInteractionSnowflakeDate=false, GatewayIntents=GatewayIntents.All)</param>
|
||||||
/// <returns>Task</returns>
|
/// <returns>Task</returns>
|
||||||
public async Task Awake()
|
public async Task Awake(DiscordSocketConfig? config = null)
|
||||||
{
|
{
|
||||||
var config = new DiscordSocketConfig
|
if (config is null)
|
||||||
|
config = new DiscordSocketConfig
|
||||||
{
|
{
|
||||||
|
|
||||||
AlwaysDownloadUsers = true,
|
AlwaysDownloadUsers = true,
|
||||||
|
|
||||||
//Disable system clock checkup (for responses at slash commands)
|
//Disable system clock checkup (for responses at slash commands)
|
||||||
UseInteractionSnowflakeDate = false
|
UseInteractionSnowflakeDate = false,
|
||||||
|
|
||||||
|
GatewayIntents = GatewayIntents.All
|
||||||
};
|
};
|
||||||
|
|
||||||
client = new DiscordSocketClient(config);
|
client = new DiscordSocketClient(config);
|
||||||
@@ -79,6 +82,7 @@ internal class Boot
|
|||||||
await client.StartAsync();
|
await client.StartAsync();
|
||||||
|
|
||||||
commandServiceHandler = new CommandHandler(client, service, botPrefix);
|
commandServiceHandler = new CommandHandler(client, service, botPrefix);
|
||||||
|
|
||||||
await commandServiceHandler.InstallCommandsAsync();
|
await commandServiceHandler.InstallCommandsAsync();
|
||||||
|
|
||||||
|
|
||||||
@@ -94,32 +98,35 @@ internal class Boot
|
|||||||
client.Log += Log;
|
client.Log += Log;
|
||||||
client.LoggedIn += LoggedIn;
|
client.LoggedIn += LoggedIn;
|
||||||
client.Ready += Ready;
|
client.Ready += Ready;
|
||||||
|
client.Disconnected += Client_Disconnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Client_Disconnected(Exception arg)
|
||||||
|
{
|
||||||
|
if (arg.Message.Contains("401"))
|
||||||
|
{
|
||||||
|
Config.Data.Remove("token");
|
||||||
|
Config.Logger.Log("The token is invalid. Please restart the bot and enter a valid token.", this, Others.LogLevel.ERROR);
|
||||||
|
await Task.Delay(4000);
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Client_LoggedOut()
|
private async Task Client_LoggedOut()
|
||||||
{
|
{
|
||||||
WriteLogFile("Successfully Logged Out");
|
Config.Logger.Log("Successfully Logged Out", this);
|
||||||
await Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !"));
|
await Log(new LogMessage(LogSeverity.Info, "Boot", "Successfully logged out from discord !"));
|
||||||
|
|
||||||
/* var cmds = await client.GetGlobalApplicationCommandsAsync();
|
|
||||||
foreach (var cmd in cmds)
|
|
||||||
await cmd.DeleteAsync();*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Ready()
|
private Task Ready()
|
||||||
{
|
{
|
||||||
Console.Title = "ONLINE";
|
|
||||||
|
|
||||||
|
|
||||||
isReady = true;
|
isReady = true;
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task LoggedIn()
|
private Task LoggedIn()
|
||||||
{
|
{
|
||||||
Console.Title = "CONNECTED";
|
Config.Logger.Log("Successfully Logged In", this);
|
||||||
WriteLogFile("The bot has been logged in at " + DateTime.Now.ToShortDateString() + " (" +
|
|
||||||
DateTime.Now.ToShortTimeString() + ")"
|
|
||||||
);
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,21 +136,13 @@ internal class Boot
|
|||||||
{
|
{
|
||||||
case LogSeverity.Error:
|
case LogSeverity.Error:
|
||||||
case LogSeverity.Critical:
|
case LogSeverity.Critical:
|
||||||
WriteErrFile(message.Message);
|
Config.Logger.Log(message.Message, this, Others.LogLevel.ERROR);
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Console.WriteLine("[ERROR] " + message.Message);
|
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LogSeverity.Info:
|
case LogSeverity.Info:
|
||||||
case LogSeverity.Debug:
|
case LogSeverity.Debug:
|
||||||
WriteLogFile(message.Message);
|
Config.Logger.Log(message.Message, this);
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.Cyan;
|
|
||||||
Console.WriteLine("[INFO] " + message.Message);
|
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
using PluginManager.Interfaces;
|
||||||
using PluginManager.Loaders;
|
using PluginManager.Loaders;
|
||||||
using PluginManager.Others;
|
using PluginManager.Others;
|
||||||
using PluginManager.Others.Permissions;
|
using PluginManager.Others.Permissions;
|
||||||
|
|
||||||
namespace DiscordBot.Discord.Core;
|
namespace PluginManager.Bot;
|
||||||
|
|
||||||
internal class CommandHandler
|
internal class CommandHandler
|
||||||
{
|
{
|
||||||
@@ -29,6 +29,7 @@ internal class CommandHandler
|
|||||||
this.client = client;
|
this.client = client;
|
||||||
this.commandService = commandService;
|
this.commandService = commandService;
|
||||||
this.botPrefix = botPrefix;
|
this.botPrefix = botPrefix;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -42,7 +43,7 @@ internal class CommandHandler
|
|||||||
await commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null);
|
await commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Client_SlashCommandExecuted(SocketSlashCommand arg)
|
private Task Client_SlashCommandExecuted(SocketSlashCommand arg)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -50,7 +51,8 @@ internal class CommandHandler
|
|||||||
.Where(p => p.Name == arg.Data.Name)
|
.Where(p => p.Name == arg.Data.Name)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
if (plugin is null) throw new Exception("Failed to run command. !");
|
if (plugin is null)
|
||||||
|
throw new Exception("Failed to run command. !");
|
||||||
|
|
||||||
|
|
||||||
if (arg.Channel is SocketDMChannel)
|
if (arg.Channel is SocketDMChannel)
|
||||||
@@ -59,11 +61,11 @@ internal class CommandHandler
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
Config.Logger.Log(ex.Message, "CommandHandler", LogLevel.ERROR);
|
||||||
Console.WriteLine(ex.ToString());
|
|
||||||
ex.WriteErrFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -73,54 +75,76 @@ internal class CommandHandler
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private async Task MessageHandler(SocketMessage Message)
|
private async Task MessageHandler(SocketMessage Message)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (Message.Author.IsBot)
|
||||||
|
return;
|
||||||
|
|
||||||
if (Message as SocketUserMessage == null)
|
if (Message as SocketUserMessage == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var message = Message as SocketUserMessage;
|
var message = Message as SocketUserMessage;
|
||||||
|
|
||||||
if (message == null)
|
if (message is null)
|
||||||
return;
|
|
||||||
|
|
||||||
if (!message.Content.StartsWith(botPrefix))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var argPos = 0;
|
var argPos = 0;
|
||||||
|
|
||||||
if (message.HasMentionPrefix(client.CurrentUser, ref argPos))
|
if (!message.Content.StartsWith(botPrefix) && !message.HasMentionPrefix(client.CurrentUser, ref argPos))
|
||||||
{
|
|
||||||
await message.Channel.SendMessageAsync("Can not exec mentioned commands !");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.Author.IsBot)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var context = new SocketCommandContext(client, message);
|
var context = new SocketCommandContext(client, message);
|
||||||
|
|
||||||
await commandService.ExecuteAsync(context, argPos, null);
|
await commandService.ExecuteAsync(context, argPos, null);
|
||||||
|
|
||||||
var plugin = PluginLoader.Commands!
|
DBCommand plugin;
|
||||||
.Where(
|
string cleanMessage = "";
|
||||||
p => p.Command == message.Content.Split(' ')[0].Substring(botPrefix.Length) ||
|
|
||||||
|
if (message.HasMentionPrefix(client.CurrentUser, ref argPos))
|
||||||
|
{
|
||||||
|
string mentionPrefix = "<@" + client.CurrentUser.Id + ">";
|
||||||
|
|
||||||
|
plugin = PluginLoader.Commands!
|
||||||
|
.FirstOrDefault(plug => plug.Command == message.Content.Substring(mentionPrefix.Length+1).Split(' ')[0] ||
|
||||||
|
(
|
||||||
|
plug.Aliases is not null &&
|
||||||
|
plug.Aliases.Contains(message.CleanContent.Substring(mentionPrefix.Length+1).Split(' ')[0])
|
||||||
|
));
|
||||||
|
|
||||||
|
cleanMessage = message.Content.Substring(mentionPrefix.Length + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
plugin = PluginLoader.Commands!
|
||||||
|
.FirstOrDefault(p => p.Command == message.Content.Split(' ')[0].Substring(botPrefix.Length) ||
|
||||||
(p.Aliases is not null &&
|
(p.Aliases is not null &&
|
||||||
p.Aliases.Contains(
|
p.Aliases.Contains(
|
||||||
message.Content.Split(' ')[0].Substring(botPrefix.Length))))
|
message.Content.Split(' ')[0].Substring(botPrefix.Length))));
|
||||||
.FirstOrDefault();
|
cleanMessage = message.Content.Substring(botPrefix.Length);
|
||||||
|
}
|
||||||
if (plugin is null) throw new Exception("Failed to run command. !");
|
if (plugin is null)
|
||||||
|
throw new Exception($"Failed to run command ! " + message.CleanContent + " (user: " + context.Message.Author.Username + " - " + context.Message.Author.Id + ")");
|
||||||
|
|
||||||
if (plugin.requireAdmin && !context.Message.Author.isAdmin())
|
if (plugin.requireAdmin && !context.Message.Author.isAdmin())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
string[] split = cleanMessage.Split(' ');
|
||||||
|
|
||||||
|
string[] argsClean = null;
|
||||||
|
if(split.Length > 1)
|
||||||
|
argsClean = string.Join(' ', split, 1, split.Length-1).Split(' ');
|
||||||
|
|
||||||
|
DBCommandExecutingArguments cmd = new(context, cleanMessage, split[0], argsClean);
|
||||||
|
|
||||||
if (context.Channel is SocketDMChannel)
|
if (context.Channel is SocketDMChannel)
|
||||||
plugin.ExecuteDM(context);
|
plugin.ExecuteDM(cmd);
|
||||||
else plugin.ExecuteServer(context);
|
else plugin.ExecuteServer(cmd);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ex.WriteErrFile();
|
Config.Logger.Log(ex.Message, this, LogLevel.ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,199 +1,167 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using PluginManager.Others;
|
||||||
|
using System.Collections;
|
||||||
using PluginManager.Online.Helpers;
|
using PluginManager.Online.Helpers;
|
||||||
|
using PluginManager.Others.Logger;
|
||||||
|
|
||||||
namespace PluginManager;
|
namespace PluginManager;
|
||||||
|
|
||||||
public static class Config
|
public static class Config
|
||||||
{
|
{
|
||||||
private static bool IsLoaded = false;
|
private static bool IsLoaded = false;
|
||||||
|
|
||||||
|
public static DBLogger Logger;
|
||||||
|
public static Json<string, string> Data;
|
||||||
|
public static Json<string, string> Plugins;
|
||||||
|
|
||||||
public static async Task Initialize()
|
public static async Task Initialize()
|
||||||
{
|
{
|
||||||
if (IsLoaded)
|
if (IsLoaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!await Settings.sqlDatabase.TableExistsAsync("Plugins"))
|
Directory.CreateDirectory("./Data/Resources");
|
||||||
await Settings.sqlDatabase.CreateTableAsync("Plugins", "PluginName", "Version");
|
Directory.CreateDirectory("./Data/Plugins");
|
||||||
if (!await Settings.sqlDatabase.TableExistsAsync("Variables"))
|
Directory.CreateDirectory("./Data/PAKS");
|
||||||
await Settings.sqlDatabase.CreateTableAsync("Variables", "VarName", "Value", "ReadOnly");
|
Directory.CreateDirectory("./Data/Logs/Logs");
|
||||||
|
Directory.CreateDirectory("./Data/Logs/Errors");
|
||||||
|
|
||||||
|
Data = new Json<string, string>("./Data/Resources/config.json");
|
||||||
|
Plugins = new Json<string, string>("./Data/Resources/Plugins.json");
|
||||||
|
|
||||||
|
Config.Data["LogFolder"] = "./Data/Logs/Logs";
|
||||||
|
Config.Data["ErrorFolder"] = "./Data/Logs/Errors";
|
||||||
|
|
||||||
|
Logger = new DBLogger();
|
||||||
|
|
||||||
|
ArchiveManager.Initialize();
|
||||||
|
|
||||||
IsLoaded = true;
|
IsLoaded = true;
|
||||||
|
|
||||||
|
Logger.Log("Config initialized", LogLevel.INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Variables
|
public class Json<TKey, TValue> : IDictionary<TKey, TValue>
|
||||||
{
|
{
|
||||||
public static async Task<string> GetValueAsync(string VarName)
|
protected IDictionary<TKey, TValue> _dictionary;
|
||||||
|
private readonly string _file = "";
|
||||||
|
|
||||||
|
public Json(string file)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
_dictionary = PrivateReadConfig(file).GetAwaiter().GetResult();
|
||||||
throw new Exception("Config is not loaded");
|
this._file = file;
|
||||||
return await Settings.sqlDatabase.GetValueAsync("Variables", "VarName", VarName, "Value");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetValue(string VarName)
|
public async void Save()
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
await Functions.SaveToJsonFile(_file, _dictionary);
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
return Settings.sqlDatabase.GetValue("Variables", "VarName", VarName, "Value");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Add(TKey key, TValue value)
|
||||||
public static async Task SetValueAsync(string VarName, string Value)
|
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
_dictionary.Add(key, value);
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
|
|
||||||
if (await IsReadOnlyAsync(VarName))
|
|
||||||
throw new Exception($"Variable ({VarName}) is read only and can not be changed to {Value}");
|
|
||||||
|
|
||||||
await Settings.sqlDatabase.SetValueAsync("Variables", "VarName", VarName, "Value", Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetValue(string VarName, string Value)
|
public void Clear() { _dictionary.Clear(); }
|
||||||
|
|
||||||
|
public bool ContainsKey(TKey key)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
if (_dictionary == null)
|
||||||
throw new Exception("Config is not loaded");
|
throw new Exception("Dictionary is null");
|
||||||
if (IsReadOnly(VarName))
|
|
||||||
throw new Exception($"Variable ({VarName}) is read only and can not be changed to {Value}");
|
return _dictionary.ContainsKey(key);
|
||||||
Settings.sqlDatabase.SetValue("Variables", "VarName", VarName, "Value", Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual ICollection<TKey> Keys => _dictionary.Keys;
|
||||||
|
|
||||||
public static async Task<bool> IsReadOnlyAsync(string VarName)
|
public virtual ICollection<TValue> Values => _dictionary.Values;
|
||||||
|
|
||||||
|
public int Count => _dictionary.Count;
|
||||||
|
|
||||||
|
public bool IsReadOnly => _dictionary.IsReadOnly;
|
||||||
|
|
||||||
|
public virtual TValue this[TKey key]
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
get
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
return (await Settings.sqlDatabase.GetValueAsync("Variables", "VarName", VarName, "ReadOnly")).Equals("true", StringComparison.CurrentCultureIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsReadOnly(string VarName)
|
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
if (_dictionary.TryGetValue(key, out TValue value)) return value;
|
||||||
throw new Exception("Config is not loaded");
|
throw new Exception("Key not found in dictionary " + key.ToString() + " (Json )" + this.GetType().Name + ")");
|
||||||
return (Settings.sqlDatabase.GetValue("Variables", "VarName", VarName, "ReadOnly")).Equals("true", StringComparison.CurrentCultureIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task SetReadOnlyAsync(string VarName, bool ReadOnly)
|
}
|
||||||
|
set
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
if (_dictionary.ContainsKey(key))
|
||||||
throw new Exception("Config is not loaded");
|
_dictionary[key] = value;
|
||||||
await Settings.sqlDatabase.SetValueAsync("Variables", "VarName", VarName, "ReadOnly", ReadOnly ? "true" : "false");
|
else _dictionary.Add(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetReadOnly(string VarName, bool ReadOnly)
|
public virtual bool TryGetValue(TKey key, out TValue value)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
return _dictionary.TryGetValue(key, out value);
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
Settings.sqlDatabase.SetValue("Variables", "VarName", VarName, "ReadOnly", ReadOnly ? "true" : "false");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<bool> ExistsAsync(string VarName)
|
private async Task<Dictionary<TKey, TValue>> PrivateReadConfig(string file)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
if (!File.Exists(file))
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
return await Settings.sqlDatabase.KeyExistsAsync("Variables", "VarName", VarName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool Exists(string VarName)
|
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
var dictionary = new Dictionary<TKey, TValue>();
|
||||||
throw new Exception("Config is not loaded");
|
await Functions.SaveToJsonFile(file, _dictionary);
|
||||||
return Settings.sqlDatabase.KeyExists("Variables", "VarName", VarName);
|
return dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task AddAsync(string VarName, string Value, bool ReadOnly = false)
|
try
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
var d = await Functions.ConvertFromJson<Dictionary<TKey, TValue>>(file);
|
||||||
throw new Exception("Config is not loaded");
|
if (d is null)
|
||||||
if (await ExistsAsync(VarName))
|
throw new Exception("Failed to read config file");
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}catch (Exception ex)
|
||||||
{
|
{
|
||||||
await SetValueAsync(VarName, Value);
|
File.Delete(file);
|
||||||
await SetReadOnlyAsync(VarName, ReadOnly);
|
return new Dictionary<TKey, TValue>();
|
||||||
return;
|
|
||||||
}
|
|
||||||
await Settings.sqlDatabase.InsertAsync("Variables", VarName, Value, ReadOnly ? "true" : "false");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Add(string VarName, string Value, bool ReadOnly = false)
|
}
|
||||||
|
|
||||||
|
public bool Remove(TKey key)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
return _dictionary.Remove(key);
|
||||||
throw new Exception("Config is not loaded");
|
}
|
||||||
if (Exists(VarName))
|
|
||||||
|
public void Add(KeyValuePair<TKey, TValue> item)
|
||||||
{
|
{
|
||||||
SetValue(VarName, Value);
|
_dictionary.Add(item);
|
||||||
SetReadOnly(VarName, ReadOnly);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Settings.sqlDatabase.Insert("Variables", VarName, Value, ReadOnly ? "true" : "false");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task RemoveKeyAsync(string VarName)
|
public bool Contains(KeyValuePair<TKey, TValue> item)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
return _dictionary.Contains(item);
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
await Settings.sqlDatabase.RemoveKeyAsync("Variables", "VarName", VarName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveKey(string VarName)
|
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
_dictionary.CopyTo(array, arrayIndex);
|
||||||
throw new Exception("Config is not loaded");
|
|
||||||
Settings.sqlDatabase.RemoveKey("Variables", "VarName", VarName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Plugins
|
public bool Remove(KeyValuePair<TKey, TValue> item)
|
||||||
{
|
{
|
||||||
public static async Task<string> GetVersionAsync(string pluginName)
|
return _dictionary.Remove(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
return _dictionary.GetEnumerator();
|
||||||
throw new Exception("Config is not loaded yet");
|
|
||||||
|
|
||||||
string result = await Settings.sqlDatabase.GetValueAsync("Plugins", "PluginName", pluginName, "Version");
|
|
||||||
if (result is null)
|
|
||||||
return "0.0.0";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetVersion(string pluginName)
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
return ((IEnumerable)_dictionary).GetEnumerator();
|
||||||
throw new Exception("Config is not loaded yet");
|
}
|
||||||
|
|
||||||
string result = Settings.sqlDatabase.GetValue("Plugins", "PluginName", pluginName, "Version");
|
|
||||||
if (result is null)
|
|
||||||
return "0.0.0";
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task SetVersionAsync(string pluginName, VersionString version)
|
|
||||||
{
|
|
||||||
if (!IsLoaded)
|
|
||||||
throw new Exception("Config is not loaded yet");
|
|
||||||
|
|
||||||
if (!await Settings.sqlDatabase.KeyExistsAsync("Plugins", "PluginName", pluginName))
|
|
||||||
{
|
|
||||||
await Settings.sqlDatabase.InsertAsync("Plugins", pluginName, version.ToShortString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await Settings.sqlDatabase.SetValueAsync("Plugins", "PluginName", pluginName, "Version", version.ToShortString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetVersion(string pluginName, VersionString version)
|
|
||||||
{
|
|
||||||
if (!IsLoaded)
|
|
||||||
throw new Exception("Config is not loaded yet");
|
|
||||||
|
|
||||||
if (!Settings.sqlDatabase.KeyExists("Plugins", "PluginName", pluginName))
|
|
||||||
{
|
|
||||||
Settings.sqlDatabase.Insert("Plugins", pluginName, version.ToShortString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.sqlDatabase.SetValue("Plugins", "PluginName", pluginName, "Version", version.ToShortString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Data.SQLite;
|
using System.Data.SQLite;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace PluginManager.Database
|
namespace PluginManager.Database
|
||||||
{
|
{
|
||||||
public class SqlDatabase
|
public class SqlDatabase
|
||||||
@@ -9,24 +10,40 @@ namespace PluginManager.Database
|
|||||||
private string ConnectionString;
|
private string ConnectionString;
|
||||||
private SQLiteConnection Connection;
|
private SQLiteConnection Connection;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialize a SQL connection by specifing its private path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">The path to the database (it is starting from ./Data/Resources/)</param>
|
||||||
public SqlDatabase(string fileName)
|
public SqlDatabase(string fileName)
|
||||||
{
|
{
|
||||||
|
if (!fileName.StartsWith("./Data/Resources/"))
|
||||||
|
fileName = Path.Combine("./Data/Resources", fileName);
|
||||||
if (!File.Exists(fileName))
|
if (!File.Exists(fileName))
|
||||||
SQLiteConnection.CreateFile(fileName);
|
SQLiteConnection.CreateFile(fileName);
|
||||||
ConnectionString = $"URI=file:{fileName}";
|
ConnectionString = $"URI=file:{fileName}";
|
||||||
Connection = new SQLiteConnection(ConnectionString);
|
Connection = new SQLiteConnection(ConnectionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open the SQL Connection. To close use the Stop() method
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task Open()
|
public async Task Open()
|
||||||
{
|
{
|
||||||
await Connection.OpenAsync();
|
await Connection.OpenAsync();
|
||||||
|
|
||||||
//Console.WriteLine("Opened database successfully");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Insert into a specified table some values
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="values">The values to be inserted (in the correct order and number)</param>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task InsertAsync(string tableName, params string[] values)
|
public async Task InsertAsync(string tableName, params string[] values)
|
||||||
{
|
{
|
||||||
|
|
||||||
string query = $"INSERT INTO {tableName} VALUES (";
|
string query = $"INSERT INTO {tableName} VALUES (";
|
||||||
for (int i = 0; i < values.Length; i++)
|
for (int i = 0; i < values.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -34,15 +51,23 @@ namespace PluginManager.Database
|
|||||||
if (i != values.Length - 1)
|
if (i != values.Length - 1)
|
||||||
query += ", ";
|
query += ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
query += ")";
|
query += ")";
|
||||||
|
|
||||||
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
||||||
await command.ExecuteNonQueryAsync();
|
await command.ExecuteNonQueryAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Insert into a specified table some values
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="values">The values to be inserted (in the correct order and number)</param>
|
||||||
|
/// <returns></returns>
|
||||||
public void Insert(string tableName, params string[] values)
|
public void Insert(string tableName, params string[] values)
|
||||||
{
|
{
|
||||||
|
|
||||||
string query = $"INSERT INTO {tableName} VALUES (";
|
string query = $"INSERT INTO {tableName} VALUES (";
|
||||||
for (int i = 0; i < values.Length; i++)
|
for (int i = 0; i < values.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -50,37 +75,50 @@ namespace PluginManager.Database
|
|||||||
if (i != values.Length - 1)
|
if (i != values.Length - 1)
|
||||||
query += ", ";
|
query += ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
query += ")";
|
query += ")";
|
||||||
|
|
||||||
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
||||||
command.ExecuteNonQuery();
|
command.ExecuteNonQuery();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove every row in a table that has a certain propery
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="KeyName">The column name that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the specified column</param>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task RemoveKeyAsync(string tableName, string KeyName, string KeyValue)
|
public async Task RemoveKeyAsync(string tableName, string KeyName, string KeyValue)
|
||||||
{
|
{
|
||||||
|
|
||||||
string query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'";
|
string query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'";
|
||||||
|
|
||||||
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
||||||
await command.ExecuteNonQueryAsync();
|
await command.ExecuteNonQueryAsync();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove every row in a table that has a certain propery
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="KeyName">The column name that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the specified column</param>
|
||||||
|
/// <returns></returns>
|
||||||
public void RemoveKey(string tableName, string KeyName, string KeyValue)
|
public void RemoveKey(string tableName, string KeyName, string KeyValue)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
string query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'";
|
string query = $"DELETE FROM {tableName} WHERE {KeyName} = '{KeyValue}'";
|
||||||
|
|
||||||
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
SQLiteCommand command = new SQLiteCommand(query, Connection);
|
||||||
command.ExecuteNonQuery();
|
command.ExecuteNonQuery();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the key exists in the table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="keyName">The column that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the specified column</param>
|
||||||
|
/// <returns></returns>
|
||||||
public async Task<bool> KeyExistsAsync(string tableName, string keyName, string KeyValue)
|
public async Task<bool> KeyExistsAsync(string tableName, string keyName, string KeyValue)
|
||||||
{
|
{
|
||||||
string query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'";
|
string query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'";
|
||||||
@@ -91,6 +129,13 @@ namespace PluginManager.Database
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if the key exists in the table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="keyName">The column that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the specified column</param>
|
||||||
|
/// <returns></returns>
|
||||||
public bool KeyExists(string tableName, string keyName, string KeyValue)
|
public bool KeyExists(string tableName, string keyName, string KeyValue)
|
||||||
{
|
{
|
||||||
string query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'";
|
string query = $"SELECT * FROM {tableName} where {keyName} = '{KeyValue}'";
|
||||||
@@ -99,19 +144,38 @@ namespace PluginManager.Database
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set value of a column in a table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="keyName">The column that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the column specified</param>
|
||||||
|
/// <param name="ResultColumnName">The column that has to be modified</param>
|
||||||
|
/// <param name="ResultColumnValue">The new value that will replace the old value from the column specified</param>
|
||||||
|
|
||||||
public async Task SetValueAsync(string tableName, string keyName, string KeyValue, string ResultColumnName, string ResultColumnValue)
|
public async Task SetValueAsync(string tableName, string keyName, string KeyValue, string ResultColumnName,
|
||||||
|
string ResultColumnValue)
|
||||||
{
|
{
|
||||||
if (!await TableExistsAsync(tableName))
|
if (!await TableExistsAsync(tableName))
|
||||||
throw new System.Exception($"Table {tableName} does not exist");
|
throw new System.Exception($"Table {tableName} does not exist");
|
||||||
|
|
||||||
await ExecuteAsync($"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'");
|
await ExecuteAsync(
|
||||||
|
$"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetValue(string tableName, string keyName, string KeyValue, string ResultColumnName, string ResultColumnValue)
|
/// <summary>
|
||||||
|
/// Set value of a column in a table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="keyName">The column that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the column specified</param>
|
||||||
|
/// <param name="ResultColumnName">The column that has to be modified</param>
|
||||||
|
/// <param name="ResultColumnValue">The new value that will replace the old value from the column specified</param>
|
||||||
|
|
||||||
|
public void SetValue(string tableName, string keyName, string KeyValue, string ResultColumnName,
|
||||||
|
string ResultColumnValue)
|
||||||
{
|
{
|
||||||
if (!TableExists(tableName))
|
if (!TableExists(tableName))
|
||||||
throw new System.Exception($"Table {tableName} does not exist");
|
throw new System.Exception($"Table {tableName} does not exist");
|
||||||
@@ -119,8 +183,16 @@ namespace PluginManager.Database
|
|||||||
Execute($"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'");
|
Execute($"UPDATE {tableName} SET {ResultColumnName}='{ResultColumnValue}' WHERE {keyName}='{KeyValue}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
public async Task<string> GetValueAsync(string tableName, string keyName, string KeyValue, string ResultColumnName)
|
/// Get value from a column in a table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="keyName">The column that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the specified column</param>
|
||||||
|
/// <param name="ResultColumnName">The column that has the result</param>
|
||||||
|
/// <returns>A string that has the requested value (can be null if nothing found)</returns>
|
||||||
|
public async Task<string?> GetValueAsync(string tableName, string keyName, string KeyValue,
|
||||||
|
string ResultColumnName)
|
||||||
{
|
{
|
||||||
if (!await TableExistsAsync(tableName))
|
if (!await TableExistsAsync(tableName))
|
||||||
throw new System.Exception($"Table {tableName} does not exist");
|
throw new System.Exception($"Table {tableName} does not exist");
|
||||||
@@ -128,7 +200,16 @@ namespace PluginManager.Database
|
|||||||
return await ReadDataAsync($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'");
|
return await ReadDataAsync($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetValue(string tableName, string keyName, string KeyValue, string ResultColumnName)
|
/// <summary>
|
||||||
|
/// Get value from a column in a table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="keyName">The column that the search is made by</param>
|
||||||
|
/// <param name="KeyValue">The value that is searched in the specified column</param>
|
||||||
|
/// <param name="ResultColumnName">The column that has the result</param>
|
||||||
|
/// <returns>A string that has the requested value (can be null if nothing found)</returns>
|
||||||
|
|
||||||
|
public string? GetValue(string tableName, string keyName, string KeyValue, string ResultColumnName)
|
||||||
{
|
{
|
||||||
if (!TableExists(tableName))
|
if (!TableExists(tableName))
|
||||||
throw new System.Exception($"Table {tableName} does not exist");
|
throw new System.Exception($"Table {tableName} does not exist");
|
||||||
@@ -136,14 +217,24 @@ namespace PluginManager.Database
|
|||||||
return ReadData($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'");
|
return ReadData($"SELECT {ResultColumnName} FROM {tableName} WHERE {keyName}='{KeyValue}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop the connection to the SQL Database
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
public async void Stop()
|
public async void Stop()
|
||||||
{
|
{
|
||||||
await Connection.CloseAsync();
|
await Connection.CloseAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddColumnsToTableAsync(string tableName, string[] columns)
|
/// <summary>
|
||||||
|
/// Change the structure of a table by adding new columns
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="columns">The columns to be added</param>
|
||||||
|
/// <param name="TYPE">The type of the columns (TEXT, INTEGER, FLOAT, etc)</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task AddColumnsToTableAsync(string tableName, string[] columns, string TYPE = "TEXT")
|
||||||
{
|
{
|
||||||
|
|
||||||
var command = Connection.CreateCommand();
|
var command = Connection.CreateCommand();
|
||||||
command.CommandText = $"SELECT * FROM {tableName}";
|
command.CommandText = $"SELECT * FROM {tableName}";
|
||||||
var reader = await command.ExecuteReaderAsync();
|
var reader = await command.ExecuteReaderAsync();
|
||||||
@@ -155,15 +246,22 @@ namespace PluginManager.Database
|
|||||||
{
|
{
|
||||||
if (!tableColumns.Contains(column))
|
if (!tableColumns.Contains(column))
|
||||||
{
|
{
|
||||||
command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} TEXT";
|
command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} {TYPE}";
|
||||||
await command.ExecuteNonQueryAsync();
|
await command.ExecuteNonQueryAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddColumnsToTable(string tableName, string[] columns)
|
/// <summary>
|
||||||
{
|
/// Change the structure of a table by adding new columns
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="columns">The columns to be added</param>
|
||||||
|
/// <param name="TYPE">The type of the columns (TEXT, INTEGER, FLOAT, etc)</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
|
||||||
|
public void AddColumnsToTable(string tableName, string[] columns, string TYPE = "TEXT")
|
||||||
|
{
|
||||||
var command = Connection.CreateCommand();
|
var command = Connection.CreateCommand();
|
||||||
command.CommandText = $"SELECT * FROM {tableName}";
|
command.CommandText = $"SELECT * FROM {tableName}";
|
||||||
var reader = command.ExecuteReader();
|
var reader = command.ExecuteReader();
|
||||||
@@ -175,16 +273,19 @@ namespace PluginManager.Database
|
|||||||
{
|
{
|
||||||
if (!tableColumns.Contains(column))
|
if (!tableColumns.Contains(column))
|
||||||
{
|
{
|
||||||
command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} TEXT";
|
command.CommandText = $"ALTER TABLE {tableName} ADD COLUMN {column} {TYPE}";
|
||||||
command.ExecuteNonQuery();
|
command.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if a table exists
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <returns>True if the table exists, false if not</returns>
|
||||||
public async Task<bool> TableExistsAsync(string tableName)
|
public async Task<bool> TableExistsAsync(string tableName)
|
||||||
{
|
{
|
||||||
|
|
||||||
var cmd = Connection.CreateCommand();
|
var cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
|
cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
|
||||||
var result = await cmd.ExecuteScalarAsync();
|
var result = await cmd.ExecuteScalarAsync();
|
||||||
@@ -194,9 +295,13 @@ namespace PluginManager.Database
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if a table exists
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <returns>True if the table exists, false if not</returns>
|
||||||
public bool TableExists(string tableName)
|
public bool TableExists(string tableName)
|
||||||
{
|
{
|
||||||
|
|
||||||
var cmd = Connection.CreateCommand();
|
var cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
|
cmd.CommandText = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
|
||||||
var result = cmd.ExecuteScalar();
|
var result = cmd.ExecuteScalar();
|
||||||
@@ -206,24 +311,39 @@ namespace PluginManager.Database
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="columns">The columns of the table</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
|
||||||
public async Task CreateTableAsync(string tableName, params string[] columns)
|
public async Task CreateTableAsync(string tableName, params string[] columns)
|
||||||
{
|
{
|
||||||
|
|
||||||
var cmd = Connection.CreateCommand();
|
var cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})";
|
cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})";
|
||||||
await cmd.ExecuteNonQueryAsync();
|
await cmd.ExecuteNonQueryAsync();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a table
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tableName">The table name</param>
|
||||||
|
/// <param name="columns">The columns of the table</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
|
||||||
public void CreateTable(string tableName, params string[] columns)
|
public void CreateTable(string tableName, params string[] columns)
|
||||||
{
|
{
|
||||||
|
|
||||||
var cmd = Connection.CreateCommand();
|
var cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})";
|
cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {tableName} ({string.Join(", ", columns)})";
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute a custom query
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>The number of rows that the query modified</returns>
|
||||||
public async Task<int> ExecuteAsync(string query)
|
public async Task<int> ExecuteAsync(string query)
|
||||||
{
|
{
|
||||||
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
@@ -233,6 +353,11 @@ namespace PluginManager.Database
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute a custom query
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>The number of rows that the query modified</returns>
|
||||||
public int Execute(string query)
|
public int Execute(string query)
|
||||||
{
|
{
|
||||||
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
@@ -243,7 +368,12 @@ namespace PluginManager.Database
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> ReadDataAsync(string query)
|
/// <summary>
|
||||||
|
/// Read data from the result table and return the first row
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>The result is a string that has all values separated by space character</returns>
|
||||||
|
public async Task<string?> ReadDataAsync(string query)
|
||||||
{
|
{
|
||||||
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
await Connection.OpenAsync();
|
await Connection.OpenAsync();
|
||||||
@@ -256,10 +386,16 @@ namespace PluginManager.Database
|
|||||||
reader.GetValues(values);
|
reader.GetValues(values);
|
||||||
return string.Join<object>(" ", values);
|
return string.Join<object>(" ", values);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReadData(string query)
|
/// <summary>
|
||||||
|
/// Read data from the result table and return the first row
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>The result is a string that has all values separated by space character</returns>
|
||||||
|
public string? ReadData(string query)
|
||||||
{
|
{
|
||||||
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
Connection.Open();
|
Connection.Open();
|
||||||
@@ -272,10 +408,16 @@ namespace PluginManager.Database
|
|||||||
reader.GetValues(values);
|
reader.GetValues(values);
|
||||||
return string.Join<object>(" ", values);
|
return string.Join<object>(" ", values);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<object[]> ReadDataArrayAsync(string query)
|
/// <summary>
|
||||||
|
/// Read data from the result table and return the first row
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>The first row as separated items</returns>
|
||||||
|
public async Task<object[]?> ReadDataArrayAsync(string query)
|
||||||
{
|
{
|
||||||
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
await Connection.OpenAsync();
|
await Connection.OpenAsync();
|
||||||
@@ -288,10 +430,17 @@ namespace PluginManager.Database
|
|||||||
reader.GetValues(values);
|
reader.GetValues(values);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object[] ReadDataArray(string query)
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read data from the result table and return the first row
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>The first row as separated items</returns>
|
||||||
|
public object[]? ReadDataArray(string query)
|
||||||
{
|
{
|
||||||
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
Connection.Open();
|
Connection.Open();
|
||||||
@@ -304,7 +453,37 @@ namespace PluginManager.Database
|
|||||||
reader.GetValues(values);
|
reader.GetValues(values);
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read all rows from the result table and return them as a list of string arrays. The string arrays contain the values of each row
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">The query</param>
|
||||||
|
/// <returns>A list of string arrays representing the values that the query returns</returns>
|
||||||
|
|
||||||
|
public async Task<List<string[]>?> ReadAllRowsAsync(string query)
|
||||||
|
{
|
||||||
|
if (!Connection.State.HasFlag(System.Data.ConnectionState.Open))
|
||||||
|
await Connection.OpenAsync();
|
||||||
|
var command = new SQLiteCommand(query, Connection);
|
||||||
|
var reader = await command.ExecuteReaderAsync();
|
||||||
|
|
||||||
|
if (!reader.HasRows)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
List<string[]> rows = new();
|
||||||
|
while (await reader.ReadAsync())
|
||||||
|
{
|
||||||
|
string[] values = new string[reader.FieldCount];
|
||||||
|
reader.GetValues(values);
|
||||||
|
rows.Add(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rows.Count == 0) return null;
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using PluginManager.Others;
|
||||||
using Discord.Commands;
|
|
||||||
|
|
||||||
namespace PluginManager.Interfaces;
|
namespace PluginManager.Interfaces;
|
||||||
|
|
||||||
@@ -36,16 +35,16 @@ public interface DBCommand
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main body of the command. This is what is executed when user calls the command in Server
|
/// The main body of the command. This is what is executed when user calls the command in Server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">The disocrd Context</param>
|
/// <param name="args">The disocrd Context</param>
|
||||||
void ExecuteServer(SocketCommandContext context)
|
void ExecuteServer(DBCommandExecutingArguments args)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main body of the command. This is what is executed when user calls the command in DM
|
/// The main body of the command. This is what is executed when user calls the command in DM
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">The disocrd Context</param>
|
/// <param name="args">The disocrd Context</param>
|
||||||
void ExecuteDM(SocketCommandContext context)
|
void ExecuteDM(DBCommandExecutingArguments args)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
using Discord.WebSocket;
|
|
||||||
|
|
||||||
namespace PluginManager.Items;
|
|
||||||
|
|
||||||
public class Command
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The author of the command
|
|
||||||
/// </summary>
|
|
||||||
public SocketUser? Author;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The Command class contructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="message">The message that was sent</param>
|
|
||||||
public Command(SocketMessage message)
|
|
||||||
{
|
|
||||||
Author = message.Author;
|
|
||||||
var data = message.Content.Split(' ');
|
|
||||||
Arguments = data.Length > 1 ? new List<string>(string.Join(' ', data, 1, data.Length - 1).Split(' ')) : new List<string>();
|
|
||||||
CommandName = data[0].Substring(1);
|
|
||||||
PrefixUsed = data[0][0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The list of arguments
|
|
||||||
/// </summary>
|
|
||||||
public List<string> Arguments { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The command that is executed
|
|
||||||
/// </summary>
|
|
||||||
public string CommandName { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The prefix that is used for the command
|
|
||||||
/// </summary>
|
|
||||||
public char PrefixUsed { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConsoleCommand
|
|
||||||
{
|
|
||||||
public string CommandName { get; init; }
|
|
||||||
public string Description { get; init; }
|
|
||||||
public string Usage { get; init; }
|
|
||||||
public Action<string[]> Action { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,506 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
using Discord.WebSocket;
|
|
||||||
|
|
||||||
using PluginManager.Interfaces;
|
|
||||||
using PluginManager.Loaders;
|
|
||||||
using PluginManager.Online;
|
|
||||||
using PluginManager.Others;
|
|
||||||
|
|
||||||
using OperatingSystem = PluginManager.Others.OperatingSystem;
|
|
||||||
|
|
||||||
namespace PluginManager.Items;
|
|
||||||
|
|
||||||
public class ConsoleCommandsHandler
|
|
||||||
{
|
|
||||||
private static readonly PluginsManager manager =
|
|
||||||
new("https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/Plugins.txt");
|
|
||||||
|
|
||||||
private static readonly List<ConsoleCommand> commandList = new();
|
|
||||||
|
|
||||||
|
|
||||||
private static bool isDownloading;
|
|
||||||
private static bool pluginsLoaded;
|
|
||||||
private readonly DiscordSocketClient? client;
|
|
||||||
|
|
||||||
public ConsoleCommandsHandler(DiscordSocketClient client)
|
|
||||||
{
|
|
||||||
this.client = client;
|
|
||||||
InitializeBasicCommands();
|
|
||||||
|
|
||||||
|
|
||||||
//Settings.Variables.outputStream.WriteLine("Initialized console command handler !");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeBasicCommands()
|
|
||||||
{
|
|
||||||
commandList.Clear();
|
|
||||||
|
|
||||||
AddCommand("help", "Show help", "help <command>", args =>
|
|
||||||
{
|
|
||||||
if (args.Length <= 1)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine("Available commands:");
|
|
||||||
var items = new List<string[]>();
|
|
||||||
items.Add(new[] { "-", "-", "-" });
|
|
||||||
items.Add(new[] { "Command", "Description", "Usage" });
|
|
||||||
items.Add(new[] { " ", " ", "Argument type: <optional> [required]" });
|
|
||||||
items.Add(new[] { "-", "-", "-" });
|
|
||||||
|
|
||||||
foreach (var command in commandList)
|
|
||||||
{
|
|
||||||
var pa = from p in command.Action.Method.GetParameters()
|
|
||||||
where p.Name != null
|
|
||||||
select p.ParameterType.FullName;
|
|
||||||
items.Add(new[] { command.CommandName, command.Description, command.Usage });
|
|
||||||
}
|
|
||||||
|
|
||||||
items.Add(new[] { "-", "-", "-" });
|
|
||||||
Utilities.FormatAndAlignTable(items, TableFormat.DEFAULT);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var command in commandList)
|
|
||||||
if (command.CommandName == args[1])
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine("Command description: " + command.Description);
|
|
||||||
Settings.Variables.outputStream.WriteLine("Command execution format:" + command.Usage);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine("Command not found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
AddCommand("lp", "Load plugins", () =>
|
|
||||||
{
|
|
||||||
if (pluginsLoaded)
|
|
||||||
return;
|
|
||||||
var loader = new PluginLoader(client!);
|
|
||||||
var cc = Console.ForegroundColor;
|
|
||||||
loader.onCMDLoad += (name, typeName, success, exception) =>
|
|
||||||
{
|
|
||||||
if (name == null || name.Length < 2)
|
|
||||||
name = typeName;
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Settings.Variables.outputStream.WriteLine("[CMD] Successfully loaded command : " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
if (exception is null)
|
|
||||||
Settings.Variables.outputStream.WriteLine("An error occured while loading: " + name);
|
|
||||||
else
|
|
||||||
Settings.Variables.outputStream.WriteLine("[CMD] Failed to load command : " + name + " because " + exception!.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
};
|
|
||||||
loader.onEVELoad += (name, typeName, success, exception) =>
|
|
||||||
{
|
|
||||||
if (name == null || name.Length < 2)
|
|
||||||
name = typeName;
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Settings.Variables.outputStream.WriteLine("[EVENT] Successfully loaded event : " + name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Settings.Variables.outputStream.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception!.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
};
|
|
||||||
|
|
||||||
loader.onSLSHLoad += (name, typeName, success, exception) =>
|
|
||||||
{
|
|
||||||
if (name == null || name.Length < 2)
|
|
||||||
name = typeName;
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Settings.Variables.outputStream.WriteLine("[SLASH] Successfully loaded command : " + name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.Red;
|
|
||||||
Settings.Variables.outputStream.WriteLine("[SLASH] Failed to load command : " + name + " because " + exception!.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
};
|
|
||||||
|
|
||||||
loader.LoadPlugins();
|
|
||||||
Console.ForegroundColor = cc;
|
|
||||||
pluginsLoaded = true;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
AddCommand("listplugs", "list available plugins", () => { manager.ListAvailablePlugins().Wait(); });
|
|
||||||
|
|
||||||
AddCommand("dwplug", "download plugin", "dwplug [name]", async args =>
|
|
||||||
{
|
|
||||||
isDownloading = true;
|
|
||||||
if (args.Length == 1)
|
|
||||||
{
|
|
||||||
isDownloading = false;
|
|
||||||
Settings.Variables.outputStream.WriteLine("Please specify plugin name");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = string.Join(' ', args, 1, args.Length - 1);
|
|
||||||
// info[0] = plugin type
|
|
||||||
// info[1] = plugin link
|
|
||||||
// info[2] = if others are required, or string.Empty if none
|
|
||||||
var info = await manager.GetPluginLinkByName(name);
|
|
||||||
if (info[1] == null) // link is null
|
|
||||||
{
|
|
||||||
if (name == "")
|
|
||||||
{
|
|
||||||
isDownloading = false;
|
|
||||||
Utilities.WriteColorText("Name is invalid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isDownloading = false;
|
|
||||||
Utilities.WriteColorText($"Failed to find plugin &b{name} &c!" +
|
|
||||||
" Use &glistplugs &ccommand to display all available plugins !");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string path;
|
|
||||||
if (info[0] == "Plugin")
|
|
||||||
path = "./Data/Plugins/" + name + ".dll";
|
|
||||||
else
|
|
||||||
path = $"./{info[1].Split('/')[info[1].Split('/').Length - 1]}";
|
|
||||||
|
|
||||||
if (OperatingSystem.WINDOWS == Functions.GetOperatingSystem())
|
|
||||||
{
|
|
||||||
await ServerCom.DownloadFileAsync(info[1], path);
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.LINUX == Functions.GetOperatingSystem())
|
|
||||||
{
|
|
||||||
var bar = new Utilities.ProgressBar(ProgressBarType.NO_END);
|
|
||||||
bar.Start();
|
|
||||||
await ServerCom.DownloadFileNoProgressAsync(info[1], path);
|
|
||||||
bar.Stop("Plugin Downloaded !");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine("\n");
|
|
||||||
|
|
||||||
// check requirements if any
|
|
||||||
|
|
||||||
if (info.Length == 3 && info[2] != string.Empty && info[2] != null)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine($"Downloading requirements for plugin : {name}");
|
|
||||||
|
|
||||||
var lines = await ServerCom.ReadTextFromURL(info[2]);
|
|
||||||
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
|
||||||
if (!(line.Length > 0 && line.Contains(",")))
|
|
||||||
continue;
|
|
||||||
var split = line.Split(',');
|
|
||||||
Settings.Variables.outputStream.WriteLine($"\nDownloading item: {split[1]}");
|
|
||||||
if (File.Exists("./" + split[1])) File.Delete("./" + split[1]);
|
|
||||||
if (OperatingSystem.WINDOWS == Functions.GetOperatingSystem())
|
|
||||||
{
|
|
||||||
await ServerCom.DownloadFileAsync(split[0], "./" + split[1]);
|
|
||||||
}
|
|
||||||
else if (OperatingSystem.LINUX == Functions.GetOperatingSystem())
|
|
||||||
{
|
|
||||||
var bar = new Utilities.ProgressBar(ProgressBarType.NO_END);
|
|
||||||
bar.Start();
|
|
||||||
await ServerCom.DownloadFileNoProgressAsync(split[0], "./" + split[1]);
|
|
||||||
bar.Stop("Item downloaded !");
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine();
|
|
||||||
if (split[0].EndsWith(".pak"))
|
|
||||||
{
|
|
||||||
File.Move("./" + split[1], "./Data/PAKS/" + split[1], true);
|
|
||||||
}
|
|
||||||
else if (split[0].EndsWith(".zip") || split[0].EndsWith(".pkg"))
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine($"Extracting {split[1]} ...");
|
|
||||||
var bar = new Utilities.ProgressBar(
|
|
||||||
ProgressBarType.NO_END);
|
|
||||||
bar.Start();
|
|
||||||
await Functions.ExtractArchive("./" + split[1], "./", null,
|
|
||||||
UnzipProgressType.PercentageFromTotalSize);
|
|
||||||
bar.Stop("Extracted");
|
|
||||||
Settings.Variables.outputStream.WriteLine("\n");
|
|
||||||
File.Delete("./" + split[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
var ver = await ServerCom.GetVersionOfPackageFromWeb(name);
|
|
||||||
if (ver is null) throw new Exception("Incorrect version");
|
|
||||||
await Config.Plugins.SetVersionAsync(name, ver);
|
|
||||||
|
|
||||||
isDownloading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
AddCommand("value", "read value from VariableStack", "value [key]", args =>
|
|
||||||
{
|
|
||||||
if (args.Length != 2)
|
|
||||||
return;
|
|
||||||
if (!Config.Variables.Exists(args[1]))
|
|
||||||
return;
|
|
||||||
|
|
||||||
var data = Config.Variables.GetValue(args[1]);
|
|
||||||
Settings.Variables.outputStream.WriteLine($"{args[1]} => {data}");
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
AddCommand("add", "add variable to the system variables", "add [key] [value] [isReadOnly=true/false]", args =>
|
|
||||||
{
|
|
||||||
if (args.Length < 4)
|
|
||||||
return;
|
|
||||||
var key = args[1];
|
|
||||||
var value = args[2];
|
|
||||||
var isReadOnly = args[3].Equals("true", StringComparison.CurrentCultureIgnoreCase);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Config.Variables.Add(key, value, isReadOnly);
|
|
||||||
Settings.Variables.outputStream.WriteLine($"Updated config file with the following command: {args[1]} => {value}");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine(ex.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
AddCommand("remv", "remove variable from system variables", "remv [key]", args =>
|
|
||||||
{
|
|
||||||
if (args.Length < 2)
|
|
||||||
return;
|
|
||||||
Config.Variables.RemoveKey(args[1]);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
AddCommand("sd", "Shuts down the discord bot", async () =>
|
|
||||||
{
|
|
||||||
if (client is null)
|
|
||||||
return;
|
|
||||||
var bar = new Utilities.ProgressBar(ProgressBarType.NO_END);
|
|
||||||
|
|
||||||
bar.Start();
|
|
||||||
bar.Stop("Saved config !");
|
|
||||||
Settings.Variables.outputStream.WriteLine();
|
|
||||||
Settings.sqlDatabase.Stop();
|
|
||||||
await client.StopAsync();
|
|
||||||
await client.DisposeAsync();
|
|
||||||
|
|
||||||
await Task.Delay(1000);
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
AddCommand("import", "Load an external command", "import [pluginName]", async args =>
|
|
||||||
{
|
|
||||||
if (args.Length <= 1) return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var pName = string.Join(' ', args, 1, args.Length - 1);
|
|
||||||
var client = new HttpClient();
|
|
||||||
var url = (await manager.GetPluginLinkByName(pName))[1];
|
|
||||||
if (url is null) throw new Exception($"Invalid plugin name {pName}.");
|
|
||||||
var s = await client.GetStreamAsync(url);
|
|
||||||
var str = new MemoryStream();
|
|
||||||
await s.CopyToAsync(str);
|
|
||||||
var asmb = Assembly.Load(str.ToArray());
|
|
||||||
|
|
||||||
var types = asmb.GetTypes();
|
|
||||||
foreach (var type in types)
|
|
||||||
if (type.IsClass && typeof(DBEvent).IsAssignableFrom(type))
|
|
||||||
{
|
|
||||||
var instance = (DBEvent)Activator.CreateInstance(type);
|
|
||||||
instance.Start(this.client);
|
|
||||||
Settings.Variables.outputStream.WriteLine($"[EVENT] Loaded external {type.FullName}!");
|
|
||||||
}
|
|
||||||
else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type))
|
|
||||||
{
|
|
||||||
var instance = (DBCommand)Activator.CreateInstance(type);
|
|
||||||
Settings.Variables.outputStream.WriteLine($"[CMD] Instance: {type.FullName} loaded !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AddCommand("remplug", "Remove a plugin", "remplug [plugName]", async args =>
|
|
||||||
{
|
|
||||||
if (args.Length <= 1) return;
|
|
||||||
|
|
||||||
isDownloading = true;
|
|
||||||
var plugName = string.Join(' ', args, 1, args.Length - 1);
|
|
||||||
if (pluginsLoaded)
|
|
||||||
{
|
|
||||||
if (Functions.GetOperatingSystem() == OperatingSystem.WINDOWS)
|
|
||||||
{
|
|
||||||
Process.Start("DiscordBot.exe", $"/remplug {plugName}");
|
|
||||||
await Task.Delay(100);
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Process.Start("./DiscordBot", $"/remplug {plugName}");
|
|
||||||
await Task.Delay(100);
|
|
||||||
Environment.Exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
isDownloading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var location = $"./Data/Plugins/{plugName}.dll";
|
|
||||||
|
|
||||||
if (!File.Exists(location))
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine("The plugin does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
File.Delete(location);
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine("Removed the plugin DLL. Checking for other files ...");
|
|
||||||
|
|
||||||
var info = await manager.GetPluginLinkByName(plugName);
|
|
||||||
if (info[2] != string.Empty)
|
|
||||||
{
|
|
||||||
var lines = await ServerCom.ReadTextFromURL(info[2]);
|
|
||||||
foreach (var line in lines)
|
|
||||||
{
|
|
||||||
if (!(line.Length > 0 && line.Contains(",")))
|
|
||||||
continue;
|
|
||||||
var split = line.Split(',');
|
|
||||||
if (File.Exists("./" + split[1]))
|
|
||||||
File.Delete("./" + split[1]);
|
|
||||||
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine("Removed: " + split[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists($"./Data/Plugins/{plugName}"))
|
|
||||||
Directory.Delete($"./Data/Plugins/{plugName}", true);
|
|
||||||
|
|
||||||
if (Directory.Exists(plugName))
|
|
||||||
Directory.Delete(plugName, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
isDownloading = false;
|
|
||||||
Settings.Variables.outputStream.WriteLine(plugName + " has been successfully deleted !");
|
|
||||||
});
|
|
||||||
|
|
||||||
AddCommand("reload", "Reload the bot with all plugins", () =>
|
|
||||||
{
|
|
||||||
if (Functions.GetOperatingSystem() == OperatingSystem.WINDOWS)
|
|
||||||
{
|
|
||||||
Process.Start("DiscordBot.exe", "lp");
|
|
||||||
HandleCommand("sd");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Process.Start("./DiscordBot", "lp");
|
|
||||||
HandleCommand("sd");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//AddCommand("");
|
|
||||||
|
|
||||||
//Sort the commands by name
|
|
||||||
commandList.Sort((x, y) => x.CommandName.CompareTo(y.CommandName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddCommand(string command, string description, string usage, Action<string[]> action)
|
|
||||||
{
|
|
||||||
commandList.Add(new ConsoleCommand
|
|
||||||
{ CommandName = command, Description = description, Action = action, Usage = usage });
|
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
|
||||||
Utilities.WriteColorText($"Command &r{command} &cadded to the list of commands");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddCommand(string command, string description, Action action)
|
|
||||||
{
|
|
||||||
AddCommand(command, description, command, args => action());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveCommand(string command)
|
|
||||||
{
|
|
||||||
commandList.RemoveAll(x => x.CommandName == command);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool CommandExists(string command)
|
|
||||||
{
|
|
||||||
return GetCommand(command) is not null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ConsoleCommand? GetCommand(string command)
|
|
||||||
{
|
|
||||||
return commandList.FirstOrDefault(t => t.CommandName == command);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task ExecuteCommad(string command)
|
|
||||||
{
|
|
||||||
var args = command.Split(' ');
|
|
||||||
foreach (var item in commandList.ToList())
|
|
||||||
if (item.CommandName == args[0])
|
|
||||||
{
|
|
||||||
item.Action.Invoke(args);
|
|
||||||
while (isDownloading) await Task.Delay(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HandleCommand(string command, bool removeCommandExecution = true)
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.White;
|
|
||||||
var args = command.Split(' ');
|
|
||||||
foreach (var item in commandList.ToList())
|
|
||||||
if (item.CommandName == args[0])
|
|
||||||
{
|
|
||||||
if (removeCommandExecution)
|
|
||||||
{
|
|
||||||
Console.SetCursorPosition(0, Console.CursorTop - 1);
|
|
||||||
for (var i = 0; i < command.Length + 30; i++)
|
|
||||||
Settings.Variables.outputStream.Write(" ");
|
|
||||||
Console.SetCursorPosition(0, Console.CursorTop);
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings.Variables.outputStream.WriteLine();
|
|
||||||
item.Action(args);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
//Settings.Variables.outputStream.WriteLine($"Executing: {args[0]} with the following parameters: {args.MergeStrings(1)}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
using PluginManager.Others;
|
using PluginManager.Interfaces;
|
||||||
|
|
||||||
namespace PluginManager.Loaders;
|
namespace PluginManager.Loaders
|
||||||
|
|
||||||
internal class LoaderArgs : EventArgs
|
|
||||||
{
|
{
|
||||||
|
internal class LoaderArgs : EventArgs
|
||||||
|
{
|
||||||
internal string? PluginName { get; init; }
|
internal string? PluginName { get; init; }
|
||||||
internal string? TypeName { get; init; }
|
internal string? TypeName { get; init; }
|
||||||
internal bool IsLoaded { get; init; }
|
internal bool IsLoaded { get; init; }
|
||||||
internal Exception? Exception { get; init; }
|
internal Exception? Exception { get; init; }
|
||||||
internal object? Plugin { get; init; }
|
internal object? Plugin { get; init; }
|
||||||
}
|
}
|
||||||
|
internal class Loader
|
||||||
internal class Loader<T>
|
{
|
||||||
{
|
|
||||||
internal Loader(string path, string extension)
|
internal Loader(string path, string extension)
|
||||||
{
|
{
|
||||||
this.path = path;
|
this.path = path;
|
||||||
@@ -33,25 +32,43 @@ internal class Loader<T>
|
|||||||
|
|
||||||
internal event PluginLoadedEventHandler? PluginLoaded;
|
internal event PluginLoadedEventHandler? PluginLoaded;
|
||||||
|
|
||||||
internal List<T>? Load()
|
|
||||||
|
internal delegate void FileLoadedEventHandler(LoaderArgs args);
|
||||||
|
|
||||||
|
internal delegate void PluginLoadedEventHandler(LoaderArgs args);
|
||||||
|
|
||||||
|
|
||||||
|
internal (List<DBEvent>?, List<DBCommand>?, List<DBSlashCommand>?) Load()
|
||||||
{
|
{
|
||||||
var list = new List<T>();
|
|
||||||
|
List<DBEvent> events = new();
|
||||||
|
List<DBSlashCommand> slashCommands = new();
|
||||||
|
List<DBCommand> commands = new();
|
||||||
|
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
return null;
|
return (null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories);
|
var files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories);
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
Assembly.LoadFrom(file);
|
Assembly.LoadFrom(file);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Config.Logger.Log("PluginName: " + new FileInfo(file).Name.Split('.')[0] + " not loaded", this, Others.LogLevel.ERROR);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (FileLoaded != null)
|
if (FileLoaded != null)
|
||||||
{
|
{
|
||||||
var args = new LoaderArgs
|
var args = new LoaderArgs
|
||||||
{
|
{
|
||||||
Exception = null,
|
Exception = null,
|
||||||
TypeName = nameof(T),
|
TypeName = null,
|
||||||
IsLoaded = false,
|
IsLoaded = false,
|
||||||
PluginName = new FileInfo(file).Name.Split('.')[0],
|
PluginName = new FileInfo(file).Name.Split('.')[0],
|
||||||
Plugin = null
|
Plugin = null
|
||||||
@@ -60,6 +77,16 @@ internal class Loader<T>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (LoadItems<DBEvent>(), LoadItems<DBCommand>(), LoadItems<DBSlashCommand>());
|
||||||
|
}
|
||||||
|
|
||||||
|
internal List<T> LoadItems<T>()
|
||||||
|
{
|
||||||
|
List<T> list = new();
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var interfaceType = typeof(T);
|
var interfaceType = typeof(T);
|
||||||
@@ -83,7 +110,7 @@ internal class Loader<T>
|
|||||||
Exception = null,
|
Exception = null,
|
||||||
IsLoaded = true,
|
IsLoaded = true,
|
||||||
PluginName = type.FullName,
|
PluginName = type.FullName,
|
||||||
TypeName = nameof(T),
|
TypeName = typeof(T) == typeof(DBCommand) ? "DBCommand" : typeof(T) == typeof(DBEvent) ? "DBEvent" : "DBSlashCommand",
|
||||||
Plugin = plugin
|
Plugin = plugin
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -99,18 +126,17 @@ internal class Loader<T>
|
|||||||
TypeName = nameof(T)
|
TypeName = nameof(T)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Functions.WriteErrFile(ex.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Config.Logger.Log(ex.Message, this, Others.LogLevel.ERROR);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
internal delegate void FileLoadedEventHandler(LoaderArgs args);
|
}
|
||||||
|
|
||||||
internal delegate void PluginLoadedEventHandler(LoaderArgs args);
|
|
||||||
}
|
}
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
using PluginManager.Interfaces;
|
|
||||||
using PluginManager.Others;
|
|
||||||
|
|
||||||
namespace PluginManager.Loaders
|
|
||||||
{
|
|
||||||
internal class LoaderV2
|
|
||||||
{
|
|
||||||
internal LoaderV2(string path, string extension)
|
|
||||||
{
|
|
||||||
this.path = path;
|
|
||||||
this.extension = extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private string path { get; }
|
|
||||||
private string extension { get; }
|
|
||||||
|
|
||||||
internal event FileLoadedEventHandler? FileLoaded;
|
|
||||||
|
|
||||||
internal event PluginLoadedEventHandler? PluginLoaded;
|
|
||||||
|
|
||||||
|
|
||||||
internal delegate void FileLoadedEventHandler(LoaderArgs args);
|
|
||||||
|
|
||||||
internal delegate void PluginLoadedEventHandler(LoaderArgs args);
|
|
||||||
|
|
||||||
|
|
||||||
internal (List<DBEvent>?, List<DBCommand>?, List<DBSlashCommand>?) Load()
|
|
||||||
{
|
|
||||||
|
|
||||||
List<DBEvent> events = new();
|
|
||||||
List<DBSlashCommand> slashCommands = new();
|
|
||||||
List<DBCommand> commands = new();
|
|
||||||
|
|
||||||
if (!Directory.Exists(path))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(path);
|
|
||||||
return (null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var files = Directory.GetFiles(path, $"*.{extension}", SearchOption.AllDirectories);
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
|
||||||
Assembly.LoadFrom(file);
|
|
||||||
if (FileLoaded != null)
|
|
||||||
{
|
|
||||||
var args = new LoaderArgs
|
|
||||||
{
|
|
||||||
Exception = null,
|
|
||||||
TypeName = null,
|
|
||||||
IsLoaded = false,
|
|
||||||
PluginName = new FileInfo(file).Name.Split('.')[0],
|
|
||||||
Plugin = null
|
|
||||||
};
|
|
||||||
FileLoaded.Invoke(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (LoadItems<DBEvent>(), LoadItems<DBCommand>(), LoadItems<DBSlashCommand>());
|
|
||||||
}
|
|
||||||
|
|
||||||
internal List<T> LoadItems<T>()
|
|
||||||
{
|
|
||||||
List<T> list = new();
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var interfaceType = typeof(T);
|
|
||||||
var types = AppDomain.CurrentDomain.GetAssemblies()
|
|
||||||
.SelectMany(a => a.GetTypes())
|
|
||||||
.Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass)
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
|
|
||||||
list.Clear();
|
|
||||||
foreach (var type in types)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var plugin = (T)Activator.CreateInstance(type)!;
|
|
||||||
list.Add(plugin);
|
|
||||||
|
|
||||||
|
|
||||||
if (PluginLoaded != null)
|
|
||||||
PluginLoaded.Invoke(new LoaderArgs
|
|
||||||
{
|
|
||||||
Exception = null,
|
|
||||||
IsLoaded = true,
|
|
||||||
PluginName = type.FullName,
|
|
||||||
TypeName = typeof(T) == typeof(DBCommand) ? "DBCommand" : typeof(T) == typeof(DBEvent) ? "DBEvent" : "DBSlashCommand",
|
|
||||||
Plugin = plugin
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
if (PluginLoaded != null)
|
|
||||||
PluginLoaded.Invoke(new LoaderArgs
|
|
||||||
{
|
|
||||||
Exception = ex,
|
|
||||||
IsLoaded = false,
|
|
||||||
PluginName = type.FullName,
|
|
||||||
TypeName = nameof(T)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Functions.WriteErrFile(ex.ToString());
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Discord;
|
using Discord;
|
||||||
@@ -8,8 +9,6 @@ using Discord.WebSocket;
|
|||||||
|
|
||||||
using PluginManager.Interfaces;
|
using PluginManager.Interfaces;
|
||||||
using PluginManager.Online;
|
using PluginManager.Online;
|
||||||
using PluginManager.Online.Updates;
|
|
||||||
using PluginManager.Others;
|
|
||||||
|
|
||||||
namespace PluginManager.Loaders;
|
namespace PluginManager.Loaders;
|
||||||
|
|
||||||
@@ -66,39 +65,32 @@ public class PluginLoader
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static List<DBSlashCommand>? SlashCommands { get; set; }
|
public static List<DBSlashCommand>? SlashCommands { get; set; }
|
||||||
|
|
||||||
|
public static int PluginsLoaded { get {
|
||||||
|
var count = 0;
|
||||||
|
if (Commands is not null)
|
||||||
|
count += Commands.Count;
|
||||||
|
if (Events is not null)
|
||||||
|
count += Events.Count;
|
||||||
|
if (SlashCommands is not null)
|
||||||
|
count += SlashCommands.Count;
|
||||||
|
return count;
|
||||||
|
}}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main mathod that is called to load all events
|
/// The main mathod that is called to load all events
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async void LoadPlugins()
|
public async void LoadPlugins()
|
||||||
{
|
{
|
||||||
//Check for updates in commands
|
|
||||||
foreach (var file in Directory.GetFiles("./Data/Plugins/", $"*.{pluginExtension}",
|
|
||||||
SearchOption.AllDirectories))
|
|
||||||
await Task.Run(async () =>
|
|
||||||
{
|
|
||||||
var name = new FileInfo(file).Name.Split('.')[0];
|
|
||||||
var version = await ServerCom.GetVersionOfPackageFromWeb(name);
|
|
||||||
if (version is null)
|
|
||||||
return;
|
|
||||||
if (Config.Plugins.GetVersion(name) is not null)
|
|
||||||
Config.Plugins.SetVersion(name, version);
|
|
||||||
|
|
||||||
if (await PluginUpdater.CheckForUpdates(name))
|
|
||||||
await PluginUpdater.Download(name);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//Load all plugins
|
//Load all plugins
|
||||||
|
|
||||||
Commands = new List<DBCommand>();
|
Commands = new List<DBCommand>();
|
||||||
Events = new List<DBEvent>();
|
Events = new List<DBEvent>();
|
||||||
SlashCommands = new List<DBSlashCommand>();
|
SlashCommands = new List<DBSlashCommand>();
|
||||||
|
|
||||||
Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username);
|
Config.Logger.Log("Starting plugin loader ... Client: " + _client.CurrentUser.Username, this, Others.LogLevel.INFO);
|
||||||
Settings.Variables.outputStream.WriteLine("Loading plugins");
|
|
||||||
|
|
||||||
var loader = new LoaderV2("./Data/Plugins", "dll");
|
var loader = new Loader("./Data/Plugins", "dll");
|
||||||
loader.FileLoaded += (args) => Functions.WriteLogFile($"{args.PluginName} file Loaded");
|
loader.FileLoaded += (args) => Config.Logger.Log($"{args.PluginName} file Loaded", this , Others.LogLevel.INFO);
|
||||||
loader.PluginLoaded += Loader_PluginLoaded;
|
loader.PluginLoaded += Loader_PluginLoaded;
|
||||||
var res = loader.Load();
|
var res = loader.Load();
|
||||||
Events = res.Item1;
|
Events = res.Item1;
|
||||||
@@ -108,7 +100,7 @@ public class PluginLoader
|
|||||||
|
|
||||||
private async void Loader_PluginLoaded(LoaderArgs args)
|
private async void Loader_PluginLoaded(LoaderArgs args)
|
||||||
{
|
{
|
||||||
// Settings.Variables.outputStream.WriteLine(args.TypeName);
|
|
||||||
switch (args.TypeName)
|
switch (args.TypeName)
|
||||||
{
|
{
|
||||||
case "DBCommand":
|
case "DBCommand":
|
||||||
@@ -124,10 +116,7 @@ public class PluginLoader
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.WriteLine(ex.ToString());
|
Config.Logger.Log(ex.Message, this, Others.LogLevel.ERROR);
|
||||||
Settings.Variables.outputStream.WriteLine("Plugin: " + args.PluginName);
|
|
||||||
Settings.Variables.outputStream.WriteLine("Type: " + args.TypeName);
|
|
||||||
Settings.Variables.outputStream.WriteLine("IsLoaded: " + args.IsLoaded);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "DBSlashCommand":
|
case "DBSlashCommand":
|
||||||
@@ -139,7 +128,7 @@ public class PluginLoader
|
|||||||
builder.WithDescription(slash.Description);
|
builder.WithDescription(slash.Description);
|
||||||
builder.WithDMPermission(slash.canUseDM);
|
builder.WithDMPermission(slash.canUseDM);
|
||||||
builder.Options = slash.Options;
|
builder.Options = slash.Options;
|
||||||
//Settings.Variables.outputStream.WriteLine("Loaded " + slash.Name);
|
|
||||||
onSLSHLoad?.Invoke(((DBSlashCommand)args.Plugin!).Name, args.TypeName, args.IsLoaded, args.Exception);
|
onSLSHLoad?.Invoke(((DBSlashCommand)args.Plugin!).Name, args.TypeName, args.IsLoaded, args.Exception);
|
||||||
await _client.CreateGlobalApplicationCommandAsync(builder.Build());
|
await _client.CreateGlobalApplicationCommandAsync(builder.Build());
|
||||||
|
|
||||||
@@ -148,4 +137,36 @@ public class PluginLoader
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public static async Task LoadPluginFromAssembly(Assembly asmb, DiscordSocketClient client)
|
||||||
|
{
|
||||||
|
var types = asmb.GetTypes();
|
||||||
|
foreach (var type in types)
|
||||||
|
if (type.IsClass && typeof(DBEvent).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
var instance = (DBEvent)Activator.CreateInstance(type);
|
||||||
|
instance.Start(client);
|
||||||
|
PluginLoader.Events.Add(instance);
|
||||||
|
Config.Logger.Log($"[EVENT] Loaded external {type.FullName}!", Others.LogLevel.INFO);
|
||||||
|
}
|
||||||
|
else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
var instance = (DBCommand)Activator.CreateInstance(type);
|
||||||
|
PluginLoader.Commands.Add(instance);
|
||||||
|
Config.Logger.Log($"[CMD] Instance: {type.FullName} loaded !", Others.LogLevel.INFO);
|
||||||
|
}
|
||||||
|
else if (type.IsClass && typeof(DBSlashCommand).IsAssignableFrom(type))
|
||||||
|
{
|
||||||
|
var instance = (DBSlashCommand)Activator.CreateInstance(type);
|
||||||
|
SlashCommandBuilder builder = new SlashCommandBuilder();
|
||||||
|
builder.WithName(instance.Name);
|
||||||
|
builder.WithDescription(instance.Description);
|
||||||
|
builder.WithDMPermission(instance.canUseDM);
|
||||||
|
builder.Options = instance.Options;
|
||||||
|
|
||||||
|
await client.CreateGlobalApplicationCommandAsync(builder.Build());
|
||||||
|
PluginLoader.SlashCommands.Add(instance);
|
||||||
|
Config.Logger.Log($"[SLASH] Instance: {type.FullName} loaded !", Others.LogLevel.INFO);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using System.IO;
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using PluginManager.Others;
|
using PluginManager.Others;
|
||||||
|
|
||||||
namespace PluginManager.Online.Helpers;
|
namespace PluginManager.Online.Helpers;
|
||||||
@@ -40,14 +41,14 @@ internal static class OnlineFunctions
|
|||||||
// Convert absolute progress (bytes downloaded) into relative progress (0% - 100%)
|
// Convert absolute progress (bytes downloaded) into relative progress (0% - 100%)
|
||||||
var relativeProgress = new Progress<long>(totalBytes =>
|
var relativeProgress = new Progress<long>(totalBytes =>
|
||||||
{
|
{
|
||||||
progress.Report((float)totalBytes / contentLength.Value * 100);
|
progress?.Report((float)totalBytes / contentLength.Value * 100);
|
||||||
downloadedBytes?.Report(totalBytes);
|
downloadedBytes?.Report(totalBytes);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Use extension method to report progress while downloading
|
// Use extension method to report progress while downloading
|
||||||
await download.CopyToOtherStreamAsync(destination, bufferSize, relativeProgress, cancellation);
|
await download.CopyToOtherStreamAsync(destination, bufferSize, relativeProgress, cancellation);
|
||||||
progress.Report(1);
|
progress.Report(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,22 +14,25 @@ public class PluginsManager
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Plugin Manager constructor
|
/// The Plugin Manager constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="link">The link to the file where all plugins are stored</param>
|
/// <param name="plink">The link to the file where all plugins are stored</param>
|
||||||
public PluginsManager(string link)
|
/// <param name="vlink">The link to the file where all plugin versions are stored</param>
|
||||||
|
public PluginsManager(string plink, string vlink)
|
||||||
{
|
{
|
||||||
PluginsLink = link;
|
PluginsLink = plink;
|
||||||
|
VersionsLink = vlink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The URL of the server
|
/// The URL of the server
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PluginsLink { get; }
|
public string PluginsLink { get; }
|
||||||
|
public string VersionsLink {get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The method to load all plugins
|
/// The method to load all plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task ListAvailablePlugins()
|
public async Task<List<string[]>> GetAvailablePlugins()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -40,16 +43,12 @@ public class PluginsManager
|
|||||||
var op = Functions.GetOperatingSystem();
|
var op = Functions.GetOperatingSystem();
|
||||||
|
|
||||||
var len = lines.Length;
|
var len = lines.Length;
|
||||||
string[] titles = { "Name", "Description", "Type", "Version" };
|
|
||||||
data.Add(new[] { "-", "-", "-", "-" });
|
|
||||||
data.Add(titles);
|
|
||||||
data.Add(new[] { "-", "-", "-", "-" });
|
|
||||||
for (var i = 0; i < len; i++)
|
for (var i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if (lines[i].Length <= 2)
|
if (lines[i].Length <= 2)
|
||||||
continue;
|
continue;
|
||||||
var content = lines[i].Split(',');
|
var content = lines[i].Split(',');
|
||||||
var display = new string[titles.Length];
|
var display = new string[4]; // 4 columns
|
||||||
if (op == OperatingSystem.WINDOWS)
|
if (op == OperatingSystem.WINDOWS)
|
||||||
{
|
{
|
||||||
if (content[4].Contains("Windows"))
|
if (content[4].Contains("Windows"))
|
||||||
@@ -58,7 +57,7 @@ public class PluginsManager
|
|||||||
display[1] = content[1];
|
display[1] = content[1];
|
||||||
display[2] = content[2];
|
display[2] = content[2];
|
||||||
display[3] =
|
display[3] =
|
||||||
(await ServerCom.GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0"))
|
(await GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0"))
|
||||||
.ToShortString();
|
.ToShortString();
|
||||||
data.Add(display);
|
data.Add(display);
|
||||||
}
|
}
|
||||||
@@ -71,7 +70,7 @@ public class PluginsManager
|
|||||||
display[1] = content[1];
|
display[1] = content[1];
|
||||||
display[2] = content[2];
|
display[2] = content[2];
|
||||||
display[3] =
|
display[3] =
|
||||||
(await ServerCom.GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0"))
|
(await GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0"))
|
||||||
.ToShortString();
|
.ToShortString();
|
||||||
data.Add(display);
|
data.Add(display);
|
||||||
}
|
}
|
||||||
@@ -80,13 +79,33 @@ public class PluginsManager
|
|||||||
|
|
||||||
data.Add(new[] { "-", "-", "-", "-" });
|
data.Add(new[] { "-", "-", "-", "-" });
|
||||||
|
|
||||||
Utilities.FormatAndAlignTable(data, TableFormat.CENTER_EACH_COLUMN_BASED);
|
return data;
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.WriteLine("Failed to execute command: listplugs\nReason: " + exception.Message);
|
Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this, LogLevel.ERROR);
|
||||||
Functions.WriteErrFile(exception.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<VersionString?> GetVersionOfPackageFromWeb(string pakName)
|
||||||
|
{
|
||||||
|
var data = await ServerCom.ReadTextFromURL(VersionsLink);
|
||||||
|
foreach (var item in data)
|
||||||
|
{
|
||||||
|
if (item.StartsWith("#"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
string[] split = item.Split(',');
|
||||||
|
if (split[0] == pakName)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Searched for " + pakName + " and found " + split[1] + " as version.\nUsed url: " + VersionsLink);
|
||||||
|
return new VersionString(split[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -116,8 +135,7 @@ public class PluginsManager
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
Settings.Variables.outputStream.WriteLine("Failed to execute command: listplugs\nReason: " + exception.Message);
|
Config.Logger.Log("Failed to execute command: listplugs\nReason: " + exception.Message, this, LogLevel.ERROR);
|
||||||
Functions.WriteErrFile(exception.ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new string[] { null!, null!, null! };
|
return new string[] { null!, null!, null! };
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
using PluginManager.Online.Helpers;
|
using PluginManager.Online.Helpers;
|
||||||
using PluginManager.Others;
|
using PluginManager.Others;
|
||||||
@@ -33,7 +33,7 @@ public static class ServerCom
|
|||||||
/// <param name="progress">The <see cref="IProgress{T}" /> to track the download</param>
|
/// <param name="progress">The <see cref="IProgress{T}" /> to track the download</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async Task DownloadFileAsync(string URL, string location, IProgress<float> progress,
|
public static async Task DownloadFileAsync(string URL, string location, IProgress<float> progress,
|
||||||
IProgress<long>? downloadedBytes = null)
|
IProgress<long>? downloadedBytes)
|
||||||
{
|
{
|
||||||
using (var client = new HttpClient())
|
using (var client = new HttpClient())
|
||||||
{
|
{
|
||||||
@@ -46,69 +46,8 @@ public static class ServerCom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static async Task DownloadFileAsync(string URl, string location, IProgress<float> progress)
|
||||||
/// Download file from url
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="URL">The url to the file</param>
|
|
||||||
/// <param name="location">The location where to store the downloaded data</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static async Task DownloadFileAsync(string URL, string location)
|
|
||||||
{
|
{
|
||||||
var isDownloading = true;
|
await DownloadFileAsync(URl, location, progress, null);
|
||||||
float c_progress = 0;
|
|
||||||
|
|
||||||
var pbar = new Utilities.ProgressBar(ProgressBarType.NORMAL) { Max = 100f, NoColor = true };
|
|
||||||
|
|
||||||
IProgress<float> progress = new Progress<float>(percent => { c_progress = percent; });
|
|
||||||
|
|
||||||
|
|
||||||
var updateProgressBarTask = new Task(() =>
|
|
||||||
{
|
|
||||||
while (isDownloading)
|
|
||||||
{
|
|
||||||
pbar.Update(c_progress);
|
|
||||||
if (c_progress == 100f)
|
|
||||||
break;
|
|
||||||
Thread.Sleep(500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
new Thread(updateProgressBarTask.Start).Start();
|
|
||||||
await DownloadFileAsync(URL, location, progress);
|
|
||||||
|
|
||||||
|
|
||||||
c_progress = pbar.Max;
|
|
||||||
pbar.Update(100f);
|
|
||||||
isDownloading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task DownloadFileNoProgressAsync(string URL, string location)
|
|
||||||
{
|
|
||||||
IProgress<float> progress = new Progress<float>();
|
|
||||||
await DownloadFileAsync(URL, location, progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static VersionString? GetVersionOfPackage(string pakName)
|
|
||||||
{
|
|
||||||
if (Config.Plugins.GetVersion(pakName) is null)
|
|
||||||
return null;
|
|
||||||
return new VersionString(Config.Plugins.GetVersion(pakName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<VersionString?> GetVersionOfPackageFromWeb(string pakName)
|
|
||||||
{
|
|
||||||
var url = "https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/Versions";
|
|
||||||
var data = await ReadTextFromURL(url);
|
|
||||||
foreach (var item in data)
|
|
||||||
{
|
|
||||||
if (item.StartsWith("#"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
string[] split = item.Split(',');
|
|
||||||
if (split[0] == pakName)
|
|
||||||
return new VersionString(split[1]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using PluginManager.Items;
|
|
||||||
using PluginManager.Others;
|
|
||||||
|
|
||||||
namespace PluginManager.Online.Updates;
|
|
||||||
|
|
||||||
public class PluginUpdater
|
|
||||||
{
|
|
||||||
public static async Task<bool> CheckForUpdates(string pakName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var webV = await ServerCom.GetVersionOfPackageFromWeb(pakName);
|
|
||||||
var local = ServerCom.GetVersionOfPackage(pakName);
|
|
||||||
|
|
||||||
if (local is null) return true;
|
|
||||||
if (webV is null) return false;
|
|
||||||
|
|
||||||
if (webV == local) return false;
|
|
||||||
if (webV > local) return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<Update> DownloadUpdateInfo(string pakName)
|
|
||||||
{
|
|
||||||
var url = "https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/Versions";
|
|
||||||
var info = await ServerCom.ReadTextFromURL(url);
|
|
||||||
var version = await ServerCom.GetVersionOfPackageFromWeb(pakName);
|
|
||||||
|
|
||||||
if (version is null) return Update.Empty;
|
|
||||||
var update = new Update(pakName, string.Join('\n', info), version);
|
|
||||||
return update;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task Download(string pakName)
|
|
||||||
{
|
|
||||||
Utilities.WriteColorText("An update was found for &g" + pakName + "&c. Version: &r" +
|
|
||||||
(await ServerCom.GetVersionOfPackageFromWeb(pakName))?.ToShortString() +
|
|
||||||
"&c. Current Version: &y" +
|
|
||||||
ServerCom.GetVersionOfPackage(pakName)?.ToShortString());
|
|
||||||
await ConsoleCommandsHandler.ExecuteCommad("dwplug " + pakName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
using System;
|
|
||||||
using PluginManager.Online.Helpers;
|
|
||||||
|
|
||||||
namespace PluginManager.Online.Updates;
|
|
||||||
|
|
||||||
public class Update
|
|
||||||
{
|
|
||||||
public static Update Empty = new(null, null, null);
|
|
||||||
|
|
||||||
private readonly bool isEmpty;
|
|
||||||
|
|
||||||
public VersionString newVersion;
|
|
||||||
public string pakName;
|
|
||||||
public string UpdateMessage;
|
|
||||||
|
|
||||||
public Update(string pakName, string updateMessage, VersionString newVersion)
|
|
||||||
{
|
|
||||||
this.pakName = pakName;
|
|
||||||
UpdateMessage = updateMessage;
|
|
||||||
this.newVersion = newVersion;
|
|
||||||
|
|
||||||
if (pakName is null && updateMessage is null && newVersion is null)
|
|
||||||
isEmpty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
if (isEmpty)
|
|
||||||
throw new Exception("The update is EMPTY. Can not print information about an empty update !");
|
|
||||||
return $"Package Name: {pakName}\n" +
|
|
||||||
$"Update Message: {UpdateMessage}\n" +
|
|
||||||
$"Version: {newVersion}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
51
PluginManager/Others/Actions/ActionManager.cs
Normal file
51
PluginManager/Others/Actions/ActionManager.cs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Actions
|
||||||
|
{
|
||||||
|
public class ActionManager
|
||||||
|
{
|
||||||
|
public List<InternalAction> Actions { get; private set; }
|
||||||
|
|
||||||
|
private bool _isInitialized = false;
|
||||||
|
|
||||||
|
public ActionManager()
|
||||||
|
{
|
||||||
|
if(_isInitialized) return;
|
||||||
|
|
||||||
|
Actions = new List<InternalAction>();
|
||||||
|
|
||||||
|
_isInitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ActionExists(string name)
|
||||||
|
{
|
||||||
|
if(!_isInitialized) throw new Exception("ActionManager is not initialized");
|
||||||
|
return Actions.Any(x => x.Name == name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAction(InternalAction action)
|
||||||
|
{
|
||||||
|
if(!_isInitialized) throw new Exception("ActionManager is not initialized");
|
||||||
|
Actions.Add(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ExecuteAction(string name, string[] args)
|
||||||
|
{
|
||||||
|
if(!_isInitialized) throw new Exception("ActionManager is not initialized");
|
||||||
|
var action = Actions.FirstOrDefault(x => x.Name == name);
|
||||||
|
if(action == null) throw new Exception($"Action {name} not found");
|
||||||
|
action.Invoke(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecuteActionAsync(string name, string[] args)
|
||||||
|
{
|
||||||
|
if(!_isInitialized) throw new Exception("ActionManager is not initialized");
|
||||||
|
var action = Actions.FirstOrDefault(x => x.Name == name);
|
||||||
|
if(action == null) throw new Exception($"Action {name} not found");
|
||||||
|
await action.InvokeAsync(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
PluginManager/Others/Actions/InternalAction.cs
Normal file
40
PluginManager/Others/Actions/InternalAction.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Actions
|
||||||
|
{
|
||||||
|
public class InternalAction
|
||||||
|
{
|
||||||
|
public string? Name { get; init; }
|
||||||
|
public Action<string[]> Action { get; init; }
|
||||||
|
|
||||||
|
public InternalAction(string name, Action<string[]> action)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InternalAction(string name, Action action)
|
||||||
|
{
|
||||||
|
Name = name;
|
||||||
|
Action = (o) =>
|
||||||
|
{
|
||||||
|
action();
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Invoke(string[] args)
|
||||||
|
{
|
||||||
|
Action(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(string[] args)
|
||||||
|
{
|
||||||
|
await Task.Run(() => Action(args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
141
PluginManager/Others/ArchiveManager.cs
Normal file
141
PluginManager/Others/ArchiveManager.cs
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PluginManager.Others
|
||||||
|
{
|
||||||
|
public static class ArchiveManager
|
||||||
|
{
|
||||||
|
public static bool isInitialized { get; private set; }
|
||||||
|
private static string? archiveFolder;
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
if (isInitialized) throw new Exception("ArchiveManager is already initialized");
|
||||||
|
|
||||||
|
if (!Config.Data.ContainsKey("ArchiveFolder"))
|
||||||
|
Config.Data["ArchiveFolder"] = "./Data/PAKS/";
|
||||||
|
|
||||||
|
archiveFolder = Config.Data["ArchiveFolder"];
|
||||||
|
|
||||||
|
isInitialized = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Read data from a file that is inside an archive (ZIP format)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FileName">The file name that is inside the archive or its full path</param>
|
||||||
|
/// <param name="archFile">The archive location from the PAKs folder</param>
|
||||||
|
/// <returns>A string that represents the content of the file or null if the file does not exists or it has no content</returns>
|
||||||
|
public static async Task<string?> ReadFromPakAsync(string FileName, string archFile)
|
||||||
|
{
|
||||||
|
if (!isInitialized) throw new Exception("ArchiveManager is not initialized");
|
||||||
|
archFile = archiveFolder + archFile;
|
||||||
|
if (!File.Exists(archFile))
|
||||||
|
throw new Exception("Failed to load file !");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string? textValue = null;
|
||||||
|
using (var fs = new FileStream(archFile, FileMode.Open))
|
||||||
|
using (var zip = new ZipArchive(fs, ZipArchiveMode.Read))
|
||||||
|
{
|
||||||
|
foreach (var entry in zip.Entries)
|
||||||
|
if (entry.Name == FileName || entry.FullName == FileName)
|
||||||
|
using (var s = entry.Open())
|
||||||
|
using (var reader = new StreamReader(s))
|
||||||
|
{
|
||||||
|
textValue = await reader.ReadToEndAsync();
|
||||||
|
reader.Close();
|
||||||
|
s.Close();
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return textValue;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Config.Logger.Log(ex.Message, "Archive Manager", LogLevel.ERROR); // Write the error to a file
|
||||||
|
await Task.Delay(100);
|
||||||
|
return await ReadFromPakAsync(FileName, archFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extract zip to location
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="zip">The zip location</param>
|
||||||
|
/// <param name="folder">The target location</param>
|
||||||
|
/// <param name="progress">The progress that is updated as a file is processed</param>
|
||||||
|
/// <param name="type">The type of progress</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task ExtractArchive(string zip, string folder, IProgress<float> progress,
|
||||||
|
UnzipProgressType type)
|
||||||
|
{
|
||||||
|
if (!isInitialized) throw new Exception("ArchiveManager is not initialized");
|
||||||
|
Directory.CreateDirectory(folder);
|
||||||
|
using (var archive = ZipFile.OpenRead(zip))
|
||||||
|
{
|
||||||
|
if (type == UnzipProgressType.PERCENTAGE_FROM_NUMBER_OF_FILES)
|
||||||
|
{
|
||||||
|
var totalZIPFiles = archive.Entries.Count();
|
||||||
|
var currentZIPFile = 0;
|
||||||
|
foreach (var entry in archive.Entries)
|
||||||
|
{
|
||||||
|
if (entry.FullName.EndsWith("/")) // it is a folder
|
||||||
|
Directory.CreateDirectory(Path.Combine(folder, entry.FullName));
|
||||||
|
|
||||||
|
else
|
||||||
|
try
|
||||||
|
{
|
||||||
|
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}", "Archive Manager", LogLevel.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentZIPFile++;
|
||||||
|
await Task.Delay(10);
|
||||||
|
if (progress != null)
|
||||||
|
progress.Report((float)currentZIPFile / totalZIPFiles * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == UnzipProgressType.PERCENTAGE_FROM_TOTAL_SIZE)
|
||||||
|
{
|
||||||
|
ulong zipSize = 0;
|
||||||
|
|
||||||
|
foreach (var entry in archive.Entries)
|
||||||
|
zipSize += (ulong)entry.CompressedLength;
|
||||||
|
|
||||||
|
ulong currentSize = 0;
|
||||||
|
foreach (var entry in archive.Entries)
|
||||||
|
{
|
||||||
|
if (entry.FullName.EndsWith("/"))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.Combine(folder, entry.FullName));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
|
||||||
|
currentSize += (ulong)entry.CompressedLength;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Config.Logger.Log($"Failed to extract {entry.Name}. Exception: {ex.Message}", "Archive Manager", LogLevel.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Task.Delay(10);
|
||||||
|
if (progress != null)
|
||||||
|
progress.Report((float)currentSize / zipSize * 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
using System.Threading.Tasks;
|
|
||||||
using Discord;
|
|
||||||
|
|
||||||
namespace PluginManager.Others;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A class that handles the sending of messages to the user.
|
|
||||||
/// </summary>
|
|
||||||
public static class ChannelManagement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get the text channel by name from server
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="server">The server</param>
|
|
||||||
/// <param name="name">The channel name</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="IGuildChannel" />
|
|
||||||
/// </returns>
|
|
||||||
public static IGuildChannel GetTextChannel(this IGuild server, string name)
|
|
||||||
{
|
|
||||||
return server.GetTextChannel(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the voice channel by name from server
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="server">The server</param>
|
|
||||||
/// <param name="name">The channel name</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="IGuildChannel" />
|
|
||||||
/// </returns>
|
|
||||||
public static IGuildChannel GetVoiceChannel(this IGuild server, string name)
|
|
||||||
{
|
|
||||||
return server.GetVoiceChannel(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the DM channel between <see cref="Discord.WebSocket.DiscordSocketClient" /> and <see cref="IGuildUser" />
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user"></param>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="IDMChannel" />
|
|
||||||
/// </returns>
|
|
||||||
public static async Task<IDMChannel> GetDMChannel(IGuildUser user)
|
|
||||||
{
|
|
||||||
return await user.CreateDMChannelAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get the channel where the message was sent
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="message">The message</param>
|
|
||||||
/// <returns>
|
|
||||||
/// <see cref="IChannel" />
|
|
||||||
/// </returns>
|
|
||||||
public static IChannel GetChannel(IMessage message)
|
|
||||||
{
|
|
||||||
return message.Channel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
27
PluginManager/Others/DBCommandExecutingArguments.cs
Normal file
27
PluginManager/Others/DBCommandExecutingArguments.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using Discord.Commands;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PluginManager.Others
|
||||||
|
{
|
||||||
|
public class DBCommandExecutingArguments
|
||||||
|
{
|
||||||
|
public SocketCommandContext context { get; init; }
|
||||||
|
public string cleanContent { get; init; }
|
||||||
|
public string commandUsed { get;init; }
|
||||||
|
public string[] arguments { get;init; }
|
||||||
|
|
||||||
|
public DBCommandExecutingArguments(SocketCommandContext context, string cleanContent, string commandUsed, string[] arguments)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
this.cleanContent = cleanContent;
|
||||||
|
this.commandUsed = commandUsed;
|
||||||
|
this.arguments = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,23 +11,10 @@ public enum OperatingSystem
|
|||||||
UNKNOWN
|
UNKNOWN
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A list with all errors
|
|
||||||
/// </summary>
|
|
||||||
public enum Error
|
|
||||||
{
|
|
||||||
UNKNOWN_ERROR,
|
|
||||||
GUILD_NOT_FOUND,
|
|
||||||
STREAM_NOT_FOUND,
|
|
||||||
INVALID_USER,
|
|
||||||
INVALID_CHANNEL,
|
|
||||||
INVALID_PERMISSIONS
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The output log type
|
/// The output log type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum OutputLogLevel
|
public enum LogLevel
|
||||||
{
|
{
|
||||||
NONE,
|
NONE,
|
||||||
INFO,
|
INFO,
|
||||||
@@ -38,15 +25,8 @@ public enum OutputLogLevel
|
|||||||
|
|
||||||
public enum UnzipProgressType
|
public enum UnzipProgressType
|
||||||
{
|
{
|
||||||
PercentageFromNumberOfFiles,
|
PERCENTAGE_FROM_NUMBER_OF_FILES,
|
||||||
PercentageFromTotalSize
|
PERCENTAGE_FROM_TOTAL_SIZE
|
||||||
}
|
|
||||||
|
|
||||||
public enum TableFormat
|
|
||||||
{
|
|
||||||
CENTER_EACH_COLUMN_BASED,
|
|
||||||
CENTER_OVERALL_LENGTH,
|
|
||||||
DEFAULT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SaveType
|
public enum SaveType
|
||||||
@@ -55,8 +35,3 @@ public enum SaveType
|
|||||||
BACKUP
|
BACKUP
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ProgressBarType
|
|
||||||
{
|
|
||||||
NORMAL,
|
|
||||||
NO_END
|
|
||||||
}
|
|
||||||
@@ -1,19 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Discord.WebSocket;
|
|
||||||
|
|
||||||
using PluginManager.Items;
|
|
||||||
|
|
||||||
namespace PluginManager.Others;
|
namespace PluginManager.Others;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -26,95 +18,6 @@ public static class Functions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string dataFolder = @"./Data/Resources/";
|
public static readonly string dataFolder = @"./Data/Resources/";
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The location for all logs
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string logFolder = @"./Data/Output/Logs/";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The location for all errors
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string errFolder = @"./Data/Output/Errors/";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Archives folder
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string pakFolder = @"./Data/PAKS/";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Beta testing folder
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string betaFolder = @"./Data/BetaTest/";
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read data from a file that is inside an archive (ZIP format)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FileName">The file name that is inside the archive or its full path</param>
|
|
||||||
/// <param name="archFile">The archive location from the PAKs folder</param>
|
|
||||||
/// <returns>A string that represents the content of the file or null if the file does not exists or it has no content</returns>
|
|
||||||
public static async Task<string> ReadFromPakAsync(string FileName, string archFile)
|
|
||||||
{
|
|
||||||
archFile = pakFolder + archFile;
|
|
||||||
if (!File.Exists(archFile))
|
|
||||||
throw new Exception("Failed to load file !");
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string textValue = null;
|
|
||||||
using (var fs = new FileStream(archFile, FileMode.Open))
|
|
||||||
using (var zip = new ZipArchive(fs, ZipArchiveMode.Read))
|
|
||||||
{
|
|
||||||
foreach (var entry in zip.Entries)
|
|
||||||
if (entry.Name == FileName || entry.FullName == FileName)
|
|
||||||
using (var s = entry.Open())
|
|
||||||
using (var reader = new StreamReader(s))
|
|
||||||
{
|
|
||||||
textValue = await reader.ReadToEndAsync();
|
|
||||||
reader.Close();
|
|
||||||
s.Close();
|
|
||||||
fs.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return textValue;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
await Task.Delay(100);
|
|
||||||
return await ReadFromPakAsync(FileName, archFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Write logs to file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="LogMessage">The message to be wrote</param>
|
|
||||||
public static void WriteLogFile(string LogMessage)
|
|
||||||
{
|
|
||||||
var logsPath = logFolder + $"{DateTime.Today.ToShortDateString().Replace("/", "-").Replace("\\", "-")} Log.txt";
|
|
||||||
Directory.CreateDirectory(logFolder);
|
|
||||||
File.AppendAllText(logsPath, LogMessage + " \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Write error to file
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ErrMessage">The message to be wrote</param>
|
|
||||||
public static void WriteErrFile(string ErrMessage)
|
|
||||||
{
|
|
||||||
var errPath = errFolder +
|
|
||||||
$"{DateTime.Today.ToShortDateString().Replace("/", "-").Replace("\\", "-")} Error.txt";
|
|
||||||
Directory.CreateDirectory(errFolder);
|
|
||||||
File.AppendAllText(errPath, ErrMessage + " \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void WriteErrFile(this Exception ex)
|
|
||||||
{
|
|
||||||
WriteErrFile(ex.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the Operating system you are runnin on
|
/// Get the Operating system you are runnin on
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -127,12 +30,6 @@ public static class Functions
|
|||||||
return OperatingSystem.UNKNOWN;
|
return OperatingSystem.UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> GetArguments(SocketMessage message)
|
|
||||||
{
|
|
||||||
var command = new Command(message);
|
|
||||||
return command.Arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copy one Stream to another <see langword="async" />
|
/// Copy one Stream to another <see langword="async" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -167,79 +64,6 @@ public static class Functions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extract zip to location
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="zip">The zip location</param>
|
|
||||||
/// <param name="folder">The target location</param>
|
|
||||||
/// <param name="progress">The progress that is updated as a file is processed</param>
|
|
||||||
/// <param name="type">The type of progress</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static async Task ExtractArchive(string zip, string folder, IProgress<float> progress,
|
|
||||||
UnzipProgressType type)
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(folder);
|
|
||||||
using (var archive = ZipFile.OpenRead(zip))
|
|
||||||
{
|
|
||||||
if (type == UnzipProgressType.PercentageFromNumberOfFiles)
|
|
||||||
{
|
|
||||||
var totalZIPFiles = archive.Entries.Count();
|
|
||||||
var currentZIPFile = 0;
|
|
||||||
foreach (var entry in archive.Entries)
|
|
||||||
{
|
|
||||||
if (entry.FullName.EndsWith("/")) // it is a folder
|
|
||||||
Directory.CreateDirectory(Path.Combine(folder, entry.FullName));
|
|
||||||
|
|
||||||
else
|
|
||||||
try
|
|
||||||
{
|
|
||||||
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
currentZIPFile++;
|
|
||||||
await Task.Delay(10);
|
|
||||||
if (progress != null)
|
|
||||||
progress.Report((float)currentZIPFile / totalZIPFiles * 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (type == UnzipProgressType.PercentageFromTotalSize)
|
|
||||||
{
|
|
||||||
ulong zipSize = 0;
|
|
||||||
|
|
||||||
foreach (var entry in archive.Entries)
|
|
||||||
zipSize += (ulong)entry.CompressedLength;
|
|
||||||
|
|
||||||
ulong currentSize = 0;
|
|
||||||
foreach (var entry in archive.Entries)
|
|
||||||
{
|
|
||||||
if (entry.FullName.EndsWith("/"))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.Combine(folder, entry.FullName));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
|
|
||||||
currentSize += (ulong)entry.CompressedLength;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Settings.Variables.outputStream.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}");
|
|
||||||
}
|
|
||||||
|
|
||||||
await Task.Delay(10);
|
|
||||||
if (progress != null)
|
|
||||||
progress.Report((float)currentSize / zipSize * 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save to JSON file
|
/// Save to JSON file
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -252,6 +76,8 @@ public static class Functions
|
|||||||
var str = new MemoryStream();
|
var str = new MemoryStream();
|
||||||
await JsonSerializer.SerializeAsync(str, Data, typeof(T), new JsonSerializerOptions { WriteIndented = true });
|
await JsonSerializer.SerializeAsync(str, Data, typeof(T), new JsonSerializerOptions { WriteIndented = true });
|
||||||
await File.WriteAllBytesAsync(file, str.ToArray());
|
await File.WriteAllBytesAsync(file, str.ToArray());
|
||||||
|
await str.FlushAsync();
|
||||||
|
str.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -262,6 +88,7 @@ public static class Functions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static async Task<T> ConvertFromJson<T>(string input)
|
public static async Task<T> ConvertFromJson<T>(string input)
|
||||||
{
|
{
|
||||||
|
Console.WriteLine(input);
|
||||||
Stream text;
|
Stream text;
|
||||||
if (File.Exists(input))
|
if (File.Exists(input))
|
||||||
text = new MemoryStream(await File.ReadAllBytesAsync(input));
|
text = new MemoryStream(await File.ReadAllBytesAsync(input));
|
||||||
@@ -269,32 +96,8 @@ public static class Functions
|
|||||||
text = new MemoryStream(Encoding.ASCII.GetBytes(input));
|
text = new MemoryStream(Encoding.ASCII.GetBytes(input));
|
||||||
text.Position = 0;
|
text.Position = 0;
|
||||||
var obj = await JsonSerializer.DeserializeAsync<T>(text);
|
var obj = await JsonSerializer.DeserializeAsync<T>(text);
|
||||||
|
await text.FlushAsync();
|
||||||
text.Close();
|
text.Close();
|
||||||
return (obj ?? default)!;
|
return (obj ?? default)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool TryReadValueFromJson(string input, string codeName, out JsonElement element)
|
|
||||||
{
|
|
||||||
Stream text;
|
|
||||||
if (File.Exists(input))
|
|
||||||
text = File.OpenRead(input);
|
|
||||||
|
|
||||||
else
|
|
||||||
text = new MemoryStream(Encoding.ASCII.GetBytes(input));
|
|
||||||
|
|
||||||
var jsonObject = JsonDocument.Parse(text);
|
|
||||||
|
|
||||||
var data = jsonObject.RootElement.TryGetProperty(codeName, out element);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string CreateMD5(string input)
|
|
||||||
{
|
|
||||||
using (var md5 = MD5.Create())
|
|
||||||
{
|
|
||||||
var inputBytes = Encoding.ASCII.GetBytes(input);
|
|
||||||
var hashBytes = md5.ComputeHash(inputBytes);
|
|
||||||
return Convert.ToHexString(hashBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
52
PluginManager/Others/Logger/DBLogger.cs
Normal file
52
PluginManager/Others/Logger/DBLogger.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Logger
|
||||||
|
{
|
||||||
|
public class DBLogger
|
||||||
|
{
|
||||||
|
|
||||||
|
private List<LogMessage> LogHistory = new List<LogMessage>();
|
||||||
|
private List<LogMessage> ErrorHistory = new List<LogMessage>();
|
||||||
|
|
||||||
|
public IReadOnlyList<LogMessage> Logs => LogHistory;
|
||||||
|
public IReadOnlyList<LogMessage> Errors => ErrorHistory;
|
||||||
|
|
||||||
|
public delegate void LogHandler(string message, LogLevel logType);
|
||||||
|
public event LogHandler LogEvent;
|
||||||
|
|
||||||
|
private string _logFolder;
|
||||||
|
private string _errFolder;
|
||||||
|
|
||||||
|
public DBLogger()
|
||||||
|
{
|
||||||
|
_logFolder = Config.Data["LogFolder"];
|
||||||
|
_errFolder = Config.Data["ErrorFolder"];
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(string message, string sender = "unknown", LogLevel type = LogLevel.INFO) => Log(new LogMessage(message, type, sender));
|
||||||
|
|
||||||
|
public void Log(LogMessage message)
|
||||||
|
{
|
||||||
|
if(LogEvent is not null)
|
||||||
|
LogEvent?.Invoke(message.Message, message.Type);
|
||||||
|
|
||||||
|
if (message.Type != LogLevel.NONE)
|
||||||
|
LogHistory.Add(message);
|
||||||
|
else
|
||||||
|
ErrorHistory.Add(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Log(string message, object sender, LogLevel type = LogLevel.NONE) => Log(message, sender.GetType().Name, type);
|
||||||
|
|
||||||
|
public async void SaveToFile()
|
||||||
|
{
|
||||||
|
await Functions.SaveToJsonFile(_logFolder + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".json", LogHistory);
|
||||||
|
await Functions.SaveToJsonFile(_errFolder + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".json", ErrorHistory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
PluginManager/Others/Logger/LogMessage.cs
Normal file
47
PluginManager/Others/Logger/LogMessage.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PluginManager.Others.Logger
|
||||||
|
{
|
||||||
|
public class LogMessage
|
||||||
|
{
|
||||||
|
public string Message { get; set; }
|
||||||
|
public LogLevel Type { get; set; }
|
||||||
|
public string Time { get; set; }
|
||||||
|
public string Sender { get; set; }
|
||||||
|
public LogMessage(string message, LogLevel type)
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
Type = type;
|
||||||
|
Time = DateTime.Now.ToString("HH:mm:ss");
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogMessage(string message, LogLevel type, string sender) : this(message, type)
|
||||||
|
{
|
||||||
|
Sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"[{Time}] {Message}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator LogMessage(string message)
|
||||||
|
{
|
||||||
|
return new LogMessage(message, LogLevel.INFO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator LogMessage((string message, LogLevel type) tuple)
|
||||||
|
{
|
||||||
|
return new LogMessage(tuple.message, tuple.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator LogMessage((string message, LogLevel type, string sender) tuple)
|
||||||
|
{
|
||||||
|
return new LogMessage(tuple.message, tuple.type, tuple.sender);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using Discord;
|
using Discord;
|
||||||
using Discord.WebSocket;
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<DebugType>none</DebugType>
|
<DebugType>none</DebugType>
|
||||||
<DebugSymbols>false</DebugSymbols>
|
<DebugSymbols>false</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="BlankWindow1.xaml" />
|
<None Remove="BlankWindow1.xaml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Discord.Net" Version="3.7.2" />
|
<PackageReference Include="Discord.Net" Version="3.8.1" />
|
||||||
<PackageReference Include="System.Data.SQLite" Version="1.0.116" />
|
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.117" />
|
||||||
<PackageReference Include="Terminal.Gui" Version="1.8.2" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using System.IO;
|
|
||||||
|
|
||||||
using PluginManager.Database;
|
|
||||||
|
|
||||||
namespace PluginManager
|
|
||||||
{
|
|
||||||
public class Settings
|
|
||||||
{
|
|
||||||
|
|
||||||
public static class Variables
|
|
||||||
{
|
|
||||||
public static string WebsiteURL = "https://wizzy69.github.io/SethDiscordBot";
|
|
||||||
public static string UpdaterURL = "https://github.com/Wizzy69/installer/releases/download/release-1-discordbot/Updater.zip";
|
|
||||||
|
|
||||||
public static TextWriter outputStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SqlDatabase sqlDatabase;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
156
README.md
156
README.md
@@ -15,84 +15,87 @@ This project is based on:
|
|||||||
Plugin Types:
|
Plugin Types:
|
||||||
1. Commands
|
1. Commands
|
||||||
2. Events
|
2. Events
|
||||||
|
3. Slash Commands
|
||||||
|
|
||||||
### How to create a plugin
|
### How to create a plugin
|
||||||
|
|
||||||
First of all, Create a new project (class library) in Visual Studio.
|
First of all, create a new project (class library) in Visual Studio.
|
||||||

|
Then import the PluginManager as reference to your project.
|
||||||
|
|
||||||

|
## 1. Commands
|
||||||
|
|
||||||

|
Commands are loaded when all plugins are loaded into memory. The Execute method is called whenever any user (that respects the `requireAdmin` propery) calls the command using the bot prefix and the `Command`.
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
Now, let's add the PluginManager reference. It can be found inside the bot's main folder under
|
|
||||||
`DiscordBot/bin/Debug/net6.0/PluginManager.dll` or `PluginManager/bin/Debug/net6.0/PluginManager.dll`
|
|
||||||
after one successfull build.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
1. Commands
|
|
||||||
|
|
||||||
Commands are loaded when all plugins are loaded into memory. When an user executes the command, only then the Execute function is called.
|
|
||||||
Commands are plugins that allow users to interact with them.
|
Commands are plugins that allow users to interact with them.
|
||||||
Here is an example of class that is a command class
|
Here is an example:
|
||||||
```cs
|
```cs
|
||||||
|
using Discord;
|
||||||
using Discord.Commands;
|
using Discord.Commands;
|
||||||
using Discord.WebSocket;
|
|
||||||
|
|
||||||
using PluginManager.Interfaces;
|
using PluginManager.Interfaces;
|
||||||
|
|
||||||
namespace CMD_Utils
|
namespace LevelingSystem;
|
||||||
|
|
||||||
|
internal class LevelCommand : DBCommand
|
||||||
{
|
{
|
||||||
class FlipCoin : DBCommand
|
public string Command => "level";
|
||||||
{
|
|
||||||
public string Command => "flip";
|
|
||||||
|
|
||||||
public string Description => "Flip a coin";
|
public List<string> Aliases => new() { "lvl" };
|
||||||
|
|
||||||
public string Usage => "flip";
|
public string Description => "Display your current level";
|
||||||
|
|
||||||
public bool canUseDM => true;
|
public string Usage => "level";
|
||||||
|
|
||||||
public bool canUseServer => true;
|
|
||||||
|
|
||||||
public bool requireAdmin => false;
|
public bool requireAdmin => false;
|
||||||
|
|
||||||
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
|
public async void ExecuteServer(CmdArgs context)
|
||||||
{
|
{
|
||||||
System.Random random = new System.Random();
|
//Variables.database is a sql connection that is defined in an auxiliary file in the same napespace as this class
|
||||||
int r = random.Next(1, 3);
|
object[] user = await Variables.database.ReadDataArrayAsync($"SELECT * FROM Levels WHERE UserID='{context.Message.Author.Id}'");
|
||||||
if (r == 1)
|
if (user is null)
|
||||||
await message.Channel.SendMessageAsync("Heads");
|
{
|
||||||
else await message.Channel.SendMessageAsync("Tails");
|
await context.Channel.SendMessageAsync("You are now unranked !");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int level = (int)user[1];
|
||||||
|
int exp = (int)user[2];
|
||||||
|
|
||||||
|
var builder = new EmbedBuilder();
|
||||||
|
var r = new Random();
|
||||||
|
builder.WithColor(r.Next(256), r.Next(256), r.Next(256));
|
||||||
|
builder.AddField("Current Level", level, true)
|
||||||
|
.AddField("Current EXP", exp, true)
|
||||||
|
.AddField("Required Exp", (level * 8 + 24).ToString(), true);
|
||||||
|
builder.WithTimestamp(DateTimeOffset.Now);
|
||||||
|
builder.WithAuthor(context.Message.Author.Mention);
|
||||||
|
await context.Channel.SendMessageAsync(embed: builder.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Optional method (tell the bot what should it do if the command is executed from a DM channel)
|
||||||
|
//public async void ExecuteDM(CmdArgs context) {
|
||||||
|
//
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
#### Code description:
|
#### Code description:
|
||||||
- Command - The keyword that triggers the execution for the command. This is what players must type in order to execute your command
|
- Command - The keyword that triggers the execution for the command. This is what players must type in order to execute your command
|
||||||
|
- Aliases - The aliases that can be used instead of the full name to execute the command
|
||||||
- Description - The description of your command. Can be anything you like
|
- Description - The description of your command. Can be anything you like
|
||||||
- Usage - The usage of your command. This is what `help [Command]` command will display
|
- Usage - The usage of your command. This is what `help [Command]` command will display
|
||||||
- canUseDM - true if you plan to let users execute this command in DM chat with bot
|
|
||||||
- canUseServer - true if you plan to let the users execute this command in a server chat
|
|
||||||
- requireAdmin - true if this command requres an user with Administrator permission in the server
|
- requireAdmin - true if this command requres an user with Administrator permission in the server
|
||||||
- Execute () - the function of your command.
|
- ExecuteServer () - the function that is executed only when the command is invoked in a server channel. (optional)
|
||||||
|
- context - the command context
|
||||||
|
- ExecuteDM () - the function that is executed only when the command is invoked in a private (DM) channel. (optional)
|
||||||
- context - the command context
|
- context - the command context
|
||||||
- message - the message itself
|
|
||||||
- client - the discord bot client
|
|
||||||
- isDM - true if the message was sent from DM chat
|
|
||||||
|
|
||||||
From here on, start coding. When your plugin is done, build it as any DLL project then add it to the following path
|
From here on, start coding. When your plugin is done, build it as any DLL project then add it to the following path
|
||||||
`{bot_executable}/Data/Plugins/Commands/<optional subfolder>/yourDLLName.dll`
|
`{bot_executable}/Data/Plugins/<optional subfolder>/[plugin name].dll`
|
||||||
Then, reload bot and execute command `lp` in bot's console. The plugin should be loaded into memory or an error is thrown if not. If an error is thrown, then
|
Then, reload bot and execute command `lp` in bot's console. The plugin should be loaded into memory or an error is thrown if not. If an error is thrown, then
|
||||||
there is something wrong in your command's code.
|
there is something wrong in your command's code.
|
||||||
|
|
||||||
2. Events
|
## 2. Events
|
||||||
|
|
||||||
Events are loaded when all plugins are loaded. At the moment when they are loaded, the Start function is called.
|
Events are loaded when all plugins are loaded. At the moment when they are loaded, the Start function is called.
|
||||||
Events are used if you want the bot to do something when something happens in server. The following example shows you how to catch when a user joins the server
|
Events are used if you want the bot to do something when something happens in server. The following example shows you how to catch when a user joins the server
|
||||||
@@ -110,8 +113,6 @@ public class OnUserJoin : DBEvent
|
|||||||
|
|
||||||
public async void Start(Discord.WebSocket.DiscordSocketClient client)
|
public async void Start(Discord.WebSocket.DiscordSocketClient client)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Hello World from {name}");
|
|
||||||
|
|
||||||
client.UserJoined += async (user) => {
|
client.UserJoined += async (user) => {
|
||||||
await (await user.CreateDMChannelAsync()).SendMessageAsync("Welcome to server !");
|
await (await user.CreateDMChannelAsync()).SendMessageAsync("Welcome to server !");
|
||||||
};
|
};
|
||||||
@@ -125,3 +126,68 @@ public class OnUserJoin : DBEvent
|
|||||||
- Start() - The main body of your event. This is executed when the bot loads all plugins
|
- Start() - The main body of your event. This is executed when the bot loads all plugins
|
||||||
- client - the discord bot client
|
- client - the discord bot client
|
||||||
|
|
||||||
|
|
||||||
|
## 3. Slash Commands
|
||||||
|
|
||||||
|
|
||||||
|
Slash commands are server based commands. They work the same way as normal commands, but they require the `/` prefix as they are integrated
|
||||||
|
with the UI of Discord.
|
||||||
|
Here is an example:
|
||||||
|
```cs
|
||||||
|
using Discord;
|
||||||
|
using Discord.WebSocket;
|
||||||
|
|
||||||
|
using PluginManager.Interfaces;
|
||||||
|
|
||||||
|
namespace SlashCommands
|
||||||
|
{
|
||||||
|
public class Random : DBSlashCommand
|
||||||
|
{
|
||||||
|
public string Name => "random";
|
||||||
|
|
||||||
|
public string Description => "Generates a random nunber between 2 values";
|
||||||
|
|
||||||
|
public bool canUseDM => true;
|
||||||
|
|
||||||
|
public List<SlashCommandOptionBuilder> Options => new List<SlashCommandOptionBuilder>()
|
||||||
|
{
|
||||||
|
new SlashCommandOptionBuilder() {Name = "min-value", Description = "Minimum value", IsRequired=true, Type = ApplicationCommandOptionType.Integer, MinValue = 0, MaxValue = int.MaxValue-1},
|
||||||
|
new SlashCommandOptionBuilder() {Name = "max-value", Description = "Maximum value", IsRequired=true, Type=ApplicationCommandOptionType.Integer,MinValue = 0, MaxValue = int.MaxValue-1}
|
||||||
|
};
|
||||||
|
|
||||||
|
public async void ExecuteServer(SocketSlashCommand command)
|
||||||
|
{
|
||||||
|
var rnd = new System.Random();
|
||||||
|
var options = command.Data.Options.ToArray();
|
||||||
|
if (options.Count() != 2)
|
||||||
|
{
|
||||||
|
await command.RespondAsync("Invalid parameters", ephemeral: true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Int64 numberOne = (Int64)options[0].Value;
|
||||||
|
Int64 numberTwo = (Int64)options[1].Value;
|
||||||
|
|
||||||
|
await command.RespondAsync("Your generated number is " + rnd.Next((int)numberOne, (int)numberTwo), ephemeral: true);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Code description:
|
||||||
|
- Name - the command name (execute with /{Name})
|
||||||
|
- Description - The description of the command
|
||||||
|
- canUseDM - true id this command can be activated in DM chat, false otherwise
|
||||||
|
- Options - the arguments of the command
|
||||||
|
- ExecuteServer() - this function will be called if the command is invoked in a server channel (optional)
|
||||||
|
- context - the command context
|
||||||
|
- ExecuteDM() - this function will be called if the command is invoked in a DM channel (optional)
|
||||||
|
- context - the command context
|
||||||
|
|
||||||
|
|
||||||
|
## Note:
|
||||||
|
You can create multiple commands, events and slash commands into one single plugin (class library). The PluginManager will detect the classes and load them individualy. If there are more commands (normal commands, events or slash commands) into a single project (class library) they can use the same resources (a class for example) that is contained within the plugin.
|
||||||
|
|
||||||
|
|
||||||
|
> Updated: 7.04.2023
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.1.32421.90
|
VisualStudioVersion = 17.1.32421.90
|
||||||
@@ -7,12 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBot", "DiscordBot\Di
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginManager", "PluginManager\PluginManager.csproj", "{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PluginManager", "PluginManager\PluginManager.csproj", "{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MusicLibrary", "..\DiscordBotItems\Plugins\MusicLibrary\MusicLibrary.csproj", "{878DFE01-4596-4EBC-9651-0679598CE794}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlashCommands", "..\DiscordBotItems\Plugins\SlashCommands\SlashCommands.csproj", "{C2D73BE8-997B-4A4A-8EA5-989BE33EE1DD}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LevelingSystem", "..\DiscordBotItems\Plugins\LevelingSystem\LevelingSystem.csproj", "{0138F343-BBB9-4D5F-B499-D9C2978BE9AA}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -27,22 +21,12 @@ Global
|
|||||||
{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Debug|Any CPU.Build.0 = 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.ActiveCfg = Release|Any CPU
|
||||||
{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EDD4D9B3-98DD-4367-A09F-D1C5ACB61132}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{878DFE01-4596-4EBC-9651-0679598CE794}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{878DFE01-4596-4EBC-9651-0679598CE794}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{878DFE01-4596-4EBC-9651-0679598CE794}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{878DFE01-4596-4EBC-9651-0679598CE794}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{C2D73BE8-997B-4A4A-8EA5-989BE33EE1DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C2D73BE8-997B-4A4A-8EA5-989BE33EE1DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C2D73BE8-997B-4A4A-8EA5-989BE33EE1DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C2D73BE8-997B-4A4A-8EA5-989BE33EE1DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{0138F343-BBB9-4D5F-B499-D9C2978BE9AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{0138F343-BBB9-4D5F-B499-D9C2978BE9AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{0138F343-BBB9-4D5F-B499-D9C2978BE9AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{0138F343-BBB9-4D5F-B499-D9C2978BE9AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF}
|
SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
|||||||
36
builder.sh
Executable file
36
builder.sh
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
# All files in this directory will be copied to the root of the container
|
||||||
|
|
||||||
|
echo "Building..."
|
||||||
|
|
||||||
|
echo "Building linux-x64 not self-contained"
|
||||||
|
dotnet publish -r linux-x64 -p:PublishSingleFile=false --self-contained false -c Release -o ./publish/linux-x64
|
||||||
|
|
||||||
|
echo "Building win-x64 not self-contained"
|
||||||
|
dotnet publish -r win-x64 -p:PublishSingleFile=false --self-contained false -c Release -o ./publish/win-x64
|
||||||
|
|
||||||
|
echo "Building osx-x64 not self-contained"
|
||||||
|
dotnet publish -r osx-x64 -p:PublishSingleFile=false --self-contained false -c Release -o ./publish/osx-x64
|
||||||
|
|
||||||
|
#One file per platform
|
||||||
|
echo "Building linux-x64 self-contained"
|
||||||
|
dotnet publish -r linux-x64 -p:PublishSingleFile=true --self-contained true -c Release -o ./publish/linux-x64-selfcontained
|
||||||
|
|
||||||
|
echo "Building win-x64 self-contained"
|
||||||
|
dotnet publish -r win-x64 -p:PublishSingleFile=true --self-contained true -c Release -o ./publish/win-x64-selfcontained
|
||||||
|
|
||||||
|
echo "Building osx-x64 self-contained"
|
||||||
|
dotnet publish -r osx-x64 -p:PublishSingleFile=true --self-contained true -c Release -o ./publish/osx-x64-selfcontained
|
||||||
|
|
||||||
|
echo "Zipping..."
|
||||||
|
mkdir ./publish/zip
|
||||||
|
|
||||||
|
|
||||||
|
zip -r ./publish/zip/linux-x64.zip ./publish/linux-x64
|
||||||
|
zip -r ./publish/zip/win-x64.zip ./publish/win-x64
|
||||||
|
zip -r ./publish/zip/osx-x64.zip ./publish/osx-x64
|
||||||
|
|
||||||
|
zip -r ./publish/zip/linux-x64-selfcontained.zip ./publish/linux-x64-selfcontained
|
||||||
|
zip -r ./publish/zip/win-x64-selfcontained.zip ./publish/win-x64-selfcontained
|
||||||
|
zip -r ./publish/zip/osx-x64-selfcontained.zip ./publish/osx-x64-selfcontained
|
||||||
|
|
||||||
|
echo "Done!"
|
||||||
Reference in New Issue
Block a user