61 Commits

Author SHA1 Message Date
f7e6b0a398 DBCommand interface update & all other plugins were updated 2022-09-03 16:28:03 +03:00
68a83b052a Updater added 2022-08-28 12:59:41 +03:00
d689eee7fa 2022-08-26 10:42:15 +03:00
f6442af30c patch: listplugs, plugin version system and progress bar 2022-08-25 15:15:47 +03:00
b98f57fcf8 Merge branch 'preview' of https://github.com/Wizzy69/DiscordBotWithAPI into preview 2022-08-24 21:34:13 +03:00
77aad985fa Added a new ProgressBar type 2022-08-24 21:34:06 +03:00
Wizzy69
f8ebf76f92 Delete .idea/.idea.SethDiscordBot/.idea directory 2022-08-20 20:52:21 +03:00
6da9828e5c improved save method 2022-08-20 17:44:19 +03:00
3ba45790e7 Merge branch 'preview' of https://github.com/Wizzy69/DiscordBotWithAPI into preview 2022-08-17 20:31:55 +03:00
e440e97948 2022-08-17 20:31:52 +03:00
Wizzy69
938c73c810 Delete DiscordBotConsoleLauncher directory 2022-08-17 20:31:28 +03:00
a8520c8c96 fixed some bugs 2022-08-17 20:23:06 +03:00
debdc58646 The ability to remove a plugin has been added 2022-08-17 20:12:31 +03:00
8b36c086ef New Command added & Leveling System update 2022-08-17 14:19:46 +03:00
1f5e5d0611 patch 2022-08-17 10:09:02 +03:00
bbc1c601c9 Patching system build 2 2022-08-17 09:58:54 +03:00
5ab3195956 2022-08-16 23:08:56 +03:00
1f1983480a 2022-08-16 16:14:25 +03:00
2fcd86cf12 Merge branch 'preview' of https://github.com/Wizzy69/DiscordBotWithAPI into preview 2022-08-16 16:12:38 +03:00
2c83d00c00 2022-08-16 16:12:14 +03:00
Wizzy69
ccac0ca6d0 Update README.md 2022-07-26 15:15:13 +03:00
4c9c7410f0 2022-07-17 19:31:59 +03:00
eef13db3aa 2022-07-17 19:30:39 +03:00
27bbe899ab 2022-07-17 19:29:58 +03:00
79002de9a5 2022-07-17 19:28:22 +03:00
17f68a8e5e Moved Console activity on another thread 2022-07-17 18:53:56 +03:00
c415fa1c0c Updated display features 2022-07-17 14:21:16 +03:00
b8ec6f42df Fixed some bugs with Command handler and configuration 2022-07-13 19:48:57 +03:00
3f67d7f3f9 updated music commands 2022-07-10 21:57:22 +03:00
2dae8a3a63 2022-07-10 15:07:15 +03:00
47aae730c7 Music Commands 2022-07-09 14:57:49 +03:00
aa808e950a 2022-07-09 10:41:39 +03:00
7dd43b7841 2022-07-09 10:41:33 +03:00
82a3744d48 2022-07-09 10:26:36 +03:00
3839e4d838 patch 2022-07-09 09:48:58 +03:00
a66ebc43d9 updated music 2022-07-09 09:48:45 +03:00
45bbda8185 2022-07-07 13:56:21 +03:00
2db6bf2729 2022-07-07 13:55:32 +03:00
3097eb7fca 2022-07-06 14:43:10 +03:00
efb6ac5192 2022-07-06 14:32:16 +03:00
27fe615447 2022-07-06 14:00:41 +03:00
c40fcdac9d 2022-07-06 13:59:59 +03:00
c674c76bd0 Fixed some display bugs 2022-07-06 13:56:04 +03:00
1292e0f585 Fixed some bugs and added version checking system. 2022-07-06 13:38:44 +03:00
3abb4cdda7 Patch 2022-07-05 20:32:51 +03:00
c6e8976456 Moved library archive to github 2022-07-05 18:11:00 +03:00
19115a837c Due to buggy code the GUI was removed from the bot 2022-07-05 17:17:44 +03:00
0a200abec6 Merge branch 'preview' of https://github.com/Wizzy69/DiscordBotWithAPI into preview 2022-07-05 16:43:25 +03:00
c80fe33e6d 2022-07-05 16:43:23 +03:00
Wizzy69
edc5cb97ba Delete .vscode directory 2022-06-28 10:49:16 +03:00
059228ca52 2022-06-28 10:45:40 +03:00
861b83cda2 Cleaned up code 2022-06-12 10:22:43 +03:00
97888626b6 2022-06-09 17:19:51 +03:00
781bb489bd 2022-06-08 21:00:48 +03:00
1712205222 2022-06-08 20:45:25 +03:00
51324f6dca 2022-06-08 19:59:58 +03:00
531edcd3cc patch 2022-06-08 18:54:58 +03:00
c66ff52d94 2022-06-07 11:13:03 +03:00
Wizzy69
195c082cd7 Update README.md 2022-06-05 21:02:04 +03:00
16005ef30d 2022-06-05 20:55:33 +03:00
c15f7b4874 2022-06-05 20:50:01 +03:00
113 changed files with 3688 additions and 3501 deletions

2
.gitignore vendored
View File

@@ -362,3 +362,5 @@ MigrationBackup/
# Fody - auto-generated XML schema # Fody - auto-generated XML schema
FodyWeavers.xsd FodyWeavers.xsd
*.txt

View File

@@ -1,13 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/modules.xml
/contentModel.xml
/.idea.DiscordBotWithAPI.iml
/projectSettingsUpdater.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AvaloniaProject">
<option name="projectPerEditor">
<map>
<entry key="DiscordBotGUI/App.axaml" value="DiscordBotGUI/DiscordBotGUI.csproj" />
<entry key="DiscordBotGUI/AppUpdater.axaml" value="DiscordBotGUI/DiscordBotGUI.csproj" />
<entry key="DiscordBotGUI/Settings/Commands.axaml" value="DiscordBotGUI/DiscordBotGUI.csproj" />
<entry key="DiscordBotGUI/Settings/Events.axaml" value="DiscordBotGUI/DiscordBotGUI.csproj" />
</map>
</option>
</component>
</project>

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

1
.idea/.idea.SethDiscordBot/.idea/.name generated Normal file
View File

@@ -0,0 +1 @@
SethDiscordBot

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AvaloniaProject">
<option name="projectPerEditor">
<map>
<entry key="Updater/MainWindow.axaml" value="Updater/Updater.csproj" />
</map>
</option>
</component>
</project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RiderProjectSettingsUpdater">
<option name="vcsConfiguration" value="2" />
</component>
</project>

View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoGeneratedRunConfigurationManager">
<projectFile pubXmlPath="DiscordBot/Properties/PublishProfiles/LinuxProfile.pubxml">DiscordBot/DiscordBot.csproj</projectFile>
<projectFile pubXmlPath="DiscordBot/Properties/PublishProfiles/WindowsBuild.pubxml">DiscordBot/DiscordBot.csproj</projectFile>
<projectFile>Updater/Updater.csproj</projectFile>
</component>
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="ab173b07-aba1-4bb8-94c1-ae9846bbdb0a" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/.idea/.idea.SethDiscordBot/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.SethDiscordBot/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/BUILDS/net6.0/PluginManager.dll" beforeDir="false" afterPath="$PROJECT_DIR$/BUILDS/net6.0/PluginManager.dll" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DiscordBot/DiscordBot.csproj" beforeDir="false" afterPath="$PROJECT_DIR$/DiscordBot/DiscordBot.csproj" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="2CUQteUHoNWL2Ok4DVEh1GfFaXk" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;ASKED_SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;preferences.pluginManager&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
}
}</component>
<component name="RunManager" selected="Publish to IIS.DiscordBot: WindowsBuild">
<configuration name="DiscordBot: LinuxProfile" type="DotNetMsBuildPublish" factoryName="Publish to IIS">
<riderPublish publish_profile="LinuxProfile.pubxml" pubxml_path="$PROJECT_DIR$/DiscordBot/Properties/PublishProfiles/LinuxProfile.pubxml" uuid_high="612037599008934041" uuid_low="-9069359786678974134" />
<method v="2" />
</configuration>
<configuration name="DiscordBot: WindowsBuild" type="DotNetMsBuildPublish" factoryName="Publish to IIS">
<riderPublish publish_profile="WindowsBuild.pubxml" pubxml_path="$PROJECT_DIR$/DiscordBot/Properties/PublishProfiles/WindowsBuild.pubxml" uuid_high="612037599008934041" uuid_low="-9069359786678974134" />
<method v="2" />
</configuration>
<configuration name="Updater" type="DotNetProject" factoryName=".NET Project">
<option name="EXE_PATH" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="PASS_PARENT_ENVS" value="1" />
<option name="USE_EXTERNAL_CONSOLE" value="0" />
<option name="USE_MONO" value="0" />
<option name="RUNTIME_ARGUMENTS" value="" />
<option name="PROJECT_PATH" value="$PROJECT_DIR$/Updater/Updater.csproj" />
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
<option name="PROJECT_KIND" value="DotNetCore" />
<option name="PROJECT_TFM" value="" />
<method v="2">
<option name="Build" />
</method>
</configuration>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="ab173b07-aba1-4bb8-94c1-ae9846bbdb0a" name="Changes" comment="" />
<created>1658854902538</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1658854902538</updated>
<workItem from="1658854908500" duration="1731000" />
<workItem from="1662205818938" duration="46000" />
<workItem from="1662205887643" duration="139000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnityCheckinConfiguration" checkUnsavedScenes="true" />
<component name="UnityUnitTestConfiguration" currentTestLauncher="NUnit" />
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="VcsManagerConfiguration">
<option name="CLEAR_INITIAL_COMMIT_MESSAGE" value="true" />
</component>
</project>

26
.vscode/launch.json vendored
View File

@@ -1,26 +0,0 @@
{
"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/net5.0/DiscordBot.dll",
"args": [],
"cwd": "${workspaceFolder}/DiscordBot",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

View File

@@ -1,5 +0,0 @@
namespace {{namespace}};
public class {{name}}
{
}

View File

@@ -1,3 +0,0 @@
export class {{name}} {
}

View File

@@ -1,9 +0,0 @@
Imports System
Namespace {{namespace}}
Public Class {{name}}
End Class
End Namespace

View File

@@ -1,3 +0,0 @@
export default {{name}} {
}

View File

@@ -1,5 +0,0 @@
namespace {{namespace}};
public enum {{name}}
{
}

View File

@@ -1,5 +0,0 @@
namespace {{namespace}};
public interface {{name}}
{
}

View File

@@ -1,3 +0,0 @@
export interface {{name}} {
}

View File

@@ -1,46 +0,0 @@
{
"templates": [
{
"name": "Class",
"extension": "cs",
"file": "./class.cs-template",
"parameters": "./template-parameters.js"
},
{
"name": "Interface",
"extension": "cs",
"file": "./interface.cs-template",
"parameters": "./template-parameters.js"
},
{
"name": "Enum",
"extension": "cs",
"file": "./enum.cs-template",
"parameters": "./template-parameters.js"
},
{
"name": "Class",
"extension": "ts",
"file": "./class.ts-template",
"parameters": "./template-parameters.js"
},
{
"name": "Interface",
"extension": "ts",
"file": "./interface.ts-template",
"parameters": "./template-parameters.js"
},
{
"name": "Default",
"extension": "ts",
"file": "./default.ts-template",
"parameters": "./template-parameters.js"
},
{
"name": "Class",
"extension": "vb",
"file": "./class.vb-template",
"parameters": "./template-parameters.js"
}
]
}

View File

@@ -1,17 +0,0 @@
var path = require("path");
module.exports = function(filename, projectPath, folderPath) {
var namespace = "Unknown";
if (projectPath) {
namespace = path.basename(projectPath, path.extname(projectPath));
if (folderPath) {
namespace += "." + folderPath.replace(path.dirname(projectPath), "").substring(1).replace(/[\\\/]/g, ".");
}
namespace = namespace.replace(/[\\\-]/g, "_");
}
return {
namespace: namespace,
name: path.basename(filename, path.extname(filename))
}
};

42
.vscode/tasks.json vendored
View File

@@ -1,42 +0,0 @@
{
"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",
"${workspaceFolder}/DiscordBot/DiscordBot.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -14,28 +14,28 @@
"CMD_Utils.dll": {} "CMD_Utils.dll": {}
} }
}, },
"Discord.Net/3.6.1": { "Discord.Net/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Commands": "3.6.1", "Discord.Net.Commands": "3.7.2",
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Interactions": "3.6.1", "Discord.Net.Interactions": "3.7.2",
"Discord.Net.Rest": "3.6.1", "Discord.Net.Rest": "3.7.2",
"Discord.Net.WebSocket": "3.6.1", "Discord.Net.WebSocket": "3.7.2",
"Discord.Net.Webhook": "3.6.1" "Discord.Net.Webhook": "3.7.2"
} }
}, },
"Discord.Net.Commands/3.6.1": { "Discord.Net.Commands/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1" "Discord.Net.Core": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Commands.dll": { "lib/net6.0/Discord.Net.Commands.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Core/3.6.1": { "Discord.Net.Core/3.7.2": {
"dependencies": { "dependencies": {
"Newtonsoft.Json": "13.0.1", "Newtonsoft.Json": "13.0.1",
"System.Collections.Immutable": "5.0.0", "System.Collections.Immutable": "5.0.0",
@@ -44,59 +44,59 @@
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Core.dll": { "lib/net6.0/Discord.Net.Core.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Interactions/3.6.1": { "Discord.Net.Interactions/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Rest": "3.6.1", "Discord.Net.Rest": "3.7.2",
"Discord.Net.WebSocket": "3.6.1", "Discord.Net.WebSocket": "3.7.2",
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
"System.Collections.Immutable": "5.0.0", "System.Collections.Immutable": "5.0.0",
"System.Reactive": "5.0.0" "System.Reactive": "5.0.0"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Interactions.dll": { "lib/net6.0/Discord.Net.Interactions.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Rest/3.6.1": { "Discord.Net.Rest/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1" "Discord.Net.Core": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Rest.dll": { "lib/net6.0/Discord.Net.Rest.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Webhook/3.6.1": { "Discord.Net.Webhook/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Rest": "3.6.1" "Discord.Net.Rest": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Webhook.dll": { "lib/net6.0/Discord.Net.Webhook.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.WebSocket/3.6.1": { "Discord.Net.WebSocket/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Rest": "3.6.1" "Discord.Net.Rest": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.WebSocket.dll": { "lib/net6.0/Discord.Net.WebSocket.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
@@ -147,7 +147,7 @@
"System.ValueTuple/4.5.0": {}, "System.ValueTuple/4.5.0": {},
"PluginManager/1.0.0": { "PluginManager/1.0.0": {
"dependencies": { "dependencies": {
"Discord.Net": "3.6.1" "Discord.Net": "3.7.2"
}, },
"runtime": { "runtime": {
"PluginManager.dll": {} "PluginManager.dll": {}
@@ -161,54 +161,54 @@
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Discord.Net/3.6.1": { "Discord.Net/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-TfcL/HG57fVt//WVJ2XyF2PlytY9IYkkwwkPLIhvu5FW4wf9rm7+N8RPh4qtELLfsa5ES0FK2RbgYjABRR9AjA==", "sha512": "sha512-FAiCLGu5rp6+Z10FjKbbJ6LLpKjbMBGpozixkJlz5LZvuncPx8f4AWFAw7pBecKUuAh983qiZ8CZYZcNXsI4qg==",
"path": "discord.net/3.6.1", "path": "discord.net/3.7.2",
"hashPath": "discord.net.3.6.1.nupkg.sha512" "hashPath": "discord.net.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Commands/3.6.1": { "Discord.Net.Commands/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-kK7m571yzSzPd93o+n8Z+TfvX62BT1HtOEZIWXKwXWO8itP/sgqBNExjWK/6DOpkbD6+khc2f3rp+TA0rJD88g==", "sha512": "sha512-aOEGP04X64htsTr7ozKj9qHpmvOfitSw5gfR8Tw9TX0+FdswD2LNL2KfOAIaxRKZmRTm34aXQEJrVq0K8AptmQ==",
"path": "discord.net.commands/3.6.1", "path": "discord.net.commands/3.7.2",
"hashPath": "discord.net.commands.3.6.1.nupkg.sha512" "hashPath": "discord.net.commands.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Core/3.6.1": { "Discord.Net.Core/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-ibVjQiWzgqh0GyP/GXE2kv3TA/9ysmmNFG/WmRE7GepQQAXXGxVUO9IMJ8h14EvIXMQ0m0DktMe5DkUnilo3Ag==", "sha512": "sha512-apwswc6LjN4dj3u27SO3Hr56Jzl91wzReahieoD7IQhV+BJQaRxhTRiEEWFTrBzHfeFHEOQ7r6vZnra3zeFhKA==",
"path": "discord.net.core/3.6.1", "path": "discord.net.core/3.7.2",
"hashPath": "discord.net.core.3.6.1.nupkg.sha512" "hashPath": "discord.net.core.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Interactions/3.6.1": { "Discord.Net.Interactions/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-WGOxz6SMUu4WS5b/JdrhlwQletcplBIYqvjFBBDfnqE+uNJqcNGtAdyjLqIILfXGx8aSSSSYZSCeAUa7FZ8Yew==", "sha512": "sha512-dwGhEdDB0yyo/lGtjwIDVZmsuD52di7lIZWu/sBtvvA05dMgYZq5S6ILdsBXjOyaHeXd+EV4YMlj2VS/rm619w==",
"path": "discord.net.interactions/3.6.1", "path": "discord.net.interactions/3.7.2",
"hashPath": "discord.net.interactions.3.6.1.nupkg.sha512" "hashPath": "discord.net.interactions.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Rest/3.6.1": { "Discord.Net.Rest/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-T7RRThIS23roFEJwTL1l7aawjVyn7ZB5yH3tMge0d6TiCzzp4V4FAZ+ArTt19LHRFhPly90v8V3sWqmTMN+5Zg==", "sha512": "sha512-dyp8YaMBNJ837EH1KNz2PNGZqc2y71WFd1+pdldF+pLQJ3Gf/+V7685paAR7bQw7yFNyqEBR/QRBCNp+QIQ7Wg==",
"path": "discord.net.rest/3.6.1", "path": "discord.net.rest/3.7.2",
"hashPath": "discord.net.rest.3.6.1.nupkg.sha512" "hashPath": "discord.net.rest.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Webhook/3.6.1": { "Discord.Net.Webhook/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-xikKHIGAIMz0BzHkaTKb48DNpFjKW8mvJjLJSezJ1xQOu+laHNk/hav4qxVtyZz7HSI/vGTkmlq9hKVhWzpaUA==", "sha512": "sha512-da3i/mTq2y7mfj3xlHH14S4PivHbflJCVr8OUikJtQrxBOxvPkqP7ZYk3Y9S28q0K8qik+TUjCcjL5gELKrh/A==",
"path": "discord.net.webhook/3.6.1", "path": "discord.net.webhook/3.7.2",
"hashPath": "discord.net.webhook.3.6.1.nupkg.sha512" "hashPath": "discord.net.webhook.3.7.2.nupkg.sha512"
}, },
"Discord.Net.WebSocket/3.6.1": { "Discord.Net.WebSocket/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-hF22Xy7URlVEDQZ69INOgzPvFUsIDfd+r6U+1yF9HWdBn3d4THnvAAhkv1TraSx/T/MKS7g+jvk/HZ3mh5S3aw==", "sha512": "sha512-pYCd6ET44ADaNiyEw82TaJnR7TKYHfrKCytWFWMPL5faJhoh260avZn3Hwunlf331lEQ0f4K1CujPkQbNuq7kQ==",
"path": "discord.net.websocket/3.6.1", "path": "discord.net.websocket/3.7.2",
"hashPath": "discord.net.websocket.3.6.1.nupkg.sha512" "hashPath": "discord.net.websocket.3.7.2.nupkg.sha512"
}, },
"Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": {
"type": "package", "type": "package",

Binary file not shown.

View File

@@ -8,34 +8,47 @@
".NETCoreApp,Version=v6.0": { ".NETCoreApp,Version=v6.0": {
"Music Commands/1.0.0": { "Music Commands/1.0.0": {
"dependencies": { "dependencies": {
"PluginManager": "1.0.0" "PluginManager": "1.0.0",
"YoutubeExplode": "6.2.0"
}, },
"runtime": { "runtime": {
"Music Commands.dll": {} "Music Commands.dll": {}
} }
}, },
"Discord.Net/3.6.1": { "AngleSharp/0.17.0": {
"dependencies": { "dependencies": {
"Discord.Net.Commands": "3.6.1", "System.Buffers": "4.5.1",
"Discord.Net.Core": "3.6.1", "System.Text.Encoding.CodePages": "5.0.0"
"Discord.Net.Interactions": "3.6.1", },
"Discord.Net.Rest": "3.6.1", "runtime": {
"Discord.Net.WebSocket": "3.6.1", "lib/netstandard2.0/AngleSharp.dll": {
"Discord.Net.Webhook": "3.6.1" "assemblyVersion": "0.17.0.0",
"fileVersion": "0.17.0.0"
}
} }
}, },
"Discord.Net.Commands/3.6.1": { "Discord.Net/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1" "Discord.Net.Commands": "3.7.2",
"Discord.Net.Core": "3.7.2",
"Discord.Net.Interactions": "3.7.2",
"Discord.Net.Rest": "3.7.2",
"Discord.Net.WebSocket": "3.7.2",
"Discord.Net.Webhook": "3.7.2"
}
},
"Discord.Net.Commands/3.7.2": {
"dependencies": {
"Discord.Net.Core": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Commands.dll": { "lib/net6.0/Discord.Net.Commands.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Core/3.6.1": { "Discord.Net.Core/3.7.2": {
"dependencies": { "dependencies": {
"Newtonsoft.Json": "13.0.1", "Newtonsoft.Json": "13.0.1",
"System.Collections.Immutable": "5.0.0", "System.Collections.Immutable": "5.0.0",
@@ -44,59 +57,59 @@
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Core.dll": { "lib/net6.0/Discord.Net.Core.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Interactions/3.6.1": { "Discord.Net.Interactions/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Rest": "3.6.1", "Discord.Net.Rest": "3.7.2",
"Discord.Net.WebSocket": "3.6.1", "Discord.Net.WebSocket": "3.7.2",
"Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0", "Microsoft.Extensions.DependencyInjection.Abstractions": "5.0.0",
"System.Collections.Immutable": "5.0.0", "System.Collections.Immutable": "5.0.0",
"System.Reactive": "5.0.0" "System.Reactive": "5.0.0"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Interactions.dll": { "lib/net6.0/Discord.Net.Interactions.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Rest/3.6.1": { "Discord.Net.Rest/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1" "Discord.Net.Core": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Rest.dll": { "lib/net6.0/Discord.Net.Rest.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.Webhook/3.6.1": { "Discord.Net.Webhook/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Rest": "3.6.1" "Discord.Net.Rest": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.Webhook.dll": { "lib/net6.0/Discord.Net.Webhook.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
"Discord.Net.WebSocket/3.6.1": { "Discord.Net.WebSocket/3.7.2": {
"dependencies": { "dependencies": {
"Discord.Net.Core": "3.6.1", "Discord.Net.Core": "3.7.2",
"Discord.Net.Rest": "3.6.1" "Discord.Net.Rest": "3.7.2"
}, },
"runtime": { "runtime": {
"lib/net6.0/Discord.Net.WebSocket.dll": { "lib/net6.0/Discord.Net.WebSocket.dll": {
"assemblyVersion": "3.6.1.0", "assemblyVersion": "3.7.2.0",
"fileVersion": "3.6.1.0" "fileVersion": "3.7.2.0"
} }
} }
}, },
@@ -108,6 +121,7 @@
} }
} }
}, },
"Microsoft.NETCore.Platforms/5.0.0": {},
"Newtonsoft.Json/13.0.1": { "Newtonsoft.Json/13.0.1": {
"runtime": { "runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": { "lib/netstandard2.0/Newtonsoft.Json.dll": {
@@ -116,6 +130,7 @@
} }
} }
}, },
"System.Buffers/4.5.1": {},
"System.Collections.Immutable/5.0.0": {}, "System.Collections.Immutable/5.0.0": {},
"System.Interactive.Async/5.0.0": { "System.Interactive.Async/5.0.0": {
"dependencies": { "dependencies": {
@@ -144,10 +159,26 @@
} }
} }
}, },
"System.Text.Encoding.CodePages/5.0.0": {
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0"
}
},
"System.ValueTuple/4.5.0": {}, "System.ValueTuple/4.5.0": {},
"YoutubeExplode/6.2.0": {
"dependencies": {
"AngleSharp": "0.17.0"
},
"runtime": {
"lib/net5.0/YoutubeExplode.dll": {
"assemblyVersion": "6.2.0.0",
"fileVersion": "6.2.0.0"
}
}
},
"PluginManager/1.0.0": { "PluginManager/1.0.0": {
"dependencies": { "dependencies": {
"Discord.Net": "3.6.1" "Discord.Net": "3.7.2"
}, },
"runtime": { "runtime": {
"PluginManager.dll": {} "PluginManager.dll": {}
@@ -161,54 +192,61 @@
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Discord.Net/3.6.1": { "AngleSharp/0.17.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-TfcL/HG57fVt//WVJ2XyF2PlytY9IYkkwwkPLIhvu5FW4wf9rm7+N8RPh4qtELLfsa5ES0FK2RbgYjABRR9AjA==", "sha512": "sha512-74haoXINcj4SdMsmiNzk+9VUwIX1U9P61O6AZd5Uao8SGNnJJB8Y/r8VJRc8orn4c7Vk/oURAKSNF9XcSDxbfA==",
"path": "discord.net/3.6.1", "path": "anglesharp/0.17.0",
"hashPath": "discord.net.3.6.1.nupkg.sha512" "hashPath": "anglesharp.0.17.0.nupkg.sha512"
}, },
"Discord.Net.Commands/3.6.1": { "Discord.Net/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-kK7m571yzSzPd93o+n8Z+TfvX62BT1HtOEZIWXKwXWO8itP/sgqBNExjWK/6DOpkbD6+khc2f3rp+TA0rJD88g==", "sha512": "sha512-FAiCLGu5rp6+Z10FjKbbJ6LLpKjbMBGpozixkJlz5LZvuncPx8f4AWFAw7pBecKUuAh983qiZ8CZYZcNXsI4qg==",
"path": "discord.net.commands/3.6.1", "path": "discord.net/3.7.2",
"hashPath": "discord.net.commands.3.6.1.nupkg.sha512" "hashPath": "discord.net.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Core/3.6.1": { "Discord.Net.Commands/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-ibVjQiWzgqh0GyP/GXE2kv3TA/9ysmmNFG/WmRE7GepQQAXXGxVUO9IMJ8h14EvIXMQ0m0DktMe5DkUnilo3Ag==", "sha512": "sha512-aOEGP04X64htsTr7ozKj9qHpmvOfitSw5gfR8Tw9TX0+FdswD2LNL2KfOAIaxRKZmRTm34aXQEJrVq0K8AptmQ==",
"path": "discord.net.core/3.6.1", "path": "discord.net.commands/3.7.2",
"hashPath": "discord.net.core.3.6.1.nupkg.sha512" "hashPath": "discord.net.commands.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Interactions/3.6.1": { "Discord.Net.Core/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-WGOxz6SMUu4WS5b/JdrhlwQletcplBIYqvjFBBDfnqE+uNJqcNGtAdyjLqIILfXGx8aSSSSYZSCeAUa7FZ8Yew==", "sha512": "sha512-apwswc6LjN4dj3u27SO3Hr56Jzl91wzReahieoD7IQhV+BJQaRxhTRiEEWFTrBzHfeFHEOQ7r6vZnra3zeFhKA==",
"path": "discord.net.interactions/3.6.1", "path": "discord.net.core/3.7.2",
"hashPath": "discord.net.interactions.3.6.1.nupkg.sha512" "hashPath": "discord.net.core.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Rest/3.6.1": { "Discord.Net.Interactions/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-T7RRThIS23roFEJwTL1l7aawjVyn7ZB5yH3tMge0d6TiCzzp4V4FAZ+ArTt19LHRFhPly90v8V3sWqmTMN+5Zg==", "sha512": "sha512-dwGhEdDB0yyo/lGtjwIDVZmsuD52di7lIZWu/sBtvvA05dMgYZq5S6ILdsBXjOyaHeXd+EV4YMlj2VS/rm619w==",
"path": "discord.net.rest/3.6.1", "path": "discord.net.interactions/3.7.2",
"hashPath": "discord.net.rest.3.6.1.nupkg.sha512" "hashPath": "discord.net.interactions.3.7.2.nupkg.sha512"
}, },
"Discord.Net.Webhook/3.6.1": { "Discord.Net.Rest/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-xikKHIGAIMz0BzHkaTKb48DNpFjKW8mvJjLJSezJ1xQOu+laHNk/hav4qxVtyZz7HSI/vGTkmlq9hKVhWzpaUA==", "sha512": "sha512-dyp8YaMBNJ837EH1KNz2PNGZqc2y71WFd1+pdldF+pLQJ3Gf/+V7685paAR7bQw7yFNyqEBR/QRBCNp+QIQ7Wg==",
"path": "discord.net.webhook/3.6.1", "path": "discord.net.rest/3.7.2",
"hashPath": "discord.net.webhook.3.6.1.nupkg.sha512" "hashPath": "discord.net.rest.3.7.2.nupkg.sha512"
}, },
"Discord.Net.WebSocket/3.6.1": { "Discord.Net.Webhook/3.7.2": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
"sha512": "sha512-hF22Xy7URlVEDQZ69INOgzPvFUsIDfd+r6U+1yF9HWdBn3d4THnvAAhkv1TraSx/T/MKS7g+jvk/HZ3mh5S3aw==", "sha512": "sha512-da3i/mTq2y7mfj3xlHH14S4PivHbflJCVr8OUikJtQrxBOxvPkqP7ZYk3Y9S28q0K8qik+TUjCcjL5gELKrh/A==",
"path": "discord.net.websocket/3.6.1", "path": "discord.net.webhook/3.7.2",
"hashPath": "discord.net.websocket.3.6.1.nupkg.sha512" "hashPath": "discord.net.webhook.3.7.2.nupkg.sha512"
},
"Discord.Net.WebSocket/3.7.2": {
"type": "package",
"serviceable": true,
"sha512": "sha512-pYCd6ET44ADaNiyEw82TaJnR7TKYHfrKCytWFWMPL5faJhoh260avZn3Hwunlf331lEQ0f4K1CujPkQbNuq7kQ==",
"path": "discord.net.websocket/3.7.2",
"hashPath": "discord.net.websocket.3.7.2.nupkg.sha512"
}, },
"Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": { "Microsoft.Extensions.DependencyInjection.Abstractions/5.0.0": {
"type": "package", "type": "package",
@@ -217,6 +255,13 @@
"path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0", "path": "microsoft.extensions.dependencyinjection.abstractions/5.0.0",
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512" "hashPath": "microsoft.extensions.dependencyinjection.abstractions.5.0.0.nupkg.sha512"
}, },
"Microsoft.NETCore.Platforms/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-VyPlqzH2wavqquTcYpkIIAQ6WdenuKoFN0BdYBbCWsclXacSOHNQn66Gt4z5NBqEYW0FAPm5rlvki9ZiCij5xQ==",
"path": "microsoft.netcore.platforms/5.0.0",
"hashPath": "microsoft.netcore.platforms.5.0.0.nupkg.sha512"
},
"Newtonsoft.Json/13.0.1": { "Newtonsoft.Json/13.0.1": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
@@ -224,6 +269,13 @@
"path": "newtonsoft.json/13.0.1", "path": "newtonsoft.json/13.0.1",
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
}, },
"System.Buffers/4.5.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==",
"path": "system.buffers/4.5.1",
"hashPath": "system.buffers.4.5.1.nupkg.sha512"
},
"System.Collections.Immutable/5.0.0": { "System.Collections.Immutable/5.0.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
@@ -252,6 +304,13 @@
"path": "system.reactive/5.0.0", "path": "system.reactive/5.0.0",
"hashPath": "system.reactive.5.0.0.nupkg.sha512" "hashPath": "system.reactive.5.0.0.nupkg.sha512"
}, },
"System.Text.Encoding.CodePages/5.0.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-NyscU59xX6Uo91qvhOs2Ccho3AR2TnZPomo1Z0K6YpyztBPM/A5VbkzOO19sy3A3i1TtEnTxA7bCe3Us+r5MWg==",
"path": "system.text.encoding.codepages/5.0.0",
"hashPath": "system.text.encoding.codepages.5.0.0.nupkg.sha512"
},
"System.ValueTuple/4.5.0": { "System.ValueTuple/4.5.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,
@@ -259,6 +318,13 @@
"path": "system.valuetuple/4.5.0", "path": "system.valuetuple/4.5.0",
"hashPath": "system.valuetuple.4.5.0.nupkg.sha512" "hashPath": "system.valuetuple.4.5.0.nupkg.sha512"
}, },
"YoutubeExplode/6.2.0": {
"type": "package",
"serviceable": true,
"sha512": "sha512-oH5kst4w1QkUwRjJco0alF57JOmFofSGlPkr4OniODB8R6MEyRWn1xFg3JS2wFYd6scZluoXRDhM3/uyUjO9/g==",
"path": "youtubeexplode/6.2.0",
"hashPath": "youtubeexplode.6.2.0.nupkg.sha512"
},
"PluginManager/1.0.0": { "PluginManager/1.0.0": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<BaseOutputPath>..\DiscordBot\bin\Debug\net6.0\Data\Plugins\Commands\LevelingSystem</BaseOutputPath> <BaseOutputPath>bin\</BaseOutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,34 +1,34 @@
using System; using Discord;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager; using PluginManager;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using PluginManager.Others; using PluginManager.Others;
namespace CMD_LevelingSystem namespace CMD_LevelingSystem;
{
internal class Level : DBCommand internal class Level : DBCommand
{ {
public string Command => "level"; public string Command => "level";
public List<string> Aliases => new() { "lvl" };
public string Description => "Display tour current level"; public string Description => "Display tour current level";
public string Usage => "level"; public string Usage => "level";
public bool canUseDM => false;
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(SocketCommandContext context)
{ {
User user = await Functions.ConvertFromJson<User>(Config.GetValue("LevelingSystemPath") + $"/{message.Author.Id}.dat"); if (!File.Exists(Config.GetValue<string>("LevelingSystemPath") + $"/{context.Message.Author.Id}.dat"))
{
await context.Channel.SendMessageAsync("You are now unranked !");
return;
}
var user = await Functions.ConvertFromJson<User>(Config.GetValue<string>("LevelingSystemPath") + $"/{context.Message.Author.Id}.dat");
if (user == null) if (user == null)
{ {
await context.Channel.SendMessageAsync("You are now unranked !"); await context.Channel.SendMessageAsync("You are now unranked !");
@@ -36,7 +36,7 @@ namespace CMD_LevelingSystem
} }
var builder = new EmbedBuilder(); var builder = new EmbedBuilder();
Random r = new Random(); var r = new Random();
builder.WithColor(r.Next(256), r.Next(256), r.Next(256)); builder.WithColor(r.Next(256), r.Next(256), r.Next(256));
builder.AddField("Current Level", user.CurrentLevel, true) builder.AddField("Current Level", user.CurrentLevel, true)
.AddField("Current EXP", user.CurrentEXP, true) .AddField("Current EXP", user.CurrentEXP, true)
@@ -45,4 +45,3 @@ namespace CMD_LevelingSystem
await context.Channel.SendMessageAsync(embed: builder.Build()); await context.Channel.SendMessageAsync(embed: builder.Build());
} }
} }
}

View File

@@ -1,16 +1,18 @@
using System; using Discord.WebSocket;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMD_LevelingSystem namespace CMD_LevelingSystem;
public class DiscordUser
{ {
public string Username { get; set; }
public ushort DiscordTag { get; set; }
public ulong userID { get; set; }
}
public class User public class User
{ {
public string userID { get; set; } public DiscordUser user { get; set; }
public int CurrentLevel { get; set; } public int CurrentLevel { get; set; }
public Int64 CurrentEXP { get; set; } public long CurrentEXP { get; set; }
public Int64 RequiredEXPToLevelUp { get; set; } public long RequiredEXPToLevelUp { get; set; }
}
} }

View File

@@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<BaseOutputPath>bin\</BaseOutputPath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -1,24 +0,0 @@
using Discord.Commands;
using Discord.WebSocket;
using PluginManager.Interfaces;
internal class Echo : DBCommand
{
public string Command => "echo";
public string Description => "Replay with the same message";
public string Usage => "echo [message]";
public bool canUseDM => true;
public bool canUseServer => true;
public bool requireAdmin => false;
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{
string m = message.Content.Substring(6);
await message.Channel.SendMessageAsync(m);
}
}

View File

@@ -1,37 +1,32 @@
using System; using Discord.Commands;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces; using PluginManager.Interfaces;
namespace CMD_Utils using System.Collections.Generic;
{
class FlipCoin : DBCommand namespace CMD_Utils;
internal class FlipCoin : DBCommand
{ {
public string Command => "flip"; public string Command => "flip";
public List<string> Aliases => null;
public string Description => "Flip a coin"; public string Description => "Flip a coin";
public string Usage => "flip"; public string Usage => "flip";
public bool canUseDM => true;
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 ExecuteDM(SocketCommandContext context) => ExecuteServer(context);
public async void ExecuteServer(SocketCommandContext context)
{ {
System.Random random = new System.Random(); var random = new System.Random();
int r = random.Next(1, 3); var r = random.Next(1, 3);
if (r == 1) if (r == 1)
await message.Channel.SendMessageAsync("Heads"); await context.Message.Channel.SendMessageAsync("Heads");
else await message.Channel.SendMessageAsync("Tails"); else
} await context.Message.Channel.SendMessageAsync("Tails");
} }
} }

View File

@@ -1,44 +1,37 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using PluginManager.Others;
namespace CMD_Utils;
namespace CMD_Utils
{
public class Poll : DBCommand public class Poll : DBCommand
{ {
public string Command => "poll"; public string Command => "poll";
public List<string> Aliases => null;
public string Description => "Create a poll with options"; public string Description => "Create a poll with options";
public string Usage => "poll [This-is-question] [This-is-answer-1] [This-is-answer-2] ... "; public string Usage => "poll [This-is-question] [This-is-answer-1] [This-is-answer-2] ... ";
public bool canUseDM => false;
public bool canUseServer => true;
public bool requireAdmin => true; public bool requireAdmin => true;
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) public async void ExecuteServer(SocketCommandContext context)
{ {
if (isDM) return; var question = context.Message.Content.Split(' ')[1].Replace('-', ' ');
string question = message.Content.Split(' ')[1].Replace('-', ' '); var answers = Functions.MergeStrings(context.Message.Content.Split(' '), 2).Split(' ');
string[] answers = PluginManager.Others.Functions.MergeStrings(message.Content.Split(' '), 2).Split(' '); var embedBuilder = new EmbedBuilder();
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.Title = question; embedBuilder.Title = question;
int len = answers.Length; var len = answers.Length;
for (int i = 0; i < len; i++) for (var i = 0; i < len; i++) embedBuilder.AddField($"Answer {i + 1}", answers[i].Replace('-', ' '), true);
embedBuilder.AddField($"Answer {i + 1}", answers[i].Replace('-', ' '), true);
var msg = await context.Channel.SendMessageAsync(embed: embedBuilder.Build()); var msg = await context.Channel.SendMessageAsync(embed: embedBuilder.Build());
List<IEmote> emotes = new List<IEmote>(); var emotes = new List<IEmote>();
emotes.Add(Emoji.Parse(":one:")); emotes.Add(Emoji.Parse(":one:"));
emotes.Add(Emoji.Parse(":two:")); emotes.Add(Emoji.Parse(":two:"));
emotes.Add(Emoji.Parse(":three:")); emotes.Add(Emoji.Parse(":three:"));
@@ -46,8 +39,6 @@ namespace CMD_Utils
emotes.Add(Emoji.Parse(":five:")); emotes.Add(Emoji.Parse(":five:"));
emotes.Add(Emoji.Parse(":six:")); emotes.Add(Emoji.Parse(":six:"));
for (int i = 0; i < len; i++) for (var i = 0; i < len; i++) await msg.AddReactionAsync(emotes[i]);
await msg.AddReactionAsync(emotes[i]);
}
} }
} }

View File

@@ -1,4 +1,6 @@
using Discord.Commands; using System.Collections.Generic;
using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces; using PluginManager.Interfaces;
@@ -7,35 +9,35 @@ public class Random : DBCommand
{ {
public string Command => "random"; public string Command => "random";
public List<string> Aliases => new() { "rnd" };
public string Description => "random number between number1 and number2"; public string Description => "random number between number1 and number2";
public string Usage => "random [number1] [number2]"; public string Usage => "random [number1] [number2]";
public bool canUseDM => true;
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 ExecuteDM(SocketCommandContext context) => ExecuteServer(context);
public async void ExecuteServer(SocketCommandContext context)
{ {
try try
{ {
string msg = message.Content; var msg = context.Message.Content;
int a = int.Parse(msg.Split(' ')[1]); var a = int.Parse(msg.Split(' ')[1]);
int b = int.Parse(msg.Split(' ')[2]); var b = int.Parse(msg.Split(' ')[2]);
if (a > b) if (a > b)
{ {
int x = a; var temp = a;
a = b; a = b;
b = x; b = temp;
} }
await message.Channel.SendMessageAsync("Your random generated number is " + new System.Random().Next(a, b)); await context.Message.Channel.SendMessageAsync("Your random generated number is " + new System.Random().Next(a, b));
} }
catch catch
{ {
await message.Channel.SendMessageAsync("Invalid numbers or no numbers:\nUsage: " + Usage); await context.Message.Channel.SendMessageAsync("Invalid numbers or no numbers:\nUsage: " + Usage);
} }
} }
} }

Binary file not shown.

View File

@@ -2,6 +2,3 @@
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="4.0.0.0" /> <bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly> </dependentAssembly>

View File

@@ -1,16 +1,16 @@
using Discord; using System.Collections.Generic;
using System.Linq;
using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Loaders;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using PluginManager.Others.Permissions; using PluginManager.Loaders;
using PluginManager.Others; using PluginManager.Others;
using System.Collections.Generic; namespace DiscordBot.Discord.Commands;
namespace DiscordBot.Discord.Commands
{
/// <summary> /// <summary>
/// The help command /// The help command
/// </summary> /// </summary>
@@ -21,25 +21,17 @@ namespace DiscordBot.Discord.Commands
/// </summary> /// </summary>
public string Command => "help"; public string Command => "help";
public List<string> Aliases => null;
/// <summary> /// <summary>
/// Command Description /// Command Description
/// </summary> /// </summary>
public string Description => "This command allows you to check all loadded commands"; public string Description => "This command allows you to check all loaded commands";
/// <summary> /// <summary>
/// Command usage /// Command usage
/// </summary> /// </summary>
public string Usage => "help"; public string Usage => "help <command>";
/// <summary>
/// Check if the command can be used <inheritdoca DM <see cref="IChannel"/>/>
/// </summary>
public bool canUseDM => true;
/// <summary>
/// Check if the command can be used in a server
/// </summary>
public bool canUseServer => true;
/// <summary> /// <summary>
/// Check if the command require administrator to be executed /// Check if the command require administrator to be executed
@@ -53,54 +45,53 @@ namespace DiscordBot.Discord.Commands
/// <param name="message">The command message</param> /// <param name="message">The command message</param>
/// <param name="client">The discord bot client</param> /// <param name="client">The discord bot client</param>
/// <param name="isDM">True if the message was sent from a DM channel, false otherwise</param> /// <param name="isDM">True if the message was sent from a DM channel, false otherwise</param>
public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) public void ExecuteServer(SocketCommandContext context)
{ {
List<string> args = Functions.GetArguments(message); var args = Functions.GetArguments(context.Message);
if (args.Count != 0) if (args.Count != 0)
{ {
foreach (var item in args) foreach (var item in args)
{ {
var e = GenerateHelpCommand(item); var e = GenerateHelpCommand(item);
if (e != null) if (e is null)
context.Channel.SendMessageAsync(embed: e.Build());
else
context.Channel.SendMessageAsync("Unknown Command " + item); context.Channel.SendMessageAsync("Unknown Command " + item);
else
context.Channel.SendMessageAsync(embed: e.Build());
} }
return; return;
} }
EmbedBuilder embedBuilder = new EmbedBuilder();
string adminCommands = ""; var embedBuilder = new EmbedBuilder();
string normalCommands = "";
string DMCommands = ""; var adminCommands = "";
var normalCommands = "";
foreach (var cmd in PluginLoader.Commands!) foreach (var cmd in PluginLoader.Commands!)
{ {
if (cmd.canUseDM) DMCommands += cmd.Command + " ";
if (cmd.requireAdmin) if (cmd.requireAdmin)
adminCommands += cmd.Command + " "; adminCommands += cmd.Command + " ";
else if (cmd.canUseServer) normalCommands += cmd.Command + " "; else
normalCommands += cmd.Command + " ";
} }
embedBuilder.AddField("Admin Commands", adminCommands); embedBuilder.AddField("Admin Commands", adminCommands);
embedBuilder.AddField("Normal Commands", normalCommands); embedBuilder.AddField("Normal Commands", normalCommands);
embedBuilder.AddField("DM Commands", DMCommands);
context.Channel.SendMessageAsync(embed: embedBuilder.Build()); context.Channel.SendMessageAsync(embed: embedBuilder.Build());
} }
private EmbedBuilder GenerateHelpCommand(string command) private EmbedBuilder GenerateHelpCommand(string command)
{ {
EmbedBuilder embedBuilder = new EmbedBuilder(); var embedBuilder = new EmbedBuilder();
DBCommand 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)));
if (cmd == null) if (cmd == null) return null;
return null;
embedBuilder.AddField("Usage", cmd.Usage); embedBuilder.AddField("Usage", cmd.Usage);
embedBuilder.AddField("Description", cmd.Description); embedBuilder.AddField("Description", cmd.Description);
if (cmd.Aliases is null)
return embedBuilder;
embedBuilder.AddField("Alias", cmd.Aliases.Count == 0 ? "-" : string.Join(", ", cmd.Aliases));
return embedBuilder; return embedBuilder;
} }
} }
}

View File

@@ -1,16 +1,16 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces;
using PluginManager.Others;
using PluginManager.Others.Permissions;
using DiscordLibCommands = Discord.Commands; using DiscordLibCommands = Discord.Commands;
using DiscordLib = Discord; using DiscordLib = Discord;
using OperatingSystem = PluginManager.Others.OperatingSystem;
using PluginManager.Interfaces; namespace DiscordBot.Discord.Commands;
using PluginManager.Others.Permissions;
using PluginManager.Others;
namespace DiscordBot.Discord.Commands
{
internal class Restart : DBCommand internal class Restart : DBCommand
{ {
/// <summary> /// <summary>
@@ -18,6 +18,8 @@ namespace DiscordBot.Discord.Commands
/// </summary> /// </summary>
public string Command => "restart"; public string Command => "restart";
public List<string> Aliases => null;
/// <summary> /// <summary>
/// Command Description /// Command Description
/// </summary> /// </summary>
@@ -28,48 +30,37 @@ namespace DiscordBot.Discord.Commands
/// </summary> /// </summary>
public string Usage => "restart [-p | -c | -args | -cmd] <args>"; public string Usage => "restart [-p | -c | -args | -cmd] <args>";
/// <summary>
/// Check if the command can be used <inheritdoca DM <see cref="IChannel"/>/>
/// </summary>
public bool canUseDM => false;
/// <summary>
/// Check if the command can be used in a server
/// </summary>
public bool canUseServer => true;
/// <summary> /// <summary>
/// Check if the command require administrator to be executed /// Check if the command require administrator to be executed
/// </summary> /// </summary>
public bool requireAdmin => false; public bool requireAdmin => true;
/// <summary> /// <summary>
/// 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>
/// <param name="message">The command message</param> public async void ExecuteServer(DiscordLibCommands.SocketCommandContext context)
/// <param name="client">The discord bot client</param>
/// <param name="isDM">True if the message was sent from a DM channel, false otherwise</param>
public async void Execute(DiscordLibCommands.SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{ {
if (!DiscordPermissions.hasPermission(message.Author as SocketGuildUser, DiscordLib.GuildPermission.Administrator)) return; var args = Functions.GetArguments(context.Message);
var args = Functions.GetArguments(message);
var OS = Functions.GetOperatingSystem(); var OS = Functions.GetOperatingSystem();
if (args.Count == 0) if (args.Count == 0)
{ {
switch (OS) switch (OS)
{ {
case PluginManager.Others.OperatingSystem.WINDOWS: case OperatingSystem.WINDOWS:
Process.Start("./DiscordBot.exe"); Process.Start("./DiscordBot.exe");
break; break;
case PluginManager.Others.OperatingSystem.LINUX: case OperatingSystem.LINUX:
case PluginManager.Others.OperatingSystem.MAC_OS: case OperatingSystem.MAC_OS:
Process.Start("./DiscordBot"); Process.Start("./DiscordBot");
break; break;
default: default:
return; return;
} }
return; return;
} }
switch (args[0]) switch (args[0])
{ {
case "-p": case "-p":
@@ -80,35 +71,32 @@ namespace DiscordBot.Discord.Commands
break; break;
case "-cmd": case "-cmd":
case "-args": case "-args":
string cmd = "--args"; var cmd = "--args";
if (args.Count > 1) if (args.Count > 1)
for (int i = 1; i < args.Count; i++) for (var i = 1; i < args.Count; i++)
cmd += $" {args[i]}"; cmd += $" {args[i]}";
switch (OS) switch (OS)
{ {
case PluginManager.Others.OperatingSystem.WINDOWS: case OperatingSystem.WINDOWS:
Functions.WriteLogFile("Restarting the bot with the following arguments: \"" + cmd + "\""); Functions.WriteLogFile("Restarting the bot with the following arguments: \"" + cmd + "\"");
Process.Start("./DiscordBot.exe", cmd); Process.Start("./DiscordBot.exe", cmd);
break; break;
case PluginManager.Others.OperatingSystem.LINUX: case OperatingSystem.LINUX:
//case PluginManager.Others.OperatingSystem.MAC_OS: ?? - not tested //case PluginManager.Others.OperatingSystem.MAC_OS: ?? - not tested
Process.Start("./DiscordBot", cmd); Process.Start("./DiscordBot", cmd);
break; break;
default: default:
return; return;
} }
Environment.Exit(0); Environment.Exit(0);
break; break;
default: default:
await context.Channel.SendMessageAsync("Invalid argument. Use `help restart` to see the usage."); await context.Channel.SendMessageAsync("Invalid argument. Use `help restart` to see the usage.");
break; break;
}
} }
} }
} }

View File

@@ -1,27 +1,24 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using DiscordBot.Discord.Core;
using PluginManager; using PluginManager;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using PluginManager.Others;
using PluginManager.Others.Permissions;
namespace DiscordBot.Discord.Commands namespace DiscordBot.Discord.Commands;
{
class Settings : DBCommand
{
internal class Settings : DBCommand
{
/// <summary> /// <summary>
/// Command name /// Command name
/// </summary> /// </summary>
public string Command => "set"; public string Command => "set";
public List<string> Aliases => null;
/// <summary> /// <summary>
/// Command Description /// Command Description
/// </summary> /// </summary>
@@ -32,16 +29,6 @@ namespace DiscordBot.Discord.Commands
/// </summary> /// </summary>
public string Usage => "set [keyword] [new Value]"; public string Usage => "set [keyword] [new Value]";
/// <summary>
/// Check if the command can be used <inheritdoca DM <see cref="IChannel"/>/>
/// </summary>
public bool canUseDM => true;
/// <summary>
/// Check if the command can be used in a server
/// </summary>
public bool canUseServer => true;
/// <summary> /// <summary>
/// Check if the command require administrator to be executed /// Check if the command require administrator to be executed
/// </summary> /// </summary>
@@ -51,17 +38,14 @@ namespace DiscordBot.Discord.Commands
/// 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>
/// <param name="message">The command message</param> public async void Execute(SocketCommandContext context)
/// <param name="client">The discord bot client</param>
/// <param name="isDM">True if the message was sent from a DM channel, false otherwise</param>
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{ {
var channel = message.Channel; var channel = context.Message.Channel;
try try
{ {
string content = message.Content; var content = context.Message.Content;
string[] data = content.Split(' '); var data = content.Split(' ');
string keyword = data[1]; var keyword = data[1];
if (keyword.ToLower() == "help") if (keyword.ToLower() == "help")
{ {
await channel.SendMessageAsync("set token [new value] -- set the value of the new token (require restart)"); await channel.SendMessageAsync("set token [new value] -- set the value of the new token (require restart)");
@@ -101,7 +85,5 @@ namespace DiscordBot.Discord.Commands
Console.WriteLine(ex.Message); Console.WriteLine(ex.Message);
await channel.SendMessageAsync("Unknown usage to this command !\nUsage: " + Usage); await channel.SendMessageAsync("Unknown usage to this command !\nUsage: " + Usage);
} }
}
} }
} }

View File

@@ -1,14 +1,17 @@
using Discord; using System;
using Discord.Commands;
using Discord.WebSocket;
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using PluginManager; using PluginManager;
using static PluginManager.Others.Functions; using static PluginManager.Others.Functions;
namespace DiscordBot.Discord.Core namespace DiscordBot.Discord.Core;
{
internal class Boot internal class Boot
{ {
/// <summary> /// <summary>
@@ -21,13 +24,6 @@ namespace DiscordBot.Discord.Core
/// </summary> /// </summary>
public readonly string botToken; public readonly string botToken;
/// <summary>
/// Checks if the bot is ready
/// </summary>
/// <value> true if the bot is ready, othwerwise false </value>
public bool isReady { get; private set; } = false;
/// <summary> /// <summary>
/// The bot client /// The bot client
/// </summary> /// </summary>
@@ -54,13 +50,22 @@ namespace DiscordBot.Discord.Core
this.botToken = botToken; this.botToken = botToken;
} }
/// <summary>
/// Checks if the bot is ready
/// </summary>
/// <value> true if the bot is ready, othwerwise false </value>
public bool isReady { get; private set; }
/// <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>
/// <returns>Task</returns> /// <returns>Task</returns>
public async Task Awake() public async Task Awake()
{ {
client = new DiscordSocketClient(); DiscordSocketConfig config = new DiscordSocketConfig { AlwaysDownloadUsers = true };
client = new DiscordSocketClient(config);
service = new CommandService(); service = new CommandService();
CommonTasks(); CommonTasks();
@@ -73,7 +78,6 @@ namespace DiscordBot.Discord.Core
await Task.Delay(2000); await Task.Delay(2000);
while (!isReady) ; while (!isReady) ;
} }
private void CommonTasks() private void CommonTasks()
@@ -97,16 +101,6 @@ namespace DiscordBot.Discord.Core
Console.Title = "ONLINE"; Console.Title = "ONLINE";
isReady = true; isReady = true;
new Thread(async () =>
{
while (true)
{
Config.SaveConfig();
Thread.Sleep(10000);
}
}
).Start();
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -114,7 +108,8 @@ namespace DiscordBot.Discord.Core
{ {
Console.Title = "CONNECTED"; Console.Title = "CONNECTED";
WriteLogFile("The bot has been logged in at " + DateTime.Now.ToShortDateString() + " (" + WriteLogFile("The bot has been logged in at " + DateTime.Now.ToShortDateString() + " (" +
DateTime.Now.ToShortTimeString() + ")"); DateTime.Now.ToShortTimeString() + ")"
);
return Task.CompletedTask; return Task.CompletedTask;
} }
@@ -146,5 +141,5 @@ namespace DiscordBot.Discord.Core
return Task.CompletedTask; return Task.CompletedTask;
} }
}
} }

View File

@@ -1,25 +1,21 @@
using Discord.Commands; using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces; using PluginManager.Loaders;
using System.Reflection;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Others.Permissions; using PluginManager.Others.Permissions;
using PluginManager.Loaders;
using System.Threading.Tasks; namespace DiscordBot.Discord.Core;
using System.Linq;
using Discord;
using System;
namespace DiscordBot.Discord.Core
{
internal class CommandHandler internal class CommandHandler
{ {
private readonly string botPrefix;
private readonly DiscordSocketClient client; private readonly DiscordSocketClient client;
private readonly CommandService commandService; private readonly CommandService commandService;
private readonly string botPrefix;
/// <summary> /// <summary>
/// Command handler constructor /// Command handler constructor
@@ -41,7 +37,7 @@ namespace DiscordBot.Discord.Core
public async Task InstallCommandsAsync() public async Task InstallCommandsAsync()
{ {
client.MessageReceived += MessageHandler; client.MessageReceived += MessageHandler;
await commandService.AddModulesAsync(assembly: Assembly.GetEntryAssembly(), services: null); await commandService.AddModulesAsync(Assembly.GetEntryAssembly(), null);
} }
/// <summary> /// <summary>
@@ -58,11 +54,13 @@ namespace DiscordBot.Discord.Core
var message = Message as SocketUserMessage; var message = Message as SocketUserMessage;
if (message == null) return; if (message == null)
return;
if (!message.Content.StartsWith(botPrefix)) return; if (!message.Content.StartsWith(botPrefix))
return;
int argPos = 0; var argPos = 0;
if (message.HasMentionPrefix(client.CurrentUser, ref argPos)) if (message.HasMentionPrefix(client.CurrentUser, ref argPos))
{ {
@@ -70,67 +68,28 @@ namespace DiscordBot.Discord.Core
return; return;
} }
if (message.Author.IsBot) return; if (message.Author.IsBot)
return;
var context = new SocketCommandContext(client, message); var context = new SocketCommandContext(client, message);
await commandService.ExecuteAsync( await commandService.ExecuteAsync(context, argPos, null);
context: context,
argPos: argPos,
services: null
);
DBCommand plugin = PluginLoader.Commands!.Where(p => p.Command == (message.Content.Split(' ')[0]).Substring(botPrefix.Length)).FirstOrDefault(); var plugin = PluginLoader.Commands!.Where(p => p.Command == message.Content.Split(' ')[0].Substring(botPrefix.Length) || (p.Aliases is not null && p.Aliases.Contains(message.Content.Split(' ')[0].Substring(botPrefix.Length)))).FirstOrDefault();
if (plugin is null) throw new System.Exception("Failed to run command. !");
if (plugin != null) if (plugin.requireAdmin && !context.Message.Author.isAdmin())
{
if (message.Channel == await message.Author.CreateDMChannelAsync())
{
if (plugin.canUseDM)
{
if (plugin.requireAdmin)
{
if (message.Author.isAdmin())
{
plugin.Execute(context, message, client, true);
Functions.WriteLogFile($"[{message.Author.Id}] Executed command (DM) : " + plugin.Command);
return;
}
await message.Channel.SendMessageAsync("This command is for administrators only !");
return;
}
plugin.Execute(context, message, client, true);
Functions.WriteLogFile($"[{message.Author.Id}] Executed command (DM) : " + plugin.Command);
return;
}
await message.Channel.SendMessageAsync("This command is not for DMs");
return;
}
if (plugin.canUseServer)
{
if (plugin.requireAdmin)
{
if (message.Author.isAdmin())
{
plugin.Execute(context, message, client, false);
Functions.WriteLogFile($"[{message.Author.Id}] Executed command : " + plugin.Command);
return;
}
await message.Channel.SendMessageAsync("This command is for administrators only !");
return;
}
plugin.Execute(context, message, client, false);
Functions.WriteLogFile($"[{message.Author.Id}] Executed command : " + plugin.Command);
return;
}
return; return;
} if (context.Channel is SocketDMChannel)
} plugin.ExecuteDM(context);
catch { } else plugin.ExecuteServer(context);
} }
catch (System.Exception ex)
{
ex.WriteErrFile();
}
} }
} }

View File

@@ -8,6 +8,7 @@
<StartupObject /> <StartupObject />
<SignAssembly>False</SignAssembly> <SignAssembly>False</SignAssembly>
<IsPublishable>True</IsPublishable> <IsPublishable>True</IsPublishable>
<AssemblyVersion>1.0.0.11</AssemblyVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -37,7 +38,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Discord.Net" Version="3.6.1" /> <PackageReference Include="Discord.Net" Version="3.7.2" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,21 +1,28 @@
using DiscordBot.Discord.Core; using System;
using PluginManager;
using PluginManager.Items;
using PluginManager.Others;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace DiscordBot using Discord;
{
using DiscordBot.Discord.Core;
using PluginManager;
using PluginManager.Items;
using PluginManager.Online;
using PluginManager.Others;
namespace DiscordBot;
public class Program public class Program
{ {
private static bool loadPluginsOnStartup = false; private static bool loadPluginsOnStartup;
private static bool listPluginsAtStartup = false; private static bool listPluginsAtStartup;
private static ConsoleCommandsHandler consoleCommandsHandler;
private static bool listLanguagAtStartup = false;
/// <summary> /// <summary>
/// The main entry point for the application. /// The main entry point for the application.
@@ -24,67 +31,105 @@ namespace DiscordBot
[Obsolete] [Obsolete]
public static void Main(string[] args) public static void Main(string[] args)
{ {
Console.WriteLine("Loading resources ...");
Directory.CreateDirectory("./Data/Resources"); Directory.CreateDirectory("./Data/Resources");
Directory.CreateDirectory("./Data/Languages");
Directory.CreateDirectory("./Data/Plugins/Commands"); Directory.CreateDirectory("./Data/Plugins/Commands");
Directory.CreateDirectory("./Data/Plugins/Events"); Directory.CreateDirectory("./Data/Plugins/Events");
Config.LoadConfig().Wait(); PreLoadComponents().Wait();
if (!Config.ContainsKey("token") || Config.GetValue("token") == null || Config.GetValue("token")?.Length != 70) do
{ {
while (true) if (!Config.ContainsKey("ServerID"))
{
Console.WriteLine("Please enter the server ID: ");
Console_Utilities.WriteColorText("You can find it in the Server Settings at &r\"Widget\"&c section");
Console.WriteLine("Example: 1234567890123456789");
Console.WriteLine("This is not required, but is recommended. If you refuse to provide the ID, just press enter.\nThe server id is required to make easier for the bot to interact with the server.\nRemember: this bot is for one server ONLY.");
Console.Write("User Input > ");
ConsoleKeyInfo key = Console.ReadKey();
if (key.Key == ConsoleKey.Enter)
Config.AddValueToVariables("ServerID", "null", false);
else
{
string SID = key.KeyChar + Console.ReadLine();
if (SID.Length != 18)
{
Console.Clear();
Console_Utilities.WriteColorText("&rYour server ID is not 18 characters long. Please try again. \n");
continue;
}
Config.AddValueToVariables("ServerID", SID, false);
}
}
if (!Config.ContainsKey("token") || Config.GetValue<string>("token") == null || (Config.GetValue<string>("token")?.Length != 70 && Config.GetValue<string>("token")?.Length != 59))
{ {
Console.WriteLine("Please insert your token"); Console.WriteLine("Please insert your token");
Console.Write("Token = "); Console.Write("Token = ");
string token = Console.ReadLine(); var token = Console.ReadLine();
if (token?.Length == 59 || token?.Length == 70) if (token?.Length == 59 || token?.Length == 70)
Config.AddValueToVariables("token", token, true); Config.AddValueToVariables("token", token, true);
else else
{ {
Console.WriteLine("Invalid token"); Console.Clear();
Console_Utilities.WriteColorText("&rThe token length is invalid !");
continue; continue;
} }
}
if (!Config.ContainsKey("prefix") || Config.GetValue<string>("prefix") == null || Config.GetValue<string>("prefix")?.Length != 1)
{
Console.WriteLine("Please insert your prefix (max. 1 character long):"); Console.WriteLine("Please insert your prefix (max. 1 character long):");
Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored. No spaces or numbers allowed"); Console.WriteLine("For a prefix longer then one character, the first character will be saved and the others will be ignored.\n No spaces, numbers, '/' or '\\' allowed");
Console.Write("Prefix = "); Console.Write("Prefix = ");
char prefix = Console.ReadLine()[0]; var prefix = Console.ReadLine()![0];
if (prefix == ' ' || char.IsDigit(prefix)) continue; if (prefix == ' ' || char.IsDigit(prefix) || prefix == '/' || prefix == '\\')
{
Console.Clear();
Console_Utilities.WriteColorText("&rThe prefix is invalid");
continue;
}
Config.AddValueToVariables("prefix", prefix.ToString(), false); Config.AddValueToVariables("prefix", prefix.ToString(), false);
break;
} }
Config.SaveConfig(); break;
} } while (true);
HandleInput(args).Wait(); HandleInput(args).Wait();
} }
/// <summary>
/// Reset all settings for the bot
/// </summary>
private static async Task ResetSettings()
{
string[] files = Directory.GetFiles(@"./Data/Resources");
foreach (string file in files) File.Delete(file);
}
/// <summary> /// <summary>
/// The main loop for the discord bot /// The main loop for the discord bot
/// </summary> /// </summary>
/// <param name="discordbooter">The discord booter used to start the application</param> /// <param name="discordbooter">The discord booter used to start the application</param>
private static Task NoGUI(Boot discordbooter) private static void NoGUI(Boot discordbooter)
{ {
ConsoleCommandsHandler consoleCommandsHandler = new ConsoleCommandsHandler(discordbooter.client);
#if DEBUG
Console.WriteLine();
ConsoleCommandsHandler.ExecuteCommad("lp").Wait();
#else
if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp"); if (loadPluginsOnStartup) consoleCommandsHandler.HandleCommand("lp");
if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs"); if (listPluginsAtStartup) consoleCommandsHandler.HandleCommand("listplugs");
if (listLanguagAtStartup) consoleCommandsHandler.HandleCommand("listlang"); #endif
Config.SaveConfig(); Config.SaveConfig(SaveType.NORMAL).Wait();
while (true) while (true)
{ {
Console.ForegroundColor = ConsoleColor.White;
string cmd = Console.ReadLine(); var cmd = Console.ReadLine();
consoleCommandsHandler.HandleCommand(cmd); if (!consoleCommandsHandler.HandleCommand(cmd!
#if DEBUG
, false
#endif
) && cmd.Length > 0)
Console.WriteLine("Failed to run command " + cmd);
} }
} }
@@ -96,18 +141,53 @@ namespace DiscordBot
{ {
Console.Clear(); Console.Clear();
Console.ForegroundColor = ConsoleColor.DarkYellow; Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Discord BOT for Cross Platform");
Console.WriteLine("Created by: Wizzy\nDiscord: Wizzy#9181");
List<string> startupMessageList = await ServerCom.ReadTextFromURL("https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/StartupMessage");
foreach (var message in startupMessageList)
Console.WriteLine(message);
Console.WriteLine($"Running on version: {Config.GetValue<string>("Version") ?? System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()}");
Console.WriteLine($"Git URL: {Config.GetValue<string>("GitURL") ?? " Could not find Git URL"}");
Console_Utilities.WriteColorText("&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;
Console.WriteLine("============================ Discord BOT - Cross Platform ============================");
string token = Config.GetValue("token");
string prefix = Config.GetValue("prefix");
if (Config.ContainsKey("LaunchMessage"))
{
Console_Utilities.WriteColorText(Config.GetValue<string>("LaunchMessage"));
Config.RemoveKey("LaunchMessage");
}
Console_Utilities.WriteColorText("Please note that the bot saves a backup save file every time you are using the shudown command (&ysd&c)");
Console.WriteLine($"============================ LOG ============================");
try
{
var token = Config.GetValue<string>("token");
#if DEBUG
Console.WriteLine("Starting in DEBUG MODE");
if (!Directory.Exists("./Data/BetaTest"))
Console.WriteLine("Failed to start in debug mode because the folder ./Data/BetaTest does not exist");
else
{
token = File.ReadAllText("./Data/BetaTest/token.txt");
//Debug mode code...
}
#endif
var prefix = Config.GetValue<string>("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)
{
Console.WriteLine(ex);
return null;
}
}
/// <summary> /// <summary>
/// Clear folder /// Clear folder
@@ -115,8 +195,8 @@ namespace DiscordBot
/// <param name="d">Directory path</param> /// <param name="d">Directory path</param>
private static Task ClearFolder(string d) private static Task ClearFolder(string d)
{ {
string[] files = Directory.GetFiles(d); var files = Directory.GetFiles(d);
int fileNumb = files.Length; var fileNumb = files.Length;
for (var i = 0; i < fileNumb; i++) for (var i = 0; i < fileNumb; i++)
{ {
File.Delete(files[i]); File.Delete(files[i]);
@@ -132,57 +212,95 @@ namespace DiscordBot
/// <param name="args">The arguments</param> /// <param name="args">The arguments</param>
private static async Task HandleInput(string[] args) private static async Task HandleInput(string[] args)
{ {
int len = args.Length;
if (len == 1 && args[0] == "--help") var len = args.Length;
if (len == 3 && args[0] == "/download")
{ {
Console.WriteLine("Available commands:\n--exec -> start the bot with tools enabled"); var url = args[1];
var location = args[2];
await ServerCom.DownloadFileAsync(url, location);
return; return;
} }
if (len == 1 && args[0] == "--logout") if (len > 0 && args[0] == "/test")
{ {
File.Delete(Functions.dataFolder + "var.dat"); int p = 1;
await Task.Run(async () => bool allowed = true;
Console.CancelKeyPress += (sender, e) => allowed = false;
Console_Utilities.ProgressBar bar = new(ProgressBarType.NO_END);// { NoColor = false, Color = ConsoleColor.DarkRed };
Console.WriteLine("Press Ctrl + C to stop.");
while (p <= int.MaxValue - 1 && allowed)
{ {
await Task.Delay(1000); bar.Update(100 / p);
Environment.Exit(0x08); await Task.Delay(100);
} p++;
);
return;
} }
if (len >= 2 && args[0] == "--encrypt")
{
string s2e = args.MergeStrings(1);
Console.WriteLine("MD5: " + await Cryptography.CreateMD5(s2e));
Console.WriteLine("SHA356: " + await Cryptography.CreateSHA256(s2e));
return; return;
} }
if (len > 0 && (args.Contains("--cmd") || args.Contains("--args") || args.Contains("--nomessage"))) if (len > 0 && (args.Contains("--cmd") || args.Contains("--args") || args.Contains("--nomessage")))
{ {
if (args.Contains("lp") || args.Contains("loadplugins")) loadPluginsOnStartup = true; if (args.Contains("lp") || args.Contains("loadplugins"))
if (args.Contains("listplugs")) listPluginsAtStartup = true; loadPluginsOnStartup = true;
if (args.Contains("listlang")) listLanguagAtStartup = true; if (args.Contains("listplugs"))
//if (args.Contains("--nomessage")) ShowStartupMessage = false; listPluginsAtStartup = true;
len = 0; len = 0;
} }
if (len == 0 || args[0] != "--exec" && args[0] != "--execute")
var b = await StartNoGUI();
consoleCommandsHandler = new ConsoleCommandsHandler(b.client);
if (len > 0 && args[0] == "/remplug")
{ {
Boot b = await StartNoGUI();
await NoGUI(b); string plugName = Functions.MergeStrings(args, 1);
Console.WriteLine("Starting to remove " + plugName);
await ConsoleCommandsHandler.ExecuteCommad("remplug " + plugName);
loadPluginsOnStartup = true;
len = 0;
}
if (len == 0 || (args[0] != "--exec" && args[0] != "--execute"))
{
Thread mainThread = new Thread(() =>
{
try
{
NoGUI(b);
}
catch (IOException ex)
{
if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9)
{
if (!Config.ContainsKey("LaunchMessage"))
Config.AddValueToVariables("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 !", false);
Functions.WriteErrFile(ex.ToString());
}
}
});
mainThread.Start();
return; return;
} }
Console.ForegroundColor = ConsoleColor.DarkYellow; Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine("Execute command interface noGUI\n\n"); Console.WriteLine("Execute command interface noGUI\n\n");
Console.WriteLine( Console.WriteLine(
"\tCommand name\t\t\t\tDescription\n" + "\tCommand name\t\t\t\tDescription\n" +
"-- help | -help\t\t ------ \tDisplay the help message\n" + "-- help | -help\t\t ------ \tDisplay the help message\n" +
"--reset-full\t\t ------ \tReset all files (clear files)\n" + "--reset-full\t\t ------ \tReset all files (clear files)\n" +
"--reset-settings\t ------ \tReset only bot settings\n" +
"--reset-logs\t\t ------ \tClear up the output folder\n" + "--reset-logs\t\t ------ \tClear up the output folder\n" +
"--start\t\t ------ \tStart the bot\n" + "--start\t\t ------ \tStart the bot\n" +
"exit\t\t\t ------ \tClose the application" "exit\t\t\t ------ \tClose the application"
@@ -191,26 +309,14 @@ namespace DiscordBot
{ {
Console.ForegroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.White;
Console.Write("> "); Console.Write("> ");
string[] message = Console.ReadLine().Split(' '); var message = Console.ReadLine().Split(' ');
switch (message[0]) switch (message[0])
{ {
case "--reset-settings":
await ResetSettings();
Console.WriteLine("Successfully reseted all settings !");
break;
case "--help": case "--help":
case "-help": case "-help":
Console.ForegroundColor = ConsoleColor.DarkYellow; Console.ForegroundColor = ConsoleColor.DarkYellow;
Console.WriteLine( Console.WriteLine("\tCommand name\t\t\t\tDescription\n" + "-- help | -help\t\t ------ \tDisplay the help message\n" + "--reset-full\t\t ------ \tReset all files (clear files)\n" + "--reset-settings\t ------ \tReset only bot settings\n" + "--reset-logs\t\t ------ \tClear up the output folder\n" + "--start\t\t ------ \tStart the bot\n" + "exit\t\t\t ------ \tClose the application");
"\tCommand name\t\t\t\tDescription\n" +
"-- help | -help\t\t ------ \tDisplay the help message\n" +
"--reset-full\t\t ------ \tReset all files (clear files)\n" +
"--reset-settings\t ------ \tReset only bot settings\n" +
"--reset-logs\t\t ------ \tClear up the output folder\n" +
"--start\t\t ------ \tStart the bot\n" +
"exit\t\t\t ------ \tClose the application"
);
break; break;
case "--reset-full": case "--reset-full":
await ClearFolder("./Data/Resources/"); await ClearFolder("./Data/Resources/");
@@ -224,21 +330,108 @@ namespace DiscordBot
case "--reset-logs": case "--reset-logs":
await ClearFolder("./Output/Logs"); await ClearFolder("./Output/Logs");
await ClearFolder("./Output/Errors"); await ClearFolder("./Output/Errors");
Console.WriteLine("Successfully cleard logs folder"); Console.WriteLine("Successfully clear logs folder");
break; break;
case "--exit": case "--exit":
case "exit": case "exit":
Environment.Exit(0); Environment.Exit(0);
break; break;
case "--start":
Boot booter = await StartNoGUI();
await NoGUI(booter);
return;
default: default:
Console.WriteLine("Failed to execute command " + message[0]); Console.WriteLine("Failed to execute command " + message[0]);
break; break;
} }
} }
} }
private static async Task PreLoadComponents()
{
Console_Utilities.ProgressBar main = new Console_Utilities.ProgressBar(ProgressBarType.NO_END);
main.Start();
await Config.LoadConfig();
if (Config.ContainsKey("DeleteLogsAtStartup"))
if (Config.GetValue<bool>("DeleteLogsAtStartup"))
foreach (var file in Directory.GetFiles("./Output/Logs/"))
File.Delete(file);
List<string> OnlineDefaultKeys = await ServerCom.ReadTextFromURL("https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/SetupKeys");
Config.PluginConfig.Load();
if (!Config.ContainsKey("Version"))
Config.AddValueToVariables("Version", Assembly.GetExecutingAssembly().GetName().Version.ToString(), false);
else
Config.SetValue("Version", Assembly.GetExecutingAssembly().GetName().Version.ToString());
foreach (var key in OnlineDefaultKeys)
{
if (key.Length <= 3 || !key.Contains(' ')) continue;
string[] s = key.Split(' ');
try
{
if (Config.ContainsKey(s[0])) Config.SetValue(s[0], s[1]);
else Config.GetAndAddValueToVariable(s[0], s[1], s[2].Equals("true", StringComparison.CurrentCultureIgnoreCase));
}
catch (Exception ex)
{
Functions.WriteErrFile(ex.Message);
}
}
List<string> onlineSettingsList = await ServerCom.ReadTextFromURL("https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/OnlineData");
main.Stop();
foreach (var key in onlineSettingsList)
{
if (key.Length <= 3 || !key.Contains(' ')) continue;
string[] s = key.Split(' ');
switch (s[0])
{
case "CurrentVersion":
string newVersion = s[1];
if (!newVersion.Equals(Config.GetValue<string>("Version")))
{
if (Functions.GetOperatingSystem() == PluginManager.Others.OperatingSystem.WINDOWS)
{
string url = $"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}/net6.0.zip";
//string url2 = $"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}-preview/net6.0.zip";
Process.Start("./Updater/Updater.exe", $"/update {url} ./DiscordBot.exe ./");
}
else
{
string url = $"https://github.com/Wizzy69/SethDiscordBot/releases/download/v{newVersion}/net6.0_linux.zip";
Process.Start("./Updater/Updater", $"/update {url} ./DiscordBot ./");
}
Environment.Exit(0);
}
break;
case "UpdaterVersion":
string updaternewversion = s[1];
if (Config.UpdaterVersion != updaternewversion)
{
Console.Clear();
Console.WriteLine("Installing updater ...\nDo NOT close the bot during update !");
Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END);
bar.Start();
await ServerCom.DownloadFileNoProgressAsync("https://github.com/Wizzy69/installer/releases/download/release-1-discordbot/Updater.zip", "./Updater.zip");
await Functions.ExtractArchive("./Updater.zip", "./", null, UnzipProgressType.PercentageFromTotalSize);
Config.UpdaterVersion = updaternewversion;
File.Delete("Updater.zip");
await Config.SaveConfig(SaveType.NORMAL);
bar.Stop();
Console.Clear();
}
break;
}
}
Console_Utilities.Initialize();
await Config.SaveConfig(SaveType.NORMAL);
Console.Clear();
} }
} }

View File

@@ -1,16 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="250" d:DesignHeight="50"
x:Class="DiscordBotGUI.AppUpdater"
Title="AppUpdater"
Background="Transparent"
TransparencyLevelHint="AcrylicBlur"
HasSystemDecorations="False">
<StackPanel Margin="10">
<TextBlock x:Class="DiscordBotGUI.AppUpdater" x:Name="textBox1" Text="Checking for updates..." />
<ProgressBar IsIndeterminate="True" x:Class="DiscordBotGUI.AppUpdater" x:Name="progressBar1" Foreground="Yellow" />
</StackPanel>
</Window>

View File

@@ -1,171 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using PluginManager.Online;
using PluginManager.Others;
using System.Threading.Tasks;
using System;
using System.IO;
using System.Threading;
using PluginManager;
namespace DiscordBotGUI
{
public partial class AppUpdater : Window
{
private string _version;
public AppUpdater()
{
InitializeComponent();
if (!File.Exists("./Version.txt"))
{
File.WriteAllText("./Version.txt", "DiscordBotVersion=0");
DownloadDiscordBotClientNoGUIAsDLL();
}
if (!File.Exists("./DiscordBot.exe")) DownloadDiscordBotClientNoGUIAsDLL();
Updates();
}
private async void DownloadDiscordBotClientNoGUIAsDLL()
{
//await Task.Delay(5000);
string url_bot_dll = "https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/DiscordBot.zip";
int actiontype = 0; //0 - downolad, 1- extract
IProgress<float> progress = new Progress<float>((percent) =>
{
if (actiontype == 0)
textBox1.Text = "Downloading DiscordBot ... " + MathF.Round(percent, 2) + "%";
else
textBox1.Text = "Extracting package ..." + MathF.Round(percent, 2) + "%";
this.progressBar1.Value = percent;
});
this.progressBar1.IsIndeterminate = false;
try
{
await ServerCom.DownloadFileAsync(url_bot_dll, "./DiscordBot.zip", progress);
actiontype++;
await Functions.ExtractArchive("./DiscordBot.zip", "./", progress);
}
catch
{
textBox1.Text = "Error downloading DiscordBot.dll. Server is not responding.";
await Task.Delay(1000);
new MainWindow() { Height = 425, Width = 500 }.Show();
Close();
}
}
private async void Updates()
{
this.progressBar1.IsIndeterminate = true;
await Task.Delay(1000);
if (!await CheckForUpdates())
{
//await Task.Delay(5000);
textBox1.Text = $"You are running on the latest version ({_version}) !";
await Task.Delay(2000);
new MainWindow() { Height = 425, Width = 650 }.Show();
this.Close();
return;
}
string file = await DownloadNewUpdate();
if (file == null)
{
textBox1.Text = "There was an error while downloading the update !";
await Task.Delay(2000);
new MainWindow() { Height = 425, Width = 650 }.Show();
this.Close();
return;
}
IProgress<float> progress = new Progress<float>((percent) => { this.progressBar1.Value = percent; });
textBox1.Text = "Extracting update files ...";
await Functions.ExtractArchive(file, "./", progress);
progressBar1.IsIndeterminate = true;
textBox1.Text = "Setting up the new version ...";
File.Delete(file);
File.WriteAllText("./Version.txt", "DiscordBotVersion=" + _version);
await Task.Delay(5000);
new MainWindow() { Height = 425, Width = 650 }.Show();
this.Close();
}
private async Task<string> DownloadNewUpdate()
{
string urlNewUpdateZip = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[1];
int secondsPast = 0;
bool isDownloading = true;
this.progressBar1.IsIndeterminate = true;
textBox1.Text = "Downloading update ...";
IProgress<long> downloaded = new Progress<long>((bytes) =>
{
(double, string) download = Functions.ConvertBytes(bytes);
textBox1.Text = $"Downloading update ... {Math.Round(download.Item1 / secondsPast, 2)} {download.Item2}/s";
});
IProgress<float> progress = new Progress<float>((percent) =>
{
progressBar1.IsIndeterminate = false;
this.progressBar1.Value = percent;
});
string FileName = $"{urlNewUpdateZip.Split('/')[urlNewUpdateZip.Split('/').Length - 1]}";
try
{
new Thread(new Task(() =>
{
while (isDownloading)
{
Thread.Sleep(1000);
secondsPast++;
}
}).Start).Start();
await ServerCom.DownloadFileAsync(urlNewUpdateZip, FileName, progress, downloaded);
}
catch
{
textBox1.Text = "Error downloading the update. Server is not responding.";
isDownloading = false;
await Task.Delay(1000);
return null;
}
isDownloading = false;
return FileName;
}
private async Task<bool> CheckForUpdates()
{
try
{
string current_version = Config.GetValue("Version");
if (current_version == null)
if (!Config.SetValue("Version", "0"))
Config.AddValueToVariables("Version", "0", false);
string latest_version = (await ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Updates/Version"))[0];
_version = latest_version;
if (current_version != latest_version) { return true; }
return false;
}
catch (Exception ex)
{
textBox1.Text = "Error while checking for updates. Server is not responding.";
Functions.WriteErrFile(ex.Message);
return false;
}
}
}
}

View File

@@ -1,35 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="425"
x:Class="DiscordBotGUI.MainWindow"
Title="DiscordBotGUI"
Background="Transparent"
TransparencyLevelHint="AcrylicBlur"
ExtendClientAreaToDecorationsHint="True" >
<StackPanel Margin="20">
<Menu>
<MenuItem Header="Plugins">
<MenuItem Header="Commands" x:Class="DiscordBotGUI.MainWindow" x:Name="commandsSettingMenuItem" />
<MenuItem Header="Events" x:Class="DiscordBotGUI.MainWindow" x:Name="eventsSettingMenuItem" />
</MenuItem>
</Menu>
<Label x:Class="DiscordBotGUI.MainWindow" x:Name="label1" Content="Discord Token" />
<TextBox x:Class="DiscordBotGUI.MainWindow" x:Name="textBox1" IsReadOnly="True" TextAlignment="Center" Text=""/>
<Label x:Class="DiscordBotGUI.MainWindow" x:Name="label2" Content="Bot Prefix" />
<TextBox x:Class="DiscordBotGUI.MainWindow" x:Name="textBox2" TextAlignment="Center" HorizontalAlignment="Left" IsReadOnly="True" Text=""/>
<Border Background="Black" Padding="0.5" Margin="25"/>
<Label x:Class="DiscordBotGUI.MainWindow" x:Name="label3" Content="Start Arguments: " />
<TextBox x:Class="DiscordBotGUI.MainWindow" x:Name="textBox3" Width="250" TextAlignment="Center" HorizontalAlignment="Left" IsReadOnly="False" Text=""/>
<Label x:Class="DiscordBotGUI.MainWindow" x:Name="label4" Content="" Foreground="Red" Margin="10"/>
<Button x:Class="DiscordBotGUI.MainWindow" x:Name="button1" HorizontalAlignment="Center" VerticalAlignment="Bottom" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="200" Content="Start Bot" Margin="0,75,0,0" />
<Label x:Class="DiscordBotGUI.MainWindow" x:Name="label5" Content="" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,0,0"/>
</StackPanel>
</Window>

View File

@@ -1,101 +0,0 @@
using Avalonia.Controls;
using System.Threading.Tasks;
using PluginManager.Others;
using System.IO;
using System;
using System.Diagnostics;
using DiscordBotGUI.Settings;
using Avalonia.Themes.Fluent;
using PluginManager;
namespace DiscordBotGUI
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LoadElements();
}
private void LoadElements()
{
textBox3.Watermark = "Insert start arguments";
if (File.Exists("./Version.txt")) label5.Content = Config.GetValue("Version");
button1.Click += async (sender, e) =>
{
string token = textBox1.Text;
string prefix = textBox2.Text;
string args = "--nomessage " + textBox3.Text;
if (!((token.Length == 70 || token.Length == 59) && prefix.Length == 1))
{
label4.Content = "Invalid Token or Prefix.\n(Prefix must be 1 character long and token must be 59 or 79 characters long)";
await Task.Delay(5000);
label4.Content = "";
return;
}
Config.SetValue("token", token);
Config.SetValue("prefix", prefix);
RunDiscordBot(args);
};
commandsSettingMenuItem.Click += (sender, e) => new Commands() /*{ Height = 200, Width = 550 }*/.ShowDialog(this);
eventsSettingMenuItem.Click += (sender, e) => new Events() /*{ Height = 200, Width = 550 }*/.ShowDialog(this);
string folder = $"{Functions.dataFolder}DiscordBotCore.data";
Directory.CreateDirectory(Functions.dataFolder);
try
{
string? botToken = Config.GetValue("token") as string;
string? botPrefix = Config.GetValue("prefix") as string;
if (botToken == null || botPrefix == null)
{
textBox1.IsReadOnly = false;
textBox2.IsReadOnly = false;
textBox1.Watermark = "Insert Bot Token Here";
textBox2.Watermark = "Insert Bot Prefix Here";
}
else
{
textBox1.Text = botToken;
textBox2.Text = botPrefix;
}
}
catch
{
textBox1.IsReadOnly = false;
textBox2.IsReadOnly = false;
textBox1.Watermark = "Insert Bot Token Here";
textBox2.Watermark = "Insert Bot Prefix Here";
}
}
private void RunDiscordBot(string args)
{
var os = Functions.GetOperatingSystem();
if (os == PluginManager.Others.OperatingSystem.WINDOWS)
Process.Start("./DiscordBot.exe", args);
else if (os == PluginManager.Others.OperatingSystem.LINUX)
Process.Start("./DiscordBot", args);
else if (os == PluginManager.Others.OperatingSystem.MAC_OS)
Process.Start("./DiscordBot.app/Contents/MacOS/DiscordBot", args);
Close();
return;
}
}
}

View File

@@ -1,21 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="550" d:DesignHeight="200"
x:Class="DiscordBotGUI.Settings.Commands"
Title="Commands"
Background="Transparent"
TransparencyLevelHint="AcrylicBlur"
ExtendClientAreaToDecorationsHint="True">
<StackPanel x:Class="DiscordBotGUI.Settings.Commands" x:Name="stackpanel1" Margin="10">
<Label Content="Installed Commands" />
<TextBox x:Class="DiscordBotGUI.Settings.Commands" x:Name="textbox1" TextAlignment="Left" IsReadOnly="True" />
<Label Content="Install another command" />
<ComboBox x:Class="DiscordBotGUI.Settings.Commands" x:Name="comboBox1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,10" Padding="200,0" />
<Button x:Class="DiscordBotGUI.Settings.Commands" x:Name="button1" HorizontalAlignment="Left" Content="Install" />
<ProgressBar x:Class="DiscordBotGUI.Settings.Commands" x:Name="progressBar1" HorizontalAlignment="Left" Margin="0,10" Foreground="Yellow" />
<Label x:Class="DiscordBotGUI.Settings.Commands" x:Name="label1" Content="" HorizontalAlignment="Left" Margin="0,10" />
</StackPanel>
</Window>

View File

@@ -1,138 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using PluginManager.Others;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using System;
using System.IO;
namespace DiscordBotGUI.Settings
{
public partial class Commands : Window
{
List<string> commands = new List<string>();
public Commands()
{
InitializeComponent();
LoadData();
LoadComboBox();
button1.Click += async (sender, e) =>
{
await Download();
};
}
private void LoadData()
{
try
{
textbox1.Text = "";
Directory.CreateDirectory("./Data/Plugins/Commands/");
var files = System.IO.Directory.EnumerateFiles("./Data/Plugins/Commands/");
if (files == null || files.Count() < 1) return;
foreach (var file in files)
textbox1.Text += file.Split('/')[file.Split('/').Length - 1] + "\n";
}
catch { }
}
private async void LoadComboBox()
{
comboBox1.Items = null;
commands = await PluginManager.Online.ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Plugins");
if (commands == null) return;
string[] plugins = commands.ToArray();
string OS;
var OSG = Functions.GetOperatingSystem();
if (OSG == PluginManager.Others.OperatingSystem.WINDOWS) OS = "Windows";
else if (OSG == PluginManager.Others.OperatingSystem.LINUX) OS = "Linux";
else OS = "MAC_OS";
List<string> data = new List<string>();
for (int i = 0; i < plugins.Length; i++)
{
if (!plugins[i].Contains(OS) || !plugins[i].Contains("Commands"))
continue;
string[] info = plugins[i].Split(',');
try
{
if (System.IO.Directory.EnumerateFiles("./Data/Plugins/Commands/").Any(x => x.EndsWith(info[0] + ".dll")))
continue;
}
catch { }
data.Add($"{info[0]} - {info[1]} - {info[2]}");
}
comboBox1.Items = data;
}
private async Task Download()
{
if (comboBox1 == null || comboBox1.SelectedIndex == -1 || comboBox1.SelectedItem == null)
return;
string? pluginName = comboBox1?.SelectedItem?.ToString()?.Split('-')[0].Trim();
if (pluginName == null) return;
string? URL = (from s in commands
where s.StartsWith(pluginName)
select s.Split(',')[3].Trim()).FirstOrDefault();
if (URL == null) return;
IProgress<float> progress = new Progress<float>(async value =>
{
label1.Content = $"Downloading {pluginName} {MathF.Round(value, 2)}%";
if (value == 1f)
{
label1.Content = "Successfully Downloaded " + pluginName;
LoadData();
LoadComboBox();
await Task.Delay(5000);
label1.Content = "";
}
progressBar1.Value = value;
});
await PluginManager.Online.ServerCom.DownloadFileAsync(URL, "./Data/Plugins/Commands/" + pluginName + ".dll", progress);
string? requirements = (from s in commands
where s.StartsWith(pluginName) && s.Split(',').Length == 6
select s.Split(',')[5].Trim()).FirstOrDefault();
if (requirements == null) return;
List<string> req = await PluginManager.Online.ServerCom.ReadTextFromFile(requirements);
if (req == null) return;
foreach (var requirement in req)
{
string[] info = requirement.Split(',');
pluginName = info[1];
progress.Report(0);
await PluginManager.Online.ServerCom.DownloadFileAsync(info[0], $"./{info[1]}", progress);
await Task.Delay(1000);
if (info[0].EndsWith(".zip"))
{
await Functions.ExtractArchive("./" + info[1], "./", progress);
await Task.Delay(1000);
}
}
progress.Report(100f);
label1.Content = "Downloaded";
progressBar1.Value = 100;
}
}
}

View File

@@ -1,20 +0,0 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="550" d:DesignHeight="200"
x:Class="DiscordBotGUI.Settings.Events"
Title="Events"
Background="Transparent"
TransparencyLevelHint="AcrylicBlur"
ExtendClientAreaToDecorationsHint="True">
<StackPanel Margin="10">
<Label Content="Installed Events" />
<TextBox x:Class="DiscordBotGUI.Settings.Events" x:Name="textbox1" TextAlignment="Left" IsReadOnly="True" />
<Label Content="Install another Events" />
<ComboBox x:Class="DiscordBotGUI.Settings.Events" x:Name="comboBox1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,10" Padding="200,0" />
<Button x:Class="DiscordBotGUI.Settings.Events" x:Name="button1" HorizontalAlignment="Left" Content="Install" />
<ProgressBar x:Class="DiscordBotGUI.Settings.Events" x:Name="progressBar1" HorizontalAlignment="Left" Margin="0,10" Foreground="Yellow" />
<Label x:Class="DiscordBotGUI.Settings.Events" x:Name="label1" Content="" HorizontalAlignment="Left" Margin="0,10" />
</StackPanel>
</Window>

View File

@@ -1,139 +0,0 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using PluginManager.Others;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Reflection.Emit;
using System.Threading.Tasks;
using static PluginManager.Others.Console_Utilities;
using System.IO;
namespace DiscordBotGUI.Settings
{
public partial class Events : Window
{
List<string> events = new List<string>();
public Events()
{
InitializeComponent();
LoadData();
LoadComboBox();
button1.Click += async (sender, e) =>
{
await Download();
};
}
private void LoadData()
{
//Read components from Commands Folder:
//textbox1 = new TextBox();
try
{
Directory.CreateDirectory("./Data/Plugins/Events/");
textbox1.IsReadOnly = false;
textbox1.Text = "";
var files = System.IO.Directory.EnumerateFiles("./Data/Plugins/Events/");
if (files == null || files.Count() < 1) return;
foreach (var file in files)
textbox1.Text += file.Split('/')[file.Split('/').Length - 1] + "\n";
}
catch { }
}
private async void LoadComboBox()
{
comboBox1.Items = null;
events = await PluginManager.Online.ServerCom.ReadTextFromFile("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Plugins");
if (events == null) return;
string[] plugins = events.ToArray();
string OS;
var OSG = Functions.GetOperatingSystem();
if (OSG == PluginManager.Others.OperatingSystem.WINDOWS) OS = "Windows";
else if (OSG == PluginManager.Others.OperatingSystem.LINUX) OS = "Linux";
else OS = "MAC_OS";
List<string> data = new List<string>();
for (int i = 0; i < plugins.Length; i++)
{
if (!plugins[i].Contains(OS) || !plugins[i].Contains("Event"))
continue;
string[] info = plugins[i].Split(',');
try
{
if (System.IO.Directory.EnumerateFiles("./Data/Plugins/Events/").Any(x => x.EndsWith(info[0] + ".dll")))
continue;
}
catch { }
data.Add($"{info[0]} - {info[1]} - {info[2]}");
}
comboBox1.Items = data;
}
private async Task Download()
{
if (comboBox1 == null || comboBox1.SelectedIndex == -1 || comboBox1.SelectedItem == null)
return;
string? pluginName = comboBox1?.SelectedItem?.ToString()?.Split('-')[0].Trim();
if (pluginName == null) return;
string? URL = (from s in events
where s.StartsWith(pluginName)
select s.Split(',')[3].Trim()).FirstOrDefault();
if (URL == null) return;
IProgress<float> progress = new Progress<float>(async value =>
{
label1.Content = $"Downloading {pluginName} {MathF.Round(value, 2)}%";
if (value == 1f)
{
label1.Content = "Successfully Downloaded " + pluginName;
LoadData();
LoadComboBox();
await Task.Delay(5000);
label1.Content = "";
}
progressBar1.Value = value;
});
await PluginManager.Online.ServerCom.DownloadFileAsync(URL, "./Data/Plugins/Events/" + pluginName + ".dll", progress);
string? requirements = (from s in events
where s.StartsWith(pluginName) && s.Split(',').Length == 6
select s.Split(',')[5].Trim()).FirstOrDefault();
if (requirements == null) return;
List<string> req = await PluginManager.Online.ServerCom.ReadTextFromFile(requirements);
if (req == null) return;
foreach (var requirement in req)
{
string[] info = requirement.Split(',');
pluginName = info[1];
progress.Report(0);
await PluginManager.Online.ServerCom.DownloadFileAsync(info[0], $"./{info[1]}", progress);
await Task.Delay(1000);
if (info[0].EndsWith(".zip"))
{
await Functions.ExtractArchive("./" + info[1], "./", progress);
await Task.Delay(1000);
}
}
label1.Content = "";
}
}
}

View File

@@ -4,7 +4,7 @@
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<BaseOutputPath>..\DiscordBot\bin\Debug\net6.0\Data\Plugins\Events\LevelingSystem</BaseOutputPath> <BaseOutputPath></BaseOutputPath>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,5 +1,8 @@
using Discord.WebSocket; using Discord;
using Discord.WebSocket;
using EVE_LevelingSystem.LevelingSystemCore; using EVE_LevelingSystem.LevelingSystemCore;
using PluginManager; using PluginManager;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using PluginManager.Others; using PluginManager.Others;
@@ -10,22 +13,25 @@ namespace EVE_LevelingSystem
{ {
public string name => "Leveling System Event Handler"; public string name => "Leveling System Event Handler";
public string description => "The Leveling System Event Handler"; public string description => "The Leveling System Event Handler";
internal static Settings globalSettings = new(); internal static Settings globalSettings = new();
public async void Start(DiscordSocketClient client) public async void Start(DiscordSocketClient client)
{ {
Directory.CreateDirectory("./Data/Resources/LevelingSystem"); Directory.CreateDirectory("./Data/Resources/LevelingSystem");
if (!Config.ContainsKey("LevelingSystemPath"))
Config.AddValueToVariables("LevelingSystemPath", "./Data/Resources/LevelingSystem", true); Config.AddValueToVariables("LevelingSystemPath", "./Data/Resources/LevelingSystem", true);
if (!Config.ContainsKey("LevelingSystemSettingsFile"))
Config.AddValueToVariables("LevelingSystemSettingsFile", "./Data/Resources/LevelingSystemSettings.txt", true); Config.AddValueToVariables("LevelingSystemSettingsFile", "./Data/Resources/LevelingSystemSettings.txt", true);
//PluginManager.Config.AddValueToVariables
if (!File.Exists(Config.GetValue("LevelingSystemSettingsFile"))) if (!File.Exists(Config.GetValue<string>("LevelingSystemSettingsFile")))
{ {
globalSettings = new Settings { TimeToWaitBetweenMessages = 5 }; globalSettings = new Settings { TimeToWaitBetweenMessages = 5 };
await Functions.SaveToJsonFile<Settings>(Config.GetValue("LevelingSystemSettingsFile"), globalSettings); await Functions.SaveToJsonFile<Settings>(Config.GetValue<string>("LevelingSystemSettingsFile"), globalSettings);
} }
else else
globalSettings = await Functions.ConvertFromJson<Settings>(Config.GetValue("LevelingSystemSettingsFile")); globalSettings = await Functions.ConvertFromJson<Settings>(Config.GetValue<string>("LevelingSystemSettingsFile"));
// Console.WriteLine(globalSettings.TimeToWaitBetweenMessages); // Console.WriteLine(globalSettings.TimeToWaitBetweenMessages);
client.MessageReceived += ClientOnMessageReceived; client.MessageReceived += ClientOnMessageReceived;
@@ -33,21 +39,21 @@ namespace EVE_LevelingSystem
private async Task ClientOnMessageReceived(SocketMessage arg) private async Task ClientOnMessageReceived(SocketMessage arg)
{ {
if (arg.Author.IsBot || arg.IsTTS || arg.Content.StartsWith(Config.GetValue("prefix"))) return; if (arg.Author.IsBot || arg.IsTTS || arg.Content.StartsWith(Config.GetValue<string>("prefix"))) return;
string userID = arg.Author.Id.ToString(); string userID = arg.Author.Id.ToString();
User user; User user;
if (File.Exists($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat")) if (File.Exists($"{Config.GetValue<string>("LevelingSystemPath")}/{userID}.dat"))
{ {
user = await Functions.ConvertFromJson<User>(Config.GetValue("LevelingSystemPath")! + $"/{userID}.dat"); user = await Functions.ConvertFromJson<User>(Config.GetValue<string>("LevelingSystemPath")! + $"/{userID}.dat");
// Console.WriteLine(Config.GetValue("LevelingSystemPath")); // Console.WriteLine(Config.GetValue("LevelingSystemPath"));
if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}"); if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}");
await Functions.SaveToJsonFile(Config.GetValue("LevelingSystemPath") + $"/{userID}.dat", user); await Functions.SaveToJsonFile(Config.GetValue<string>("LevelingSystemPath") + $"/{userID}.dat", user);
return; return;
} }
user = new User() { CurrentEXP = 0, CurrentLevel = 1, RequiredEXPToLevelUp = LevelCalculator.GetNextLevelRequiredEXP(1), userID = userID }; user = new User { CurrentEXP = 0, CurrentLevel = 1, RequiredEXPToLevelUp = LevelCalculator.GetNextLevelRequiredEXP(1), user = new DiscordUser { DiscordTag = arg.Author.DiscriminatorValue, userID = arg.Author.Id, Username = arg.Author.Username } };
if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}"); if (user.AddEXP()) await arg.Channel.SendMessageAsync($"{arg.Author.Mention} is now level {user.CurrentLevel}");
await Functions.SaveToJsonFile($"{Config.GetValue("LevelingSystemPath")}/{userID}.dat", user); await Functions.SaveToJsonFile<User>($"{Config.GetValue<string>("LevelingSystemPath")}/{userID}.dat", user);
} }
} }
} }

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using PluginManager; using PluginManager;
namespace EVE_LevelingSystem.LevelingSystemCore namespace EVE_LevelingSystem.LevelingSystemCore
@@ -25,31 +26,31 @@ namespace EVE_LevelingSystem.LevelingSystemCore
internal static bool AddEXP(this User user) internal static bool AddEXP(this User user)
{ {
if (OnWaitingList.Contains(user.userID)) return false; if (OnWaitingList.Contains(user.user.userID.ToString())) return false;
Random r = new Random(); Random r = new Random();
int exp = r.Next(2, 12); int exp = r.Next(Level.globalSettings.MinEXP, Level.globalSettings.MaxEXP + 1);
Int64 userXP = user.CurrentEXP; Int64 userXP = user.CurrentEXP;
Int64 reqEXP = user.RequiredEXPToLevelUp; Int64 reqEXP = user.RequiredEXPToLevelUp;
if (userXP + exp >= reqEXP) if (userXP + exp >= reqEXP)
{ {
user.LevelUp(); user.LevelUp();
user.CurrentEXP = exp - (reqEXP - userXP); user.CurrentEXP = exp - (reqEXP - userXP);
Console.WriteLine("Level up"); //Console.WriteLine("Level up");
return true; return true;
} }
user.CurrentEXP += exp; user.CurrentEXP += exp;
OnWaitingList.Add(user.userID); OnWaitingList.Add(user.user.userID.ToString());
new Thread(() => new Thread(() =>
{ {
int minutesToWait = Level.globalSettings.TimeToWaitBetweenMessages; int minutesToWait = Level.globalSettings.TimeToWaitBetweenMessages;
Thread.Sleep(60000 * minutesToWait); Thread.Sleep(60000 * minutesToWait);
OnWaitingList.Remove(user.userID); OnWaitingList.Remove(user.user.userID.ToString());
} }
); ).Start();
return false; return false;
} }

View File

@@ -1,16 +1,20 @@
using System; using Discord;
using System.Collections.Generic; using Discord.WebSocket;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EVE_LevelingSystem.LevelingSystemCore namespace EVE_LevelingSystem.LevelingSystemCore
{ {
public class DiscordUser
{
public string Username { get; set; }
public ushort DiscordTag { get; set; }
public ulong userID { get; set; }
}
public class User public class User
{ {
public string userID { get; set; } public DiscordUser user { get; set; }
public int CurrentLevel { get; set; } public int CurrentLevel { get; set; }
public Int64 CurrentEXP { get; set; } public long CurrentEXP { get; set; }
public Int64 RequiredEXPToLevelUp { get; set; } public long RequiredEXPToLevelUp { get; set; }
} }
} }

View File

@@ -9,5 +9,7 @@ namespace EVE_LevelingSystem
public class Settings public class Settings
{ {
public int TimeToWaitBetweenMessages { get; set; } public int TimeToWaitBetweenMessages { get; set; }
public int MinEXP { get; set; }
public int MaxEXP { get; set; }
} }
} }

View File

@@ -0,0 +1,24 @@
using Discord.Commands;
using PluginManager.Interfaces;
namespace FreeGamesModule
{
public class Free : DBCommand
{
public string Command => "free";
public List<string>? Aliases => null;
public string Description => "Check out any free game";
public string Usage => "free";
public bool requireAdmin => false;
public void ExecuteServer(SocketCommandContext context)
{
}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PluginManager\PluginManager.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,35 @@
using AngleSharp.Dom;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MusicCommands
{
internal class AudioFile
{
internal string Name { get; set; }
internal string Url { get; set; }
internal AudioFile(string name, string url)
{
Name = name;
Url = url;
}
internal async Task DownloadAudioFile()
{
Process proc = new Process();
proc.StartInfo.FileName = "MusicDownloader";
proc.StartInfo.Arguments = $"{Url},{Name}";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start();
await proc.WaitForExitAsync();
}
}
}

View File

@@ -1,15 +1,13 @@
using Discord; using Discord;
using Discord.Audio; using Discord.Audio;
using MusicCommands; namespace MusicCommands;
namespace CMD_Utils.Music
{
internal static class Data internal static class Data
{ {
internal static IAudioClient audioClient = null; internal static IAudioClient audioClient = null;
internal static IVoiceChannel voiceChannel = null; internal static IVoiceChannel voiceChannel = null;
internal static MusicPlayer CurrentlyRunning = null; internal static MusicPlayer MusicPlayer = null;
} internal static MusicPlaylist Playlist = new();
} }

View File

@@ -1,39 +1,42 @@
using Discord.Commands; using System.Collections.Generic;
using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using System; namespace MusicCommands;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMD_Utils.Music internal class Leave : DBCommand
{
class Leave : DBCommand
{ {
public string Command => "leave"; public string Command => "leave";
public List<string> Aliases => null;
public string Description => "Leave the voice channel"; public string Description => "Leave the voice channel";
public string Usage => "leave"; public string Usage => "leave";
public bool canUseDM => false;
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(SocketCommandContext context)
{ {
if (Data.audioClient is not null && Data.voiceChannel is not null) if (Data.audioClient is not null && Data.voiceChannel is not null)
{ {
Data.CurrentlyRunning.Stop();
Data.CurrentlyRunning = null;
await Data.audioClient.StopAsync(); await Data.audioClient.StopAsync();
await Data.voiceChannel.DisconnectAsync(); await Data.voiceChannel.DisconnectAsync();
} }
if (Data.Playlist is not null)
{
Data.Playlist.ClearQueue();
Data.Playlist = new();
}
if (Data.MusicPlayer is not null)
{
Data.MusicPlayer.Stop();
Data.MusicPlayer = null;
} }
} }
} }

View File

@@ -3,6 +3,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<Nullable>warnings</Nullable> <Nullable>warnings</Nullable>
<BaseOutputPath>bin\</BaseOutputPath>
<AssemblyName>Music Commands</AssemblyName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -16,4 +18,8 @@
<ProjectReference Include="..\PluginManager\PluginManager.csproj" /> <ProjectReference Include="..\PluginManager\PluginManager.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="YoutubeExplode" Version="6.2.0" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,122 +1,53 @@
using CMD_Utils.Music; using System.IO;
using PluginManager.Others;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace MusicCommands namespace MusicCommands;
internal class MusicPlayer
{ {
class MusicPlayer private Stream outputStream { get; }
internal AudioFile NowPlaying = null;
internal bool isPlaying, isPaused;
public MusicPlayer(Stream outputChannel)
{ {
public Stream inputStream { get; private set; } // from FFMPEG outputStream = outputChannel;
public Stream outputStream { get; private set; } // to Voice Channel
public MusicPlayer(Stream input, Stream output)
{
inputStream = input;
outputStream = output;
} }
public MusicPlayer(Stream output) public async Task Play(Stream source, int byteSize, AudioFile songPlaying)
{ {
inputStream = null; isPlaying = true;
outputStream = output; NowPlaying = songPlaying;
} while (isPlaying)
{
if (isPaused)
continue;
public bool Paused { get; set; } var bits = new byte[byteSize];
private bool _stop { get; set; } var read = await source.ReadAsync(bits, 0, byteSize);
public void Stop() if (read == 0)
{
_stop = true;
}
public async Task StartSendAudioFromLink(string URL)
{
/* using (HttpClient client = new HttpClient())
using (HttpResponseMessage response = await client.GetAsync(URL))
using (var content = response.Content)
{
await (await content.ReadAsStreamAsync()).CopyToAsync(outputStream);
}*/
Stream ms = new MemoryStream();
int bsize = 512;
new Thread(async delegate (object o)
{
var response = await new HttpClient().GetAsync(URL);
using (var stream = await response.Content.ReadAsStreamAsync())
{
byte[] buffer = new byte[bsize];
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
var pos = ms.Position;
ms.Position = ms.Length;
ms.Write(buffer, 0, read);
ms.Position = pos;
}
}
}).Start();
Console.Write("Reading data: ");
while (ms.Length < bsize * 10)
{
await Task.Delay(1000);
Console.Title = "Reading data: " + ms.Length + " bytes read of " + bsize * 10;
Console.Write(".");
}
Console.WriteLine("\nDone");
ms.Position = 0;
_stop = false;
Paused = false;
while (!_stop)
{
if (Paused) continue;
byte[] buffer = new byte[bsize];
int read = await ms.ReadAsync(buffer, 0, buffer.Length);
if (read > 0)
await outputStream.WriteAsync(buffer, 0, read);
else break;
}
}
public async Task StartSendAudio()
{
Paused = false;
_stop = false;
while (!_stop)
{
if (Paused) continue;
int bsize = 512;
byte[] buffer = new byte[bsize];
var bcount = await inputStream.ReadAsync(buffer, 0, bsize);
if (bcount <= 0)
{
Stop();
Data.CurrentlyRunning = null;
break; break;
}
try try
{ {
await outputStream.WriteAsync(buffer, 0, bcount); await outputStream.WriteAsync(bits, 0, read);
} }
catch (Exception ex) catch
{ {
await outputStream.FlushAsync(); break;
Functions.WriteLogFile(ex.ToString()); }
} }
}
} await source.FlushAsync();
await source.DisposeAsync();
source.Close();
await outputStream.FlushAsync();
isPlaying = false;
}
public void Stop()
{
isPlaying = false;
} }
} }

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MusicCommands
{
internal class MusicPlaylist
{
internal MusicPlaylist()
{
Console.WriteLine("Initialized playlist.");
}
public Queue<AudioFile> QueueList = new();
public void Enqueue(AudioFile query) => QueueList.Enqueue(query);
public void ClearQueue() => QueueList.Clear();
public int Count => QueueList.Count;
public AudioFile GetNextSong => QueueList.Dequeue();
public AudioFile WhatIsNext => QueueList.Peek();
}
}

View File

@@ -1,27 +1,26 @@
using Discord.Commands; using System.Collections.Generic;
using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Interfaces; using PluginManager.Interfaces;
namespace CMD_Utils.Music namespace MusicCommands;
{
class Pause : DBCommand internal class Pause : DBCommand
{ {
public string Command => "pause"; public string Command => "pause";
public string Description => "Pause the music"; public List<string> Aliases => null;
public string Description => "Pause/Unpause the music that is currently running";
public string Usage => "pause"; public string Usage => "pause";
public bool canUseDM => false;
public bool canUseServer => true;
public bool requireAdmin => false; public bool requireAdmin => false;
public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM) public void ExecuteServer(SocketCommandContext context)
{ {
Data.CurrentlyRunning.Paused = true; Data.MusicPlayer.isPaused = !Data.MusicPlayer.isPaused;
}
} }
} }

View File

@@ -1,70 +1,117 @@
using Discord; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Discord;
using Discord.Audio; using Discord.Audio;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using MusicCommands;
using PluginManager.Interfaces; using PluginManager.Interfaces;
using PluginManager.Others; using PluginManager.Others;
using System; namespace MusicCommands;
using System.Diagnostics;
using System.IO;
namespace CMD_Utils.Music internal class Play : DBCommand
{ {
class Play : DBCommand public string Command => "play";
{
public string Command => "fplay"; public List<string> Aliases => new() { "p" };
public string Description => "Play music from a file"; public string Description => "Play music from a file";
public string Usage => "fplay [name]"; public string Usage => "play [name/url]";
public bool canUseDM => false;
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(SocketCommandContext context)
{ {
string path = "./Music"; Directory.CreateDirectory("Music");
string FileName = Functions.GetArguments(message).ToArray().MergeStrings(0); var path = "./Music/";
path += "/" + FileName + ".mp3"; string[] splitted = context.Message.Content.Split(' ');
if (!File.Exists(path)) if (splitted.Length < 2)
return;
do
{ {
Console.WriteLine("Unknown path " + path); if (splitted.Length == 2 && splitted[1].Contains("youtube.com") || splitted[1].Contains("youtu.be"))
{
var url = splitted[1];
path += $"{Functions.CreateMD5(url)}";
if (File.Exists(path))
{
Data.Playlist.Enqueue(new AudioFile(path, null));
}
else
{
var file = new AudioFile(path, url);
await file.DownloadAudioFile();
Data.Playlist.Enqueue(file);
}
}
else
{
var searchString = splitted.MergeStrings(1);
path += $"{Functions.CreateMD5(searchString)}";
if (File.Exists(path))
{
Data.Playlist.Enqueue(new AudioFile(path, null));
}
else
{
await context.Channel.SendMessageAsync("Searching for " + searchString);
var file = new AudioFile(path, searchString);
await file.DownloadAudioFile();
Data.Playlist.Enqueue(file);
if (Data.MusicPlayer is null)
await context.Channel.SendMessageAsync("Playing: " + searchString);
}
}
if (Data.MusicPlayer is not null)
{
await context.Channel.SendMessageAsync("Queued your request: " + splitted.MergeStrings(1));
return; return;
} }
}
while (false); // run only one time !
Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel; Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel;
if (Data.voiceChannel == null) { await context.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; }
Data.audioClient = await Data.voiceChannel.ConnectAsync(); if (Data.voiceChannel == null)
using (var ffmpeg = CreateStream(path))
using (var output = ffmpeg.StandardOutput.BaseStream)
using (var discord = Data.audioClient.CreatePCMStream(AudioApplication.Mixed))
{ {
if (Data.CurrentlyRunning != null) await context.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument.");
Data.CurrentlyRunning.Stop(); return;
Data.CurrentlyRunning = new MusicPlayer(output, discord); }
await Data.CurrentlyRunning.StartSendAudio();
if (Data.audioClient is null)
{
Data.audioClient = await Data.voiceChannel.ConnectAsync(true);
Data.MusicPlayer = null;
}
using (var discordChanneAudioOutStream = Data.audioClient.CreatePCMStream(AudioApplication.Mixed))
{
Data.MusicPlayer ??= new MusicPlayer(discordChanneAudioOutStream);
while (Data.Playlist.Count > 0)
{
var nowPlaying = Data.Playlist.GetNextSong;
using (var ffmpeg = CreateStream(nowPlaying.Name))
using (var ffmpegOutputBaseStream = ffmpeg.StandardOutput.BaseStream)
{
await Data.MusicPlayer.Play(ffmpegOutputBaseStream, 1024, nowPlaying);
Console.WriteLine("Finished playing from " + nowPlaying.Url);
} }
} }
private Process CreateStream(string path) Data.MusicPlayer = null;
}
}
private static Process CreateStream(string path)
{ {
return Process.Start(new ProcessStartInfo return Process.Start(new ProcessStartInfo { FileName = "ffmpeg", Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1", UseShellExecute = false, RedirectStandardOutput = true });
{
FileName = "ffmpeg",
Arguments = $"-hide_banner -loglevel panic -i \"{path}\" -ac 2 -f s16le -ar 48000 pipe:1",
UseShellExecute = false,
RedirectStandardOutput = true,
});
}
} }
} }

40
MusicCommands/Skip.cs Normal file
View File

@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket;
using PluginManager.Interfaces;
namespace MusicCommands
{
public class Skip : DBCommand
{
public string Command => "skip";
public List<string> Aliases => null;
public string Description => "skip the music that is currently running";
public string Usage => "skip";
public bool requireAdmin => false;
public async void ExecuteServer(SocketCommandContext context)
{
var loadedSong = Data.MusicPlayer.NowPlaying;
if (loadedSong is null || Data.MusicPlayer.isPlaying == false)
{
await context.Message.Channel.SendMessageAsync("There is no music playing");
return;
}
Data.MusicPlayer.isPlaying = false;
await context.Message.Channel.SendMessageAsync($"You have skipped {loadedSong.Name}");
}
}
}

View File

@@ -1,35 +0,0 @@
using CMD_Utils.Music;
using Discord.Commands;
using Discord.WebSocket;
using PluginManager.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MusicCommands
{
class Unpause : DBCommand
{
public string Command => "unpause";
public string Description => "Unpause the music";
public string Usage => "unpause";
public bool canUseDM => false;
public bool canUseServer => true;
public bool requireAdmin => false;
public void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{
Data.CurrentlyRunning.Paused = false;
}
}
}

View File

@@ -1,52 +0,0 @@
using CMD_Utils.Music;
using Discord.Audio;
using Discord.Commands;
using Discord.WebSocket;
using Discord;
using PluginManager.Interfaces;
namespace MusicCommands
{
class lplay : DBCommand
{
public string Command => "lplay";
public string Description => "Play music from a link";
public string Usage => "lplay [url]";
public bool canUseDM => false;
public bool canUseServer => false;
public bool requireAdmin => false;
public async void Execute(SocketCommandContext context, SocketMessage message, DiscordSocketClient client, bool isDM)
{
string URL = message.Content.Split(' ')[1];
if (!URL.EndsWith(".mp3") && !URL.EndsWith(".wav") && !URL.EndsWith(".flac") && !URL.EndsWith(".ogg"))
{
await message.Channel.SendMessageAsync("Invalid URL");
return;
}
Data.voiceChannel = (context.User as IGuildUser)?.VoiceChannel;
if (Data.voiceChannel == null) { await context.Channel.SendMessageAsync("User must be in a voice channel, or a voice channel must be passed as an argument."); return; }
Data.audioClient = await Data.voiceChannel.ConnectAsync();
using (var discord = Data.audioClient.CreatePCMStream(AudioApplication.Mixed))
{
await message.Channel.SendMessageAsync("Loading...");
Data.CurrentlyRunning = new MusicPlayer(discord);
await Data.CurrentlyRunning.StartSendAudioFromLink(URL);
}
}
}
}

30
MusicCommands/queue.cs Normal file
View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Discord.Commands;
using Discord.WebSocket;
using PluginManager.Interfaces;
namespace MusicCommands
{
public class queue : DBCommand
{
public string Command => "queue";
public List<string> Aliases => new() { "q" };
public string Description => "check queue";
public string Usage => "queue";
public bool requireAdmin => false;
public async void ExecuteServer(SocketCommandContext context)
{
await context.Channel.SendMessageAsync($"You have {Data.Playlist.Count} items in queue");
}
}
}

View File

@@ -1,75 +1,234 @@
using System; using System;
using PluginManager.Others; using PluginManager.Others;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
namespace PluginManager namespace PluginManager
{ {
internal class AppConfig internal class AppConfig
{ {
public Dictionary<string, string> ApplicationVariables { get; set; } public string UpdaterVersion { get; set; }
public List<string> ProtectedKeyWords { get; set; } public Dictionary<string, object>? ApplicationVariables { get; init; }
public List<string>? ProtectedKeyWords { get; init; }
public Dictionary<string, string>? PluginVersions { get; init; }
} }
public static class Config public static class Config
{ {
private static AppConfig appConfig = null; public static class PluginConfig
public static bool AddValueToVariables(string key, string value, bool isProtected)
{ {
if (appConfig.ApplicationVariables.ContainsKey(key)) return false; public static readonly List<Tuple<string, PluginType>> InstalledPlugins = new();
public static void Load()
{
new Thread(LoadCommands).Start();
new Thread(LoadEvents).Start();
}
private static void LoadCommands()
{
string cmd_path = "./Data/Plugins/Commands/";
string[] files = Directory.GetFiles(cmd_path, $"*.{Loaders.PluginLoader.pluginCMDExtension}", SearchOption.AllDirectories);
foreach (var file in files)
if (!file.Contains("PluginManager", StringComparison.InvariantCultureIgnoreCase))
{
string PluginName = new FileInfo(file).Name;
string name = PluginName.Substring(0, PluginName.Length - 1 - PluginManager.Loaders.PluginLoader.pluginCMDExtension.Length);
InstalledPlugins.Add(new(name, PluginType.Command));
}
}
private static void LoadEvents()
{
string eve_path = "./Data/Plugins/Events/";
string[] files = Directory.GetFiles(eve_path, $"*.{Loaders.PluginLoader.pluginEVEExtension}", SearchOption.AllDirectories);
foreach (var file in files)
if (!file.Contains("PluginManager", StringComparison.InvariantCultureIgnoreCase))
if (!file.Contains("PluginManager", StringComparison.InvariantCultureIgnoreCase))
{
string PluginName = new FileInfo(file).Name;
string name = PluginName.Substring(0, PluginName.Length - 1 - PluginManager.Loaders.PluginLoader.pluginEVEExtension.Length);
InstalledPlugins.Add(new(name, PluginType.Event));
}
}
public static bool Contains(string pluginName)
{
foreach (var tuple in InstalledPlugins)
if (tuple.Item1 == pluginName)
return true;
return false;
}
public static PluginType GetPluginType(string pluginName)
{
foreach (var tuple in InstalledPlugins)
if (tuple.Item1 == pluginName)
return tuple.Item2;
return PluginType.Unknown;
}
}
private static AppConfig? appConfig { get; set; }
public static string UpdaterVersion { get => appConfig.UpdaterVersion; set => appConfig.UpdaterVersion = value; }
public static string GetPluginVersion(string pluginName) => appConfig!.PluginVersions![pluginName];
public static void SetPluginVersion(string pluginName, string newVersion)
{
if (appConfig!.PluginVersions!.ContainsKey(pluginName))
appConfig.PluginVersions[pluginName] = newVersion;
else appConfig.PluginVersions.Add(pluginName, newVersion);
// SaveConfig();
}
public static void RemovePluginVersion(string pluginName) => appConfig!.PluginVersions!.Remove(pluginName);
public static bool PluginVersionsContainsKey(string pluginName) => appConfig!.PluginVersions!.ContainsKey(pluginName);
public static void AddValueToVariables<T>(string key, T value, bool isProtected)
{
if (value == null)
throw new Exception("The value cannot be null");
if (appConfig!.ApplicationVariables!.ContainsKey(key))
throw new Exception($"The key ({key}) already exists in the variables. Value {GetValue<T>(key)}");
appConfig.ApplicationVariables.Add(key, value); appConfig.ApplicationVariables.Add(key, value);
if (isProtected) appConfig.ProtectedKeyWords.Add(key); if (isProtected && key != "Version")
SaveConfig(); appConfig.ProtectedKeyWords!.Add(key);
return true;
SaveConfig(SaveType.NORMAL);
} }
public static string? GetValue(string key) public static Type GetVariableType(string value)
{ {
if (!appConfig.ApplicationVariables.ContainsKey(key)) return null; if (int.TryParse(value, out var intValue))
return appConfig.ApplicationVariables[key]; return typeof(int);
if (bool.TryParse(value, out var boolValue))
return typeof(bool);
if (float.TryParse(value, out var floatValue))
return typeof(float);
if (double.TryParse(value, out var doubleValue))
return typeof(double);
if (uint.TryParse(value, out var uintValue))
return typeof(uint);
if (long.TryParse(value, out var longValue))
return typeof(long);
if (byte.TryParse(value, out var byteValue))
return typeof(byte);
return typeof(string);
} }
public static bool SetValue(string key, string value) public static void GetAndAddValueToVariable(string key, string value, bool isReadOnly)
{ {
if (!appConfig.ApplicationVariables.ContainsKey(key)) return false; if (Config.ContainsKey(key))
if (appConfig.ProtectedKeyWords.Contains(key)) return false; return;
appConfig.ApplicationVariables[key] = value; if (int.TryParse(value, out var intValue))
SaveConfig(); Config.AddValueToVariables(key, intValue, isReadOnly);
return true; else if (bool.TryParse(value, out var boolValue))
Config.AddValueToVariables(key, boolValue, isReadOnly);
else if (float.TryParse(value, out var floatValue))
Config.AddValueToVariables(key, floatValue, isReadOnly);
else if (double.TryParse(value, out var doubleValue))
Config.AddValueToVariables(key, doubleValue, isReadOnly);
else if (uint.TryParse(value, out var uintValue))
Config.AddValueToVariables(key, uintValue, isReadOnly);
else if (long.TryParse(value, out var longValue))
Config.AddValueToVariables(key, longValue, isReadOnly);
else if (byte.TryParse(value, out var byteValue))
Config.AddValueToVariables(key, byteValue, isReadOnly);
else
Config.AddValueToVariables(key, value, isReadOnly);
} }
public static bool RemoveKey(string key) public static T? GetValue<T>(string key)
{ {
appConfig.ApplicationVariables.Remove(key); if (!appConfig!.ApplicationVariables!.ContainsKey(key)) return default;
appConfig.ProtectedKeyWords.Remove(key); try
return true; {
JsonElement element = (JsonElement)appConfig.ApplicationVariables[key];
return element.Deserialize<T>();
}
catch
{
return (T)appConfig.ApplicationVariables[key];
}
} }
public static async void SaveConfig() public static void SetValue<T>(string key, T value)
{ {
string path = Functions.dataFolder + "var.dat"; if (value == null)
await Functions.SaveToJsonFile<AppConfig>(path, appConfig); throw new Exception("Value is null");
if (!appConfig!.ApplicationVariables!.ContainsKey(key))
throw new Exception("Key does not exist in the config file");
if (appConfig.ProtectedKeyWords!.Contains(key))
throw new Exception("Key is protected");
appConfig.ApplicationVariables[key] = JsonSerializer.SerializeToElement(value);
SaveConfig(SaveType.NORMAL);
}
public static void RemoveKey(string key)
{
if (key == "Version" || key == "token" || key == "prefix")
throw new Exception("Key is protected");
appConfig!.ApplicationVariables!.Remove(key);
appConfig.ProtectedKeyWords!.Remove(key);
SaveConfig(SaveType.NORMAL);
}
public static async Task SaveConfig(SaveType type)
{
if (type == SaveType.NORMAL)
{
string path = Functions.dataFolder + "config.json";
await Functions.SaveToJsonFile<AppConfig>(path, appConfig!);
return;
}
if (type == SaveType.BACKUP)
{
string path = Functions.dataFolder + "config.json.bak";
await Functions.SaveToJsonFile<AppConfig>(path, appConfig!);
return;
}
} }
public static async Task LoadConfig() public static async Task LoadConfig()
{ {
string path = Functions.dataFolder + "var.dat"; string path = Functions.dataFolder + "config.json";
if (File.Exists(path)) if (File.Exists(path))
{
try
{ {
appConfig = await Functions.ConvertFromJson<AppConfig>(path); appConfig = await Functions.ConvertFromJson<AppConfig>(path);
Functions.WriteLogFile($"Loaded {appConfig.ApplicationVariables.Keys.Count} application variables.\nLoaded {appConfig.ProtectedKeyWords.Count} readonly variables.");
} }
else catch (Exception ex)
appConfig = new() { ApplicationVariables = new Dictionary<string, string>(), ProtectedKeyWords = new List<string>() }; {
File.Delete(path);
Console.WriteLine("An error occured while loading the settings. Importing from backup file...");
path = Functions.dataFolder + "config.json.bak";
appConfig = await Functions.ConvertFromJson<AppConfig>(path);
Functions.WriteErrFile(ex.Message);
} }
public static string? GetKey(string value) => appConfig.ApplicationVariables.Keys.FirstOrDefault(x => appConfig.ApplicationVariables[x] == value);
public static bool ContainsValue(string value) => appConfig.ApplicationVariables.ContainsValue(value);
public static bool ContainsKey(string key) => appConfig.ApplicationVariables.ContainsKey(key);
public static Dictionary<string, string> GetAllVariables() => new Dictionary<string, string>(appConfig.ApplicationVariables); Functions.WriteLogFile($"Loaded {appConfig.ApplicationVariables!.Keys.Count} application variables.\nLoaded {appConfig.ProtectedKeyWords!.Count} readonly variables.");
return;
}
appConfig = new() { ApplicationVariables = new Dictionary<string, object>(), ProtectedKeyWords = new List<string>(), PluginVersions = new Dictionary<string, string>(), UpdaterVersion = "-1" };
}
public static bool ContainsValue<T>(T value) => appConfig!.ApplicationVariables!.ContainsValue(value!);
public static bool ContainsKey(string key) => appConfig!.ApplicationVariables!.ContainsKey(key);
public static ReadOnlyDictionary<string, object> GetAllVariables() => new(appConfig!.ApplicationVariables!);
} }
} }

View File

@@ -1,5 +1,10 @@
namespace PluginManager.Interfaces using System.Collections.Generic;
{
using Discord.Commands;
using Discord.WebSocket;
namespace PluginManager.Interfaces;
public interface DBCommand public interface DBCommand
{ {
/// <summary> /// <summary>
@@ -8,6 +13,11 @@
/// </summary> /// </summary>
string Command { get; } string Command { get; }
/// <summary>
/// Command aliases. Users may use this to execute the command
/// </summary>
List<string>? Aliases { get; }
/// <summary> /// <summary>
/// Command description /// Command description
/// </summary> /// </summary>
@@ -19,31 +29,20 @@
/// </summary> /// </summary>
string Usage { get; } string Usage { get; }
/// <summary>
/// true if the command can be used in a DM channel, otherwise false
/// </summary>
bool canUseDM { get; }
/// <summary>
/// true if the command can be used in a server, otherwise false
/// </summary>
bool canUseServer { get; }
/// <summary> /// <summary>
/// true if the command requre admin, otherwise false /// true if the command requre admin, otherwise false
/// </summary> /// </summary>
bool requireAdmin { get; } bool requireAdmin { get; }
/// <summary> /// <summary>
/// The main body of the command. This is what is executed when user calls the command /// 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="context">The disocrd Context</param>
/// <param name="message">The message that the user types</param> void ExecuteServer(SocketCommandContext context) { }
/// <param name="client">The discord client of the bot</param>
/// <param name="isDM">true if the message was sent from DM, otherwise false. It is always false if canUseDM is false</param> /// <summary>
void Execute(Discord.Commands.SocketCommandContext context, /// The main body of the command. This is what is executed when user calls the command in DM
Discord.WebSocket.SocketMessage message, /// </summary>
Discord.WebSocket.DiscordSocketClient client, /// <param name="context">The disocrd Context</param>
bool isDM); void ExecuteDM(SocketCommandContext context) { }
}
} }

View File

@@ -1,7 +1,7 @@
using Discord.WebSocket; using Discord.WebSocket;
namespace PluginManager.Interfaces namespace PluginManager.Interfaces;
{
public interface DBEvent public interface DBEvent
{ {
/// <summary> /// <summary>
@@ -20,4 +20,3 @@ namespace PluginManager.Interfaces
/// <param name="client">The discord bot client</param> /// <param name="client">The discord bot client</param>
void Start(DiscordSocketClient client); void Start(DiscordSocketClient client);
} }
}

View File

@@ -1,51 +1,51 @@
using Discord.WebSocket; using System;
using System.Collections.Generic;
using PluginManager.Loaders; using System.Threading.Tasks;
using Discord.WebSocket;
using PluginManager.Others; using PluginManager.Others;
using System; namespace PluginManager.Items;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PluginManager.Items public class Command
{
internal class Command
{ {
/// <summary> /// <summary>
/// The author of the command /// The author of the command
/// </summary> /// </summary>
public SocketUser? Author; public SocketUser? Author;
/// <summary>
/// The list of arguments
/// </summary>
public List<string> Arguments { get; private set; }
/// <summary>
/// The command that is executed
/// </summary>
public string CommandName { get; private set; }
/// <summary>
/// The prefix that is used for the command
/// </summary>
public char PrefixUsed { get; private set; }
/// <summary> /// <summary>
/// The Command class contructor /// The Command class contructor
/// </summary> /// </summary>
/// <param name="message">The message that was sent</param> /// <param name="message">The message that was sent</param>
public Command(SocketMessage message) public Command(SocketMessage message)
{ {
this.Author = message.Author; Author = message.Author;
string[] data = message.Content.Split(' '); var data = message.Content.Split(' ');
if (data.Length > 1) Arguments = data.Length > 1 ? new List<string>(data.MergeStrings(1).Split(' ')) : new List<string>();
this.Arguments = new List<string>(data.MergeStrings(1).Split(' ')); CommandName = data[0].Substring(1);
else this.Arguments = new List<string>(); PrefixUsed = data[0][0];
this.CommandName = data[0].Substring(1);
this.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; }
} }

View File

@@ -1,126 +1,176 @@
using Discord.WebSocket; using System;
using PluginManager.Loaders;
using PluginManager.Online;
using PluginManager.Others;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Threading.Tasks; using System.IO;
using System.Threading;
using System.Linq; using System.Linq;
using System.Reflection.Metadata.Ecma335; using System.Net.Http;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Discord.WebSocket;
using PluginManager.Interfaces;
using PluginManager.Loaders;
using PluginManager.Online;
using PluginManager.Online.Helpers;
using PluginManager.Online.Updates;
using PluginManager.Others;
namespace PluginManager.Items;
namespace PluginManager.Items
{
public class ConsoleCommandsHandler public class ConsoleCommandsHandler
{ {
private static PluginsManager manager = new("https://sethdiscordbot.000webhostapp.com/Storage/Discord%20Bot/Plugins"); 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 readonly DiscordSocketClient? client;
public static List<Tuple<string, string, Action<string[]>>>? commandList = new List<Tuple<string, string, Action<string[]>>>();
private DiscordSocketClient client; private static bool isDownloading = false;
private static bool pluginsLoaded = false;
public ConsoleCommandsHandler(DiscordSocketClient client) public ConsoleCommandsHandler(DiscordSocketClient client)
{ {
this.client = client; this.client = client;
InitializeBasicCommands(); InitializeBasicCommands();
Console.WriteLine("Initalized console command handeler !"); //Console.WriteLine("Initialized console command handler !");
} }
private void InitializeBasicCommands() private void InitializeBasicCommands()
{ {
bool pluginsLoaded = false;
commandList.Clear(); commandList.Clear();
AddCommand("help", "Show help", (args) => AddCommand("help", "Show help", "help <command>", args =>
{ {
if (args.Length <= 1) if (args.Length <= 1)
{ {
Console.WriteLine("Available commands:"); Console.WriteLine("Available commands:");
List<string[]> 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) foreach (var command in commandList)
{ {
Console.WriteLine("\t" + command.Item1 + " - " + command.Item2); 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[] { "-", "-", "-" });
Console_Utilities.FormatAndAlignTable(items, TableFormat.DEFAULT);
} }
else else
{ {
foreach (var command in commandList) foreach (var command in commandList)
if (command.CommandName == args[1])
{ {
if (command.Item1 == args[1]) Console.WriteLine("Command description: " + command.Description);
{ Console.WriteLine("Command execution format:" + command.Usage);
Console.WriteLine(command.Item2);
return; return;
} }
}
Console.WriteLine("Command not found"); Console.WriteLine("Command not found");
} }
}); }
);
AddCommand("lp", "Load plugins", () => AddCommand("lp", "Load plugins", () =>
{ {
if (pluginsLoaded) return; if (pluginsLoaded)
var loader = new PluginLoader(client); return;
var loader = new PluginLoader(client!);
ConsoleColor cc = Console.ForegroundColor;
loader.onCMDLoad += (name, typeName, success, exception) => loader.onCMDLoad += (name, typeName, success, exception) =>
{ {
Console.ForegroundColor = ConsoleColor.Green;
if (name == null || name.Length < 2) if (name == null || name.Length < 2)
name = typeName; name = typeName;
if (success) if (success)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("[CMD] Successfully loaded command : " + name); Console.WriteLine("[CMD] Successfully loaded command : " + name);
}
else else
Console.WriteLine("[CMD] Failed to load command : " + name + " because " + exception.Message); {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("[CMD] Failed to load command : " + name + " because " + exception!.Message);
}
Console.ForegroundColor = cc;
}; };
loader.onEVELoad += (name, typeName, success, exception) => loader.onEVELoad += (name, typeName, success, exception) =>
{ {
if (name == null || name.Length < 2) if (name == null || name.Length < 2)
name = typeName; name = typeName;
Console.ForegroundColor = ConsoleColor.Green;
if (success) if (success)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("[EVENT] Successfully loaded event : " + name); Console.WriteLine("[EVENT] Successfully loaded event : " + name);
}
else else
Console.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception.Message); {
Console.ForegroundColor = ConsoleColor.Red; Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("[EVENT] Failed to load event : " + name + " because " + exception!.Message);
}
Console.ForegroundColor = cc;
}; };
loader.LoadPlugins(); loader.LoadPlugins();
Console.ForegroundColor = cc;
pluginsLoaded = true; pluginsLoaded = true;
});
AddCommand("listplugs", "list available plugins", async () => }
{ );
await manager.ListAvailablePlugins();
});
AddCommand("dwplug", "download plugin", async (args) => AddCommand("listplugs", "list available plugins", () => { manager.ListAvailablePlugins().Wait(); });
AddCommand("dwplug", "download plugin", "dwplug [name]", async args =>
{ {
isDownloading = true;
if (args.Length == 1) if (args.Length == 1)
{ {
isDownloading = false;
Console.WriteLine("Please specify plugin name"); Console.WriteLine("Please specify plugin name");
return; return;
} }
string name = args.MergeStrings(1); var name = args.MergeStrings(1);
// info[0] = plugin type // info[0] = plugin type
// info[1] = plugin link // info[1] = plugin link
// info[2] = if others are required, or string.Empty if none // info[2] = if others are required, or string.Empty if none
string[] info = await manager.GetPluginLinkByName(name); var info = await manager.GetPluginLinkByName(name);
if (info[1] == null) // link is null if (info[1] == null) // link is null
{ {
if (name == "") if (name == "")
{ {
Console_Utilities.WriteColorText($"Name is invalid"); isDownloading = false;
Console_Utilities.WriteColorText("Name is invalid");
return; return;
} }
Console_Utilities.WriteColorText($"Failed to find plugin &b{name} &c!" + isDownloading = false;
$" Use &glistplugs &ccommand to display all available plugins !"); Console_Utilities.WriteColorText($"Failed to find plugin &b{name} &c!" + " Use &glistplugs &ccommand to display all available plugins !");
return; return;
}
}
string path; string path;
if (info[0] == "Command" || info[0] == "Event") if (info[0] == "Command" || info[0] == "Event")
path = "./Data/Plugins/" + info[0] + "s/" + name + ".dll"; path = "./Data/Plugins/" + info[0] + "s/" + name + "." + (info[0] == "Command" ? PluginLoader.pluginCMDExtension : PluginLoader.pluginEVEExtension);
else path = $"./{info[1].Split('/')[info[1].Split('/').Length - 1]}"; else
path = $"./{info[1].Split('/')[info[1].Split('/').Length - 1]}";
//Console.WriteLine("Downloading: " + path + " [" + info[1] + "]");
await ServerCom.DownloadFileAsync(info[1], path); await ServerCom.DownloadFileAsync(info[1], path);
if (info[0] == "Command" || info[0] == "Event")
if (info[0] == "Event")
Config.PluginConfig.InstalledPlugins.Add(new(name, PluginType.Event));
else if (info[0] == "Command")
Config.PluginConfig.InstalledPlugins.Add(new(name, PluginType.Command));
Console.WriteLine("\n"); Console.WriteLine("\n");
// check requirements if any // check requirements if any
@@ -129,154 +179,290 @@ namespace PluginManager.Items
{ {
Console.WriteLine($"Downloading requirements for plugin : {name}"); Console.WriteLine($"Downloading requirements for plugin : {name}");
List<string> lines = await ServerCom.ReadTextFromFile(info[2]); var lines = await ServerCom.ReadTextFromURL(info[2]);
foreach (var line in lines) foreach (var line in lines)
{ {
string[] split = line.Split(','); if (!(line.Length > 0 && line.Contains(",")))
continue;
var split = line.Split(',');
Console.WriteLine($"\nDownloading item: {split[1]}"); Console.WriteLine($"\nDownloading item: {split[1]}");
if (File.Exists("./" + split[1])) File.Delete("./" + split[1]);
await ServerCom.DownloadFileAsync(split[0], "./" + split[1]); await ServerCom.DownloadFileAsync(split[0], "./" + split[1]);
Console.WriteLine(); Console.WriteLine();
if (split[0].EndsWith(".zip")) if (split[0].EndsWith(".zip") || split[0].EndsWith(".pak") || split[0].EndsWith(".pkg"))
{ {
Console.WriteLine($"Extracting {split[1]} ...");
Console.WriteLine($"Extracting {split[1]}"); var bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END) { Max = 100f, Color = ConsoleColor.Green };
double proc = 0d; bar.Start();
bool isExtracting = true; await Functions.ExtractArchive("./" + split[1], "./", null, UnzipProgressType.PercentageFromTotalSize);
Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(100, ""); bar.Stop();
IProgress<float> extractProgress = new Progress<float>(value =>
{
proc = value;
});
new Thread(new Task(() =>
{
while (isExtracting)
{
bar.Update((int)proc);
if (proc >= 99.9f)
break;
Thread.Sleep(500);
}
}).Start).Start();
await Functions.ExtractArchive("./" + split[1], "./", extractProgress);
bar.Update(100);
isExtracting = false;
await Task.Delay(1000);
bar.Update(100);
Console.WriteLine("\n"); Console.WriteLine("\n");
System.IO.File.Delete("./" + split[1]); File.Delete("./" + split[1]);
}
if (name == "DBUI")
{
Console.WriteLine("Reload with GUI ?[y/n]");
if (Console.ReadKey().Key == ConsoleKey.Y)
{
Process.Start("./DiscordBotGUI.exe");
Environment.Exit(0);
}
} }
} }
Console.WriteLine(); Console.WriteLine();
} }
VersionString? ver = await VersionString.GetVersionOfPackageFromWeb(name);
if (ver is null) throw new Exception("Incorrect version");
Config.SetPluginVersion(name, $"{ver.PackageVersionID}.{ver.PackageMainVersion}.{ver.PackageCheckVersion}");
// Console.WriteLine();
}); isDownloading = false;
}
);
AddCommand("value", "read value from VariableStack", (args) => AddCommand("value", "read value from VariableStack", "value [key]", args =>
{ {
if (args.Length != 2) return; if (args.Length != 2)
if (!Config.ContainsKey(args[1])) return; return;
if (!Config.ContainsKey(args[1]))
return;
string data = Config.GetValue(args[1]); var data = Config.GetValue<string>(args[1]);
Console.WriteLine($"{args[1]} => {data}"); Console.WriteLine($"{args[1]} => {data}");
} }
); );
AddCommand("addv", "add variable to the system variables", async (args) => AddCommand("add", "add variable to the system variables", "add [key] [value] [isReadOnly=true/false]", args =>
{ {
if (args.Length < 3) return; if (args.Length < 4)
string in1 = args[1]; return;
if (!Config.ContainsKey(in1)) var key = args[1];
Config.AddValueToVariables(in1, Functions.MergeStrings(args, 2), false); var value = args[2];
else var isReadOnly = args[3].Equals("true", StringComparison.CurrentCultureIgnoreCase);
Config.SetValue(in1, Functions.MergeStrings(args, 2));
Console.WriteLine($"Updated config file with the following command: {in1} => {Config.GetValue(in1)}"); try
Config.SaveConfig(); {
Config.GetAndAddValueToVariable(key, value, isReadOnly);
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", (args) => AddCommand("remv", "remove variable from system variables", "remv [key]", args =>
{ {
if (args.Length < 2) return; if (args.Length < 2)
return;
Config.RemoveKey(args[1]); Config.RemoveKey(args[1]);
Config.SaveConfig();
}
);
AddCommand("vars", "Display all variables", () =>
{
var d = Config.GetAllVariables();
List<string[]> data = new List<string[]>();
data.Add(new string[] { "-", "-" });
data.Add(new string[] { "Key", "Value" });
data.Add(new string[] { "-", "-" });
foreach (var kvp in d) data.Add(new string[] { kvp.Key, kvp.Value });
data.Add(new string[] { "-", "-" });
Console_Utilities.FormatAndAlignTable(data);
} }
); );
AddCommand("sd", "Shuts down the discord bot", async () => AddCommand("sd", "Shuts down the discord bot", async () =>
{ {
if (client is null)
return;
Console_Utilities.ProgressBar bar = new Console_Utilities.ProgressBar(ProgressBarType.NO_END);
bar.Start();
await Config.SaveConfig(SaveType.NORMAL);
await Config.SaveConfig(SaveType.BACKUP);
await Task.Delay(4000);
bar.Stop();
Console.WriteLine();
await client.StopAsync(); await client.StopAsync();
await client.DisposeAsync(); await client.DisposeAsync();
Config.SaveConfig();
Environment.Exit(0); Environment.Exit(0);
} }
); );
AddCommand("extern", "Load an external command", "extern [pluginName]", async (args) =>
{
if (args.Length <= 1) return;
string pName = Functions.MergeStrings(args, 1);
HttpClient client = new HttpClient();
string url = (await manager.GetPluginLinkByName(pName))[1];
Stream s = await client.GetStreamAsync(url);
MemoryStream 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))
{
DBEvent instance = (DBEvent)Activator.CreateInstance(type);
instance.Start(this.client);
Console.WriteLine($"Loaded external {type.FullName}!");
}
else if (type.IsClass && typeof(DBCommand).IsAssignableFrom(type))
{
Console.WriteLine("Only events can be loaded from external sources !");
return;
}
}
});
AddCommand("remplug", "Remove a plugin", "remplug [plugName]", async args =>
{
if (args.Length <= 1) return;
isDownloading = true;
string plugName = Functions.MergeStrings(args, 1);
if (pluginsLoaded)
{
if (Functions.GetOperatingSystem() == Others.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;
} }
public static void AddCommand(string command, string description, Action<string[]> action)
string location = "./Data/Plugins/";
location = Config.PluginConfig.GetPluginType(plugName) switch
{ {
commandList.Add(new Tuple<string, string, Action<string[]>>(command, description, action)); PluginType.Command => location + "Commands/" + plugName + "." + PluginLoader.pluginCMDExtension,
PluginType.Event => location + "Events/" + plugName + "." + PluginLoader.pluginEVEExtension,
PluginType.Unknown => "./",
_ => throw new NotImplementedException("Plugin type incorrect")
};
if (!File.Exists(location))
{
Console.WriteLine("The plugin does not exist");
return;
}
File.Delete(location);
if (Config.PluginConfig.Contains(plugName))
{
var tuple = Config.PluginConfig.InstalledPlugins.Where(t => t.Item1 == plugName).FirstOrDefault();
Console.WriteLine("Found: " + tuple.ToString());
Config.PluginConfig.InstalledPlugins.Remove(tuple);
Config.RemovePluginVersion(plugName);
await Config.SaveConfig(SaveType.NORMAL);
}
Console.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]);
Console.WriteLine("Removed: " + split[1]);
}
if (Directory.Exists(plugName))
Directory.Delete(plugName, true);
}
isDownloading = false;
Console.WriteLine(plugName + " has been successfully deleted !");
});
AddCommand("reload", "Reload the bot with all plugins", () =>
{
if (Functions.GetOperatingSystem() == Others.OperatingSystem.WINDOWS)
{
Process.Start("DiscordBot.exe", $"lp");
HandleCommand("sd");
}
else
{
Process.Start("./DiscordBot", $"lp");
HandleCommand("sd");
}
});
//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; Console.ForegroundColor = ConsoleColor.White;
Console_Utilities.WriteColorText($"Command &r{command} &cadded to the list of commands"); Console_Utilities.WriteColorText($"Command &r{command} &cadded to the list of commands");
} }
public static void AddCommand(string command, string description, Action action) public static void AddCommand(string command, string description, Action action)
{ {
AddCommand(command, description, (args) => action()); AddCommand(command, description, command, args => action());
} }
public static void RemoveCommand(string command) public static void RemoveCommand(string command)
{ {
commandList.RemoveAll(x => x.Item1 == command); commandList.RemoveAll(x => x.CommandName == command);
} }
public static Tuple<string, string, Action<string[]>>? SearchCommand(string command) public static bool CommandExists(string command)
{ {
return commandList.FirstOrDefault(t => t.Item1 == command); return GetCommand(command) is not null;
} }
public void HandleCommand(string command) public static ConsoleCommand? GetCommand(string command)
{ {
string[] args = command.Split(' '); return commandList.FirstOrDefault(t => t.CommandName == command);
}
public static async Task ExecuteCommad(string command)
{
var args = command.Split(' ');
// Console.WriteLine(command);
foreach (var item in commandList.ToList()) foreach (var item in commandList.ToList())
if (item.CommandName == args[0])
{ {
if (item.Item1 == args[0]) item.Action.Invoke(args);
Console.WriteLine();
while (isDownloading) await Task.Delay(1000);
}
}
public bool HandleCommand(string command, bool removeCommandExecution = true)
{ {
item.Item3(args); 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 (int i = 0; i < command.Length + 30; i++)
Console.Write(" ");
Console.SetCursorPosition(0, Console.CursorTop);
}
Console.WriteLine();
item.Action(args);
return true;
}
return false;
//Console.WriteLine($"Executing: {args[0]} with the following parameters: {args.MergeStrings(1)}"); //Console.WriteLine($"Executing: {args[0]} with the following parameters: {args.MergeStrings(1)}");
} }
} }
}
}
}

View File

@@ -1,54 +0,0 @@
using System;
using System.Threading.Tasks;
namespace PluginManager.Items
{
public class Spinner
{
/// <summary>
/// True if active, false otherwise
/// </summary>
public bool isSpinning;
/// <summary>
/// The Spinner constructor
/// </summary>
public Spinner()
{
isSpinning = false;
}
/// <summary>
/// The method that is called to start spinning the spinner
/// </summary>
public async void Start()
{
isSpinning = true;
int cnt = 0;
while (isSpinning)
{
cnt++;
switch (cnt % 4)
{
case 0: Console.Write("/"); break;
case 1: Console.Write("-"); break;
case 2: Console.Write("\\"); break;
case 3: Console.Write("|"); break;
}
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
await Task.Delay(250);
}
}
/// <summary>
/// The method that is called to stop the spinner from spinning
/// </summary>
public void Stop()
{
if (!isSpinning)
throw new Others.Exceptions.APIException("Spinner was not spinning", GetType());
isSpinning = false;
}
}
}

View File

@@ -3,12 +3,13 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Threading.Tasks;
using PluginManager.Interfaces;
using PluginManager.Online.Updates;
using PluginManager.Others; using PluginManager.Others;
namespace PluginManager.Loaders namespace PluginManager.Loaders;
{
internal class LoaderArgs : EventArgs internal class LoaderArgs : EventArgs
{ {
internal string? PluginName { get; init; } internal string? PluginName { get; init; }
@@ -20,46 +21,47 @@ namespace PluginManager.Loaders
internal class Loader<T> internal class Loader<T>
{ {
internal delegate void FileLoadedEventHandler(LoaderArgs args);
internal event FileLoadedEventHandler? FileLoaded;
internal delegate void PluginLoadedEventHandler(LoaderArgs args);
internal event PluginLoadedEventHandler? PluginLoaded;
private string path { get; }
private string extension { get; }
internal Loader(string path, string extension) internal Loader(string path, string extension)
{ {
this.path = path; this.path = path;
this.extension = extension; this.extension = extension;
} }
private string path { get; }
private string extension { get; }
internal delegate void FileLoadedEventHandler(LoaderArgs args);
internal delegate void PluginLoadedEventHandler(LoaderArgs args);
internal event FileLoadedEventHandler? FileLoaded;
internal event PluginLoadedEventHandler? PluginLoaded;
internal List<T>? Load() internal List<T>? Load()
{ {
List<T> list = new List<T>(); var list = new List<T>();
if (!Directory.Exists(path)) if (!Directory.Exists(path))
{ {
Directory.CreateDirectory(path); Directory.CreateDirectory(path);
return null; return null;
} }
string[] 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)
{ {
Assembly.LoadFrom(file); Assembly.LoadFrom(file);
if (FileLoaded != null) if (FileLoaded != null)
{ {
LoaderArgs args = new LoaderArgs() var args = new LoaderArgs
{ {
Exception = null, Exception = null,
TypeName = nameof(T), TypeName = nameof(T),
IsLoaded = false, IsLoaded = false,
PluginName = file, PluginName = new FileInfo(file).Name.Split('.')[0],
Plugin = null Plugin = null
}; };
FileLoaded.Invoke(args); FileLoaded.Invoke(args);
@@ -68,25 +70,23 @@ namespace PluginManager.Loaders
try try
{ {
Type interfaceType = typeof(T); var interfaceType = typeof(T);
Type[] types = AppDomain.CurrentDomain.GetAssemblies() var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes()) .SelectMany(a => a.GetTypes())
.Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass) .Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass)
.ToArray(); .ToArray();
list.Clear(); list.Clear();
foreach (Type type in types) foreach (var type in types)
{
try try
{ {
T plugin = (T)(Activator.CreateInstance(type)!); var plugin = (T)Activator.CreateInstance(type)!;
list.Add(plugin); list.Add(plugin);
if (PluginLoaded != null) if (PluginLoaded != null)
{ PluginLoaded.Invoke(new LoaderArgs
PluginLoaded.Invoke(new()
{ {
Exception = null, Exception = null,
IsLoaded = true, IsLoaded = true,
@@ -96,14 +96,9 @@ namespace PluginManager.Loaders
} }
); );
} }
}
catch (Exception ex) catch (Exception ex)
{ {
if (PluginLoaded != null) if (PluginLoaded != null) PluginLoaded.Invoke(new LoaderArgs { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) });
{
PluginLoaded.Invoke(new() { Exception = ex, IsLoaded = false, PluginName = type.FullName, TypeName = nameof(T) });
}
}
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -115,4 +110,3 @@ namespace PluginManager.Loaders
return list; return list;
} }
} }
}

View File

@@ -1,42 +1,31 @@
using Discord.WebSocket; using System;
using PluginManager.Interfaces;
using PluginManager.Others;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Discord.WebSocket;
using PluginManager.Interfaces;
using PluginManager.Online.Helpers;
using PluginManager.Online.Updates;
using PluginManager.Others;
namespace PluginManager.Loaders;
namespace PluginManager.Loaders
{
public class PluginLoader public class PluginLoader
{ {
private readonly DiscordSocketClient _client; public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null);
/// <summary> public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null);
/// The Plugin Loader constructor
/// </summary>
/// <param name="discordSocketClient">The discord bot client where the plugins will pe attached to</param>
public PluginLoader(DiscordSocketClient discordSocketClient) { this._client = discordSocketClient; }
private const string pluginCMDFolder = @"./Data/Plugins/Commands/"; private const string pluginCMDFolder = @"./Data/Plugins/Commands/";
private const string pluginEVEFolder = @"./Data/Plugins/Events/"; private const string pluginEVEFolder = @"./Data/Plugins/Events/";
private const string pluginCMDExtension = "dll"; internal const string pluginCMDExtension = "dll";
private const string pluginEVEExtension = "dll"; internal const string pluginEVEExtension = "dll";
private readonly DiscordSocketClient _client;
/// <summary>
/// A list of <see cref="DBCommand"/> commands
/// </summary>
public static List<DBCommand>? Commands { get; set; }
/// <summary>
/// A list of <see cref="DBEvent"/> commands
/// </summary>
public static List<DBEvent>? Events { get; set; }
public delegate void CMDLoaded(string name, string typeName, bool success, Exception? e = null);
public delegate void EVELoaded(string name, string typeName, bool success, Exception? e = null);
/// <summary> /// <summary>
/// Event that is fired when a <see cref="DBCommand" /> is successfully loaded into commands list /// Event that is fired when a <see cref="DBCommand" /> is successfully loaded into commands list
@@ -48,19 +37,76 @@ namespace PluginManager.Loaders
/// </summary> /// </summary>
public EVELoaded? onEVELoad; public EVELoaded? onEVELoad;
/// <summary>
/// The Plugin Loader constructor
/// </summary>
/// <param name="discordSocketClient">The discord bot client where the plugins will pe attached to</param>
public PluginLoader(DiscordSocketClient discordSocketClient)
{
_client = discordSocketClient;
}
/// <summary>
/// A list of <see cref="DBCommand" /> commands
/// </summary>
public static List<DBCommand>? Commands { get; set; }
/// <summary>
/// A list of <see cref="DBEvent" /> commands
/// </summary>
public static List<DBEvent>? Events { get; set; }
/// <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 void LoadPlugins() public async void LoadPlugins()
{ {
//Check for updates in commands
foreach (var file in Directory.GetFiles("./Data/Plugins/Commands", $"*.{pluginCMDExtension}", SearchOption.AllDirectories))
{
await Task.Run(async () =>
{
string name = new FileInfo(file).Name.Split('.')[0];
if (!Config.PluginVersionsContainsKey(name))
Config.SetPluginVersion(name, (await VersionString.GetVersionOfPackageFromWeb(name))?.PackageVersionID + ".0.0");
if (await PluginUpdater.CheckForUpdates(name))
await PluginUpdater.Download(name);
});
}
//Check for updates in events
foreach (var file in Directory.GetFiles("./Data/Plugins/Events", $"*.{pluginEVEExtension}", SearchOption.AllDirectories))
{
await Task.Run(async () =>
{
string name = new FileInfo(file).Name.Split('.')[0];
if (!Config.PluginVersionsContainsKey(name))
Config.SetPluginVersion(name, (await VersionString.GetVersionOfPackageFromWeb(name))?.PackageVersionID + ".0.0");
if (await PluginUpdater.CheckForUpdates(name))
await PluginUpdater.Download(name);
});
}
//Save the new config file (after the updates)
await Config.SaveConfig(SaveType.NORMAL);
//Load all plugins
Commands = new List<DBCommand>(); Commands = new List<DBCommand>();
Events = new List<DBEvent>(); Events = new List<DBEvent>();
Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username); Functions.WriteLogFile("Starting plugin loader ... Client: " + _client.CurrentUser.Username);
Console.WriteLine("Loading plugins"); Console.WriteLine("Loading plugins");
Loader<DBCommand> commandsLoader = new Loader<DBCommand>(pluginCMDFolder, pluginCMDExtension); var commandsLoader = new Loader<DBCommand>(pluginCMDFolder, pluginCMDExtension);
Loader<DBEvent> eventsLoader = new Loader<DBEvent>(pluginEVEFolder, pluginEVEExtension); var eventsLoader = new Loader<DBEvent>(pluginEVEFolder, pluginEVEExtension);
commandsLoader.FileLoaded += OnCommandFileLoaded; commandsLoader.FileLoaded += OnCommandFileLoaded;
commandsLoader.PluginLoaded += OnCommandLoaded; commandsLoader.PluginLoaded += OnCommandLoaded;
@@ -70,28 +116,45 @@ namespace PluginManager.Loaders
Commands = commandsLoader.Load(); Commands = commandsLoader.Load();
Events = eventsLoader.Load(); Events = eventsLoader.Load();
} }
private void EventFileLoaded(LoaderArgs e) private void EventFileLoaded(LoaderArgs e)
{ {
if (e.IsLoaded) Functions.WriteLogFile($"[EVENT] Event from file [{e.PluginName}] has been successfully created !"); if (!e.IsLoaded)
{
Functions.WriteLogFile($"[EVENT] Event from file [{e.PluginName}] has been successfully created !");
}
} }
private void OnCommandFileLoaded(LoaderArgs e) private void OnCommandFileLoaded(LoaderArgs e)
{ {
if (e.IsLoaded) Functions.WriteLogFile($"[CMD] Command from file [{e.PluginName}] has been successfully loaded !"); if (!e.IsLoaded)
{
Functions.WriteLogFile($"[CMD] Command from file [{e.PluginName}] has been successfully loaded !");
}
} }
private void OnEventLoaded(LoaderArgs e) private void OnEventLoaded(LoaderArgs e)
{ {
if (e.IsLoaded) { ((DBEvent)e.Plugin!).Start(_client); } try
{
if (e.IsLoaded)
((DBEvent)e.Plugin!).Start(_client);
if (onEVELoad != null) onEVELoad.Invoke(((DBEvent)e.Plugin!).name, e.TypeName!, e.IsLoaded, e.Exception); onEVELoad?.Invoke(((DBEvent)e.Plugin!).name, e.TypeName!, e.IsLoaded, e.Exception);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.WriteLine("Plugin: " + e.PluginName);
Console.WriteLine("Type: " + e.TypeName);
Console.WriteLine("IsLoaded: " + e.IsLoaded);
}
} }
private void OnCommandLoaded(LoaderArgs e) private void OnCommandLoaded(LoaderArgs e)
{ {
if (onCMDLoad != null) onCMDLoad.Invoke(((DBCommand)e.Plugin!).Command, e.TypeName!, e.IsLoaded, e.Exception); onCMDLoad?.Invoke(((DBCommand)e.Plugin!).Command, e.TypeName!, e.IsLoaded, e.Exception);
}
} }
} }

View File

@@ -18,21 +18,19 @@ namespace PluginManager.Online.Helpers
/// <param name="progress">The <see cref="IProgress{T}"/> that is used to track the download progress</param> /// <param name="progress">The <see cref="IProgress{T}"/> that is used to track the download progress</param>
/// <param name="cancellation">The cancellation token</param> /// <param name="cancellation">The cancellation token</param>
/// <returns></returns> /// <returns></returns>
internal static async Task DownloadFileAsync(this HttpClient client, string url, Stream destination, internal static async Task DownloadFileAsync(this HttpClient client, string url, Stream destination, IProgress<float>? progress = null, IProgress<long>? downloadedBytes = null, int bufferSize = 81920, CancellationToken cancellation = default)
IProgress<float>? progress = null, IProgress<long>? downloadedBytes = null, CancellationToken cancellation = default)
{ {
using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead)) using (var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancellation))
{ {
var contentLength = response.Content.Headers.ContentLength; var contentLength = response.Content.Headers.ContentLength;
using (var download = await response.Content.ReadAsStreamAsync()) using (var download = await response.Content.ReadAsStreamAsync(cancellation))
{ {
// Ignore progress reporting when no progress reporter was // Ignore progress reporting when no progress reporter was
// passed or when the content length is unknown // passed or when the content length is unknown
if (progress == null || !contentLength.HasValue) if (progress == null || !contentLength.HasValue)
{ {
await download.CopyToAsync(destination); await download.CopyToAsync(destination, cancellation);
return; return;
} }
@@ -41,9 +39,11 @@ namespace PluginManager.Online.Helpers
{ {
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, 81920, relativeProgress, cancellation); await download.CopyToOtherStreamAsync(destination, bufferSize, relativeProgress, cancellation);
progress.Report(1); progress.Report(1);
} }
} }
@@ -57,10 +57,8 @@ namespace PluginManager.Online.Helpers
/// <returns></returns> /// <returns></returns>
internal static async Task<string> DownloadStringAsync(string url, CancellationToken cancellation = default) internal static async Task<string> DownloadStringAsync(string url, CancellationToken cancellation = default)
{ {
using (var client = new HttpClient()) using var client = new HttpClient();
{ return await client.GetStringAsync(url, cancellation);
return await client.GetStringAsync(url);
}
} }

View File

@@ -0,0 +1,91 @@
using PluginManager.Others;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
namespace PluginManager.Online.Helpers
{
public class VersionString
{
public int PackageVersionID;
public int PackageMainVersion;
public int PackageCheckVersion;
public VersionString(string version)
{
string[] data = version.Split('.');
try
{
PackageVersionID = int.Parse(data[0]);
PackageMainVersion = int.Parse(data[1]);
PackageCheckVersion = int.Parse(data[2]);
}
catch (Exception ex)
{
throw new Exception("Failed to write Version", ex);
}
}
#region operators
public static bool operator >(VersionString s1, VersionString s2)
{
if (s1.PackageVersionID > s2.PackageVersionID) return true;
if (s1.PackageVersionID == s2.PackageVersionID)
{
if (s1.PackageMainVersion > s2.PackageMainVersion) return true;
if (s1.PackageMainVersion == s2.PackageMainVersion && s1.PackageCheckVersion > s2.PackageCheckVersion) return true;
}
return false;
}
public static bool operator <(VersionString s1, VersionString s2) => !(s1 > s2) && s1 != s2;
public static bool operator ==(VersionString s1, VersionString s2)
{
if (s1.PackageVersionID == s2.PackageVersionID && s1.PackageMainVersion == s2.PackageMainVersion && s1.PackageCheckVersion == s2.PackageCheckVersion) return true;
return false;
}
public static bool operator !=(VersionString s1, VersionString s2) => !(s1 == s2);
public static bool operator <=(VersionString s1, VersionString s2) => (s1 < s2 || s1 == s2);
public static bool operator >=(VersionString s1, VersionString s2) => (s1 > s2 || s1 == s2);
#endregion
public override string ToString()
{
return "{PackageID: " + PackageVersionID + ", PackageVersion: " + PackageMainVersion + ", PackageCheckVersion: " + PackageCheckVersion + "}";
}
public string ToShortString()
{
if (PackageVersionID == 0 && PackageCheckVersion == 0 && PackageMainVersion == 0)
return "Unknown";
return $"{PackageVersionID}.{PackageMainVersion}.{PackageCheckVersion}";
}
public static VersionString? GetVersionOfPackage(string pakName)
{
if (!Config.PluginVersionsContainsKey(pakName))
return null;
return new VersionString(Config.GetPluginVersion(pakName));
}
public static async Task<VersionString?> GetVersionOfPackageFromWeb(string pakName)
{
string url = "https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/Versions";
List<string> data = await ServerCom.ReadTextFromURL(url);
string? version = (from item in data
where !item.StartsWith("#") && item.StartsWith(pakName)
select item.Split(',')[1]).FirstOrDefault();
if (version == default || version == null) return null;
return new VersionString(version);
}
}
}

View File

@@ -1,86 +0,0 @@
using System;
using System.IO;
using System.Threading.Tasks;
using System.Net;
using System.Collections.Generic;
using PluginManager.Others;
namespace PluginManager.Online
{
public class LanguageManager
{
private string link;
/// <summary>
/// The Language Manager constructor
/// </summary>
/// <param name="link">The link to where all the languages for the bot are stored</param>
public LanguageManager(string link) => this.link = link;
/// <summary>
/// The method to list all languages
/// </summary>
/// <returns></returns>
public async Task ListAllLanguages()
{
try
{
List<string> list = await ServerCom.ReadTextFromFile(link);
string[] lines = list.ToArray();
List<string[]> info = new List<string[]>();
info.Add(new string[] { "-", "-" });
info.Add(new string[] { "Language Name", "File Size" });
info.Add(new string[] { "-", "-" });
foreach (var line in lines)
{
if (line.Length <= 2) continue;
string[] d = line.Split(',');
if (d[3].Contains("cp") || d[3].Contains("CrossPlatform"))
info.Add(new string[] { d[0], d[1] });
}
info.Add(new string[] { "-", "-" });
Console_Utilities.FormatAndAlignTable(info);
}
catch (Exception exception)
{
Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message);
Others.Functions.WriteErrFile(exception.ToString());
}
}
/// <summary>
/// A function that gets the download link for specified language
/// </summary>
/// <param name="langName">The name of the language</param>
/// <returns></returns>
public async Task<string[]?> GetDownloadLink(string langName)
{
try
{
List<string> list = await ServerCom.ReadTextFromFile(link);
string[] lines = list.ToArray();
foreach (var line in lines)
{
if (line.Length <= 2) continue;
string[] d = line.Split(',');
if (d[0].Equals(langName) && (d[3].Contains("cp") || d[3].Contains("CrossPlatform")))
return new string[] { d[2], d[3] };
}
}
catch (Exception exception)
{
Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message);
Others.Functions.WriteErrFile(exception.ToString());
}
return null;
}
}
}

View File

@@ -1,20 +1,16 @@
using System; using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using PluginManager.Online.Helpers;
using PluginManager.Others; using PluginManager.Others;
namespace PluginManager.Online using OperatingSystem = PluginManager.Others.OperatingSystem;
{
namespace PluginManager.Online;
public class PluginsManager public class PluginsManager
{ {
/// <summary>
/// The URL of the server
/// </summary>
public string PluginsLink { get; private set; }
/// <summary> /// <summary>
/// The Plugin Manager constructor /// The Plugin Manager constructor
/// </summary> /// </summary>
@@ -24,6 +20,11 @@ namespace PluginManager.Online
PluginsLink = link; PluginsLink = link;
} }
/// <summary>
/// The URL of the server
/// </summary>
public string PluginsLink { get; }
/// <summary> /// <summary>
/// The method to load all plugins /// The method to load all plugins
/// </summary> /// </summary>
@@ -32,60 +33,64 @@ namespace PluginManager.Online
{ {
try try
{ {
List<string> list = await ServerCom.ReadTextFromFile(PluginsLink); var list = await ServerCom.ReadTextFromURL(PluginsLink);
string[] lines = list.ToArray(); var lines = list.ToArray();
List<string[]> data = new List<string[]>(); var data = new List<string[]>();
var op = Functions.GetOperatingSystem(); var op = Functions.GetOperatingSystem();
int len = lines.Length; var len = lines.Length;
string[] titles = { "Name", "Description", "Plugin Type", "Libraries" }; string[] titles = { "Name", "Description", "Type", "Version", "Installed" };
data.Add(new string[] { "-", "-", "-", "-" }); data.Add(new[] { "-", "-", "-", "-", "-" });
data.Add(titles); data.Add(titles);
data.Add(new string[] { "-", "-", "-", "-" }); data.Add(new[] { "-", "-", "-", "-", "-" });
for (int i = 0; i < len; i++) for (var i = 0; i < len; i++)
{ {
if (lines[i].Length <= 2) continue; if (lines[i].Length <= 2)
string[] content = lines[i].Split(','); continue;
string[] display = new string[4]; var content = lines[i].Split(',');
if (op == Others.OperatingSystem.WINDOWS) var display = new string[titles.Length];
if (op == OperatingSystem.WINDOWS)
{ {
if (content[4].Contains("Windows")) if (content[4].Contains("Windows"))
{ {
display[0] = content[0]; display[0] = content[0];
display[1] = content[1]; display[1] = content[1];
display[2] = content[2]; display[2] = content[2];
if (content.Length == 6 && (content[5] != null || content[5].Length > 2)) display[3] = (await VersionString.GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0")).ToShortString();
display[3] = ((await ServerCom.ReadTextFromFile(content[5])).Count + 1).ToString(); if (Config.PluginConfig.Contains(content[0]) || Config.PluginConfig.Contains(content[0]))
display[4] = "✓";
else display[3] = "1"; else
display[4] = "X";
data.Add(display); data.Add(display);
continue;
} }
} }
else if (op == Others.OperatingSystem.LINUX) else if (op == OperatingSystem.LINUX)
{ {
if (content[4].Contains("Linux")) if (content[4].Contains("Linux"))
{ {
display[0] = content[0]; display[0] = content[0];
display[1] = content[1]; display[1] = content[1];
display[2] = content[2]; display[2] = content[2];
display[3] = (await VersionString.GetVersionOfPackageFromWeb(content[0]) ?? new VersionString("0.0.0")).ToShortString();
if (Config.PluginConfig.Contains(content[0]) || Config.PluginConfig.Contains(content[0]))
display[4] = "✓";
else
display[4] = "X";
data.Add(display); data.Add(display);
continue;
} }
} }
} }
data.Add(new string[] { "-", "-", "-", "-" }); data.Add(new[] { "-", "-", "-", "-", "-" });
Console_Utilities.FormatAndAlignTable(data); Console_Utilities.FormatAndAlignTable(data, TableFormat.CENTER_EACH_COLUMN_BASED);
} }
catch (Exception exception) catch (Exception exception)
{ {
Console.WriteLine("Failed to execute command: listlang\nReason: " + exception.Message); Console.WriteLine("Failed to execute command: listplugs\nReason: " + exception.Message);
Others.Functions.WriteErrFile(exception.ToString()); Functions.WriteErrFile(exception.ToString());
} }
} }
/// <summary> /// <summary>
@@ -97,32 +102,28 @@ namespace PluginManager.Online
{ {
try try
{ {
List<string> list = await ServerCom.ReadTextFromFile(PluginsLink); var list = await ServerCom.ReadTextFromURL(PluginsLink);
string[] lines = list.ToArray(); var lines = list.ToArray();
int len = lines.Length; var len = lines.Length;
for (int i = 0; i < len; i++) for (var i = 0; i < len; i++)
{ {
string[] contents = lines[i].Split(','); var contents = lines[i].Split(',');
if (contents[0] == name) if (contents[0] == name)
{ {
if (contents.Length == 6) if (contents.Length == 6)
return new string[] { contents[2], contents[3], contents[5] }; return new[] { contents[2], contents[3], contents[5] };
else if (contents.Length == 5) if (contents.Length == 5)
return new string[] { contents[2], contents[3], string.Empty }; return new[] { contents[2], contents[3], string.Empty };
else throw new Exception("Failed to download plugin. Invalid Argument Length"); throw new Exception("Failed to download plugin. Invalid Argument Length");
} }
} }
} }
catch (Exception exception) catch (Exception exception)
{ {
Console.WriteLine("Failed to execute command: listplugs\nReason: " + exception.Message); Console.WriteLine("Failed to execute command: listplugs\nReason: " + exception.Message);
Others.Functions.WriteErrFile(exception.ToString()); Functions.WriteErrFile(exception.ToString());
} }
return new string[] { null!, null!, null! }; return new string[] { null!, null!, null! };
} }
}
} }

View File

@@ -1,22 +1,22 @@
using PluginManager.Online.Helpers; using PluginManager.Online.Helpers;
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.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using PluginManager.Others;
namespace PluginManager.Online namespace PluginManager.Online
{ {
public class ServerCom public static class ServerCom
{ {
/// <summary> /// <summary>
/// Read all lines from a file async /// Read all lines from a file async
/// </summary> /// </summary>
/// <param name="link">The link of the file</param> /// <param name="link">The link of the file</param>
/// <returns></returns> /// <returns></returns>
public static async Task<List<string>> ReadTextFromFile(string link) public static async Task<List<string>> ReadTextFromURL(string link)
{ {
string response = await OnlineFunctions.DownloadStringAsync(link); string response = await OnlineFunctions.DownloadStringAsync(link);
string[] lines = response.Split('\n'); string[] lines = response.Split('\n');
@@ -52,35 +52,37 @@ namespace PluginManager.Online
public static async Task DownloadFileAsync(string URL, string location) public static async Task DownloadFileAsync(string URL, string location)
{ {
bool isDownloading = true; bool isDownloading = true;
int c_progress = 0; float c_progress = 0;
Others.Console_Utilities.ProgressBar pbar = new Others.Console_Utilities.ProgressBar(100, ""); Console_Utilities.ProgressBar pbar = new Console_Utilities.ProgressBar(ProgressBarType.NORMAL) { Max = 100f, NoColor = true };
IProgress<float> progress = new Progress<float>(percent => { c_progress = percent; });
IProgress<float> progress = new Progress<float>(percent =>
{
c_progress = (int)percent;
});
Task updateProgressBarTask = new Task(() => Task updateProgressBarTask = new Task(() =>
{ {
while (isDownloading) while (isDownloading)
{ {
pbar.Update(c_progress); pbar.Update(c_progress);
if (c_progress == 100) if (c_progress == 100f)
break; break;
System.Threading.Thread.Sleep(500); Thread.Sleep(500);
} }
}); }
);
new System.Threading.Thread(updateProgressBarTask.Start).Start(); new Thread(updateProgressBarTask.Start).Start();
await DownloadFileAsync(URL, location, progress); await DownloadFileAsync(URL, location, progress);
c_progress = 100; c_progress = pbar.Max;
pbar.Update(100); pbar.Update(100f);
isDownloading = false; isDownloading = false;
}
public static async Task DownloadFileNoProgressAsync(string URL, string location)
{
IProgress<float> progress = new Progress<float>();
await DownloadFileAsync(URL, location, progress);
} }
} }

View File

@@ -0,0 +1,51 @@
using PluginManager.Items;
using PluginManager.Online.Helpers;
using PluginManager.Others;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PluginManager.Online.Updates
{
public class PluginUpdater
{
public static async Task<bool> CheckForUpdates(string pakName)
{
try
{
var webV = await VersionString.GetVersionOfPackageFromWeb(pakName);
var local = VersionString.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)
{
string url = "https://raw.githubusercontent.com/Wizzy69/installer/discord-bot-files/Versions";
List<string> info = await ServerCom.ReadTextFromURL(url);
VersionString? version = await VersionString.GetVersionOfPackageFromWeb(pakName);
if (version is null) return Update.Empty;
Update update = new Update(pakName, string.Join('\n', info), version);
return update;
}
public static async Task Download(string pakName)
{
Console_Utilities.WriteColorText("An update was found for &g" + pakName + "&c. Version: &r" + (await VersionString.GetVersionOfPackageFromWeb(pakName))?.ToShortString() + "&c. Current Version: &y" + VersionString.GetVersionOfPackage(pakName)?.ToShortString());
await ConsoleCommandsHandler.ExecuteCommad("dwplug " + pakName);
}
}
}

View File

@@ -0,0 +1,36 @@
using PluginManager.Online.Helpers;
namespace PluginManager.Online.Updates
{
public class Update
{
public static Update Empty = new Update(null, null, null);
public string pakName;
public string UpdateMessage;
public VersionString newVersion;
private bool isEmpty;
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 System.Exception("The update is EMPTY. Can not print information about an empty update !");
return $"Package Name: {this.pakName}\n" +
$"Update Message: {UpdateMessage}\n" +
$"Version: {newVersion.ToString()}";
}
}
}

View File

@@ -1,9 +1,8 @@
using System.Threading.Tasks;
using Discord; using Discord;
using System.Threading.Tasks; namespace PluginManager.Others;
namespace PluginManager.Others
{
/// <summary> /// <summary>
/// A class that handles the sending of messages to the user. /// A class that handles the sending of messages to the user.
/// </summary> /// </summary>
@@ -14,29 +13,48 @@ namespace PluginManager.Others
/// </summary> /// </summary>
/// <param name="server">The server</param> /// <param name="server">The server</param>
/// <param name="name">The channel name</param> /// <param name="name">The channel name</param>
/// <returns><see cref="IGuildChannel"/></returns> /// <returns>
public static IGuildChannel GetTextChannel(this IGuild server, string name) => server.GetTextChannel(name); /// <see cref="IGuildChannel" />
/// </returns>
public static IGuildChannel GetTextChannel(this IGuild server, string name)
{
return server.GetTextChannel(name);
}
/// <summary> /// <summary>
/// Get the voice channel by name from server /// Get the voice channel by name from server
/// </summary> /// </summary>
/// <param name="server">The server</param> /// <param name="server">The server</param>
/// <param name="name">The channel name</param> /// <param name="name">The channel name</param>
/// <returns><see cref="IGuildChannel"/></returns> /// <returns>
public static IGuildChannel GetVoiceChannel(this IGuild server, string name) => server.GetVoiceChannel(name); /// <see cref="IGuildChannel" />
/// </returns>
public static IGuildChannel GetVoiceChannel(this IGuild server, string name)
{
return server.GetVoiceChannel(name);
}
/// <summary> /// <summary>
/// Get the DM channel between <see cref="Discord.WebSocket.DiscordSocketClient" /> and <see cref="IGuildUser" /> /// Get the DM channel between <see cref="Discord.WebSocket.DiscordSocketClient" /> and <see cref="IGuildUser" />
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="user"></param>
/// <returns><see cref="IDMChannel"/></returns> /// <returns>
public static async Task<IDMChannel> GetDMChannel(IGuildUser user) => await user.CreateDMChannelAsync(); /// <see cref="IDMChannel" />
/// </returns>
public static async Task<IDMChannel> GetDMChannel(IGuildUser user)
{
return await user.CreateDMChannelAsync();
}
/// <summary> /// <summary>
/// Get the channel where the message was sent /// Get the channel where the message was sent
/// </summary> /// </summary>
/// <param name="message">The message</param> /// <param name="message">The message</param>
/// <returns><see cref="IChannel"/></returns> /// <returns>
public static IChannel GetChannel(IMessage message) => message.Channel; /// <see cref="IChannel" />
/// </returns>
public static IChannel GetChannel(IMessage message)
{
return message.Channel;
} }
} }

View File

@@ -1,35 +1,115 @@
using System; using Discord;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace PluginManager.Others namespace PluginManager.Others
{ {
public class Console_Utilities public static class Console_Utilities
{ {
public static void Initialize()
{
if (!Config.ContainsKey("TableVariables"))
Config.AddValueToVariables("TableVariables", new Dictionary<string, string> { { "DefaultSpace", "3" } }, false);
if (!Config.ContainsKey("ColorDataBase"))
Config.AddValueToVariables("ColorDataBase", new Dictionary<char, ConsoleColor>()
{
{ 'g', ConsoleColor.Green },
{ 'b', ConsoleColor.Blue },
{ 'r', ConsoleColor.Red },
{ 'm', ConsoleColor.Magenta },
{ 'y', ConsoleColor.Yellow },
}, false
);
if (!Config.ContainsKey("ColorPrefix"))
Config.AddValueToVariables("ColorPrefix", '&', false);
}
/// <summary> /// <summary>
/// Progress bar object /// Progress bar object
/// </summary> /// </summary>
public class ProgressBar public class ProgressBar
{ {
public int Max { get; set; } public ProgressBar(ProgressBarType type)
public string Message { get; set; }
public ConsoleColor Color { get; init; }
public ProgressBar(int max, string message)
{ {
Max = max; this.type = type;
Message = message;
var consoleColors = Enum.GetValues(typeof(ConsoleColor));
while ((Color = (ConsoleColor)consoleColors.GetValue(new Random().Next(consoleColors.Length))!) == ConsoleColor.White && Color != ConsoleColor.Black) ;
} }
public void Update(int progress, double speed = -1, string? unit = null) public float Max { get; init; }
{ public ConsoleColor Color { get; init; }
public bool NoColor { get; init; }
public ProgressBarType type { get; set; }
//progress bar private int BarLength = 32;
private int position = 1;
private bool positive = true;
private bool isRunning;
public async void Start()
{
if (type != ProgressBarType.NO_END)
throw new Exception("Only NO_END progress bar can use this method");
if (isRunning)
throw new Exception("This progress bar is already running");
isRunning = true;
while (isRunning)
{
UpdateNoEnd();
await System.Threading.Tasks.Task.Delay(100);
}
}
public void Stop()
{
if (type != ProgressBarType.NO_END)
throw new Exception("Only NO_END progress bar can use this method");
if (!isRunning)
throw new Exception("Can not stop a progressbar that did not start");
isRunning = false;
}
public void Update(float progress)
{
switch (type)
{
case ProgressBarType.NORMAL:
UpdateNormal(progress);
return;
case ProgressBarType.NO_END:
if (progress <= 99.9f)
UpdateNoEnd();
return;
default:
return;
}
}
private void UpdateNoEnd()
{
Console.CursorLeft = 0; Console.CursorLeft = 0;
Console.Write("["); Console.Write("[");
Console.CursorLeft = 32; for (int i = 1; i <= position; i++)
Console.Write(" ");
Console.Write("<==()==>");
position += positive ? 1 : -1;
for (int i = position; i <= BarLength - 1 - (positive ? 0 : 2); i++)
Console.Write(" ");
Console.Write("]");
if (position == BarLength - 1 || position == 1)
positive = !positive;
}
private void UpdateNormal(float progress)
{
Console.CursorLeft = 0;
Console.Write("[");
Console.CursorLeft = BarLength;
Console.Write("]"); Console.Write("]");
Console.CursorLeft = 1; Console.CursorLeft = 1;
float onechunk = 30.0f / Max; float onechunk = 30.0f / Max;
@@ -38,38 +118,38 @@ namespace PluginManager.Others
for (int i = 0; i < onechunk * progress; i++) for (int i = 0; i < onechunk * progress; i++)
{ {
Console.BackgroundColor = this.Color; Console.BackgroundColor = NoColor ? ConsoleColor.Black : this.Color;
Console.CursorLeft = position++; Console.CursorLeft = position++;
Console.Write(" "); Console.Write("#");
} }
for (int i = position; i <= 31; i++) for (int i = position; i < BarLength; i++)
{ {
Console.BackgroundColor = ConsoleColor.Gray; Console.BackgroundColor = NoColor ? ConsoleColor.Black : ConsoleColor.DarkGray;
Console.CursorLeft = position++; Console.CursorLeft = position++;
Console.Write(" "); Console.Write(" ");
} }
Console.CursorLeft = 35; Console.CursorLeft = BarLength + 4;
Console.BackgroundColor = ConsoleColor.Black; Console.BackgroundColor = ConsoleColor.Black;
if (speed == -1 || unit == null) if (progress.CanAproximateTo(Max))
{ Console.Write(progress + " % ✓");
if (progress == Max)
Console.Write(progress.ToString() + " % ✓");
else Console.Write(progress.ToString() + " % ");
}
else else
Console.Write(progress.ToString() + $"{speed} {unit}/s "); Console.Write(MathF.Round(progress, 2) + " % ");
}
}
}
} private static bool CanAproximateTo(this float f, float y) => (MathF.Abs(f - y) < 0.000001);
/// <summary> /// <summary>
/// A way to create a table based on input data /// A way to create a table based on input data
/// </summary> /// </summary>
/// <param name="data">The List of arrays of strings that represent the rows.</param> /// <param name="data">The List of arrays of strings that represent the rows.</param>
public static void FormatAndAlignTable(List<string[]> data) public static void FormatAndAlignTable(List<string[]> data, TableFormat format)
{
if (format == TableFormat.CENTER_EACH_COLUMN_BASED)
{ {
char tableLine = '-'; char tableLine = '-';
char tableCross = '+'; char tableCross = '+';
@@ -77,17 +157,17 @@ namespace PluginManager.Others
int[] len = new int[data[0].Length]; int[] len = new int[data[0].Length];
foreach (var line in data) foreach (var line in data)
{
for (int i = 0; i < line.Length; i++) for (int i = 0; i < line.Length; i++)
if (line[i].Length > len[i]) if (line[i].Length > len[i])
len[i] = line[i].Length; len[i] = line[i].Length;
}
foreach (string[] row in data) foreach (string[] row in data)
{ {
if (row[0][0] == tableLine) Console.Write(tableCross); if (row[0][0] == tableLine)
else Console.Write(tableWall); Console.Write(tableCross);
else
Console.Write(tableWall);
for (int l = 0; l < row.Length; l++) for (int l = 0; l < row.Length; l++)
{ {
if (row[l][0] == tableLine) if (row[l][0] == tableLine)
@@ -103,7 +183,6 @@ namespace PluginManager.Others
} }
else else
{ {
int lenHalf = row[l].Length / 2; int lenHalf = row[l].Length / 2;
for (int i = 0; i < ((len[l] + 4) / 2 - lenHalf); ++i) for (int i = 0; i < ((len[l] + 4) / 2 - lenHalf); ++i)
Console.Write(" "); Console.Write(" ");
@@ -114,47 +193,132 @@ namespace PluginManager.Others
Console.Write(" "); Console.Write(" ");
} }
if (row[l][0] == tableLine) Console.Write(tableCross); Console.Write(row[l][0] == tableLine ? tableCross : tableWall);
else Console.Write(tableWall);
} }
Console.WriteLine(); //end line Console.WriteLine(); //end line
}
} }
public static void WriteColorText(string text, bool appendNewLine = true) return;
}
if (format == TableFormat.CENTER_OVERALL_LENGTH)
{ {
int maxLen = 0;
foreach (string[] row in data)
foreach (string s in row)
if (s.Length > maxLen)
maxLen = s.Length;
string[] words = text.Split(' '); int div = (maxLen + 4) / 2;
ConsoleColor fg = Console.ForegroundColor;
Dictionary<string, ConsoleColor> colors = new Dictionary<string, ConsoleColor>() foreach (string[] row in data)
{ {
{ "&g", ConsoleColor.Green }, Console.Write("\t");
{ "&b", ConsoleColor.Blue }, if (row[0] == "-")
{ "&r", ConsoleColor.Red }, Console.Write("+");
{ "&m", ConsoleColor.Magenta }, else
{ "&y", ConsoleColor.Yellow }, Console.Write("|");
{ "&c", fg }
}; foreach (string s in row)
foreach (string word in words)
{ {
if (word.Length >= 2) if (s == "-")
{ {
string prefix = word.Substring(0, 2); for (int i = 0; i < maxLen + 4; ++i)
if (colors.ContainsKey(prefix)) Console.Write("-");
Console.ForegroundColor = colors[prefix]; }
else if (s.Length == maxLen)
{
Console.Write(" ");
Console.Write(s);
Console.Write(" ");
}
else
{
int lenHalf = s.Length / 2;
for (int i = 0; i < div - lenHalf; ++i)
Console.Write(" ");
Console.Write(s);
for (int i = div + lenHalf + 1; i < maxLen + 4; ++i)
Console.Write(" ");
if (s.Length % 2 == 0)
Console.Write(" ");
} }
string m = word; if (s == "-")
foreach (var key in colors.Keys) { m = m.Replace(key, ""); } Console.Write("+");
else
Console.Write(m + " "); Console.Write("|");
}
if (appendNewLine)
Console.Write('\n');
Console.ForegroundColor = fg;
} }
Console.WriteLine(); //end line
}
return;
}
if (format == TableFormat.DEFAULT)
{
int[] widths = new int[data[0].Length];
int space_between_columns = int.Parse(Config.GetValue<Dictionary<string, string>>("TableVariables")?["DefaultSpace"]!);
for (int i = 0; i < data.Count; i++)
{
for (int j = 0; j < data[i].Length; j++)
{
if (data[i][j].Length > widths[j])
widths[j] = data[i][j].Length;
}
}
for (int i = 0; i < data.Count; i++)
{
for (int j = 0; j < data[i].Length; j++)
{
if (data[i][j] == "-")
data[i][j] = " ";
Console.Write(data[i][j]);
for (int k = 0; k < widths[j] - data[i][j].Length + 1 + space_between_columns; k++)
Console.Write(" ");
}
Console.WriteLine();
}
return;
}
throw new Exception("Unknown type of table");
}
public static void WriteColorText(string text, bool appendNewLineAtEnd = true)
{
ConsoleColor initialForeGround = Console.ForegroundColor;
char[] input = text.ToCharArray();
for (int i = 0; i < input.Length; i++)
{
if (input[i] == Config.GetValue<char>("ColorPrefix"))
{
if (i + 1 < input.Length)
{
if (Config.GetValue<Dictionary<char, ConsoleColor>>("ColorDataBase")!.ContainsKey(input[i + 1]))
{
Console.ForegroundColor = Config.GetValue<Dictionary<char, ConsoleColor>>("ColorDataBase")![input[i + 1]];
i++;
}
else if (input[i + 1] == 'c')
{
Console.ForegroundColor = initialForeGround;
i++;
}
}
}
else
Console.Write(input[i]);
}
Console.ForegroundColor = initialForeGround;
if (appendNewLineAtEnd)
Console.WriteLine();
}
} }
} }

View File

@@ -1,91 +0,0 @@
using System;
namespace PluginManager.Others
{
public class Cryptography
{
/// <summary>
/// Translate hex to string
/// </summary>
/// <param name="hexString">The encrypted string</param>
/// <returns></returns>
public static string FromHexToString(string hexString)
{
var bytes = new byte[hexString.Length / 2];
for (var i = 0; i < bytes.Length; i++)
{
bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
}
return System.Text.Encoding.Unicode.GetString(bytes);
}
/// <summary>
/// Translate string to hex
/// </summary>
/// <param name="str">The string to encrypt</param>
/// <returns></returns>
public static string ToHexString(string str)
{
var sb = new System.Text.StringBuilder();
var bytes = System.Text.Encoding.Unicode.GetBytes(str);
foreach (var t in bytes)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString();
}
/// <summary>
/// Create MD5 hash
/// </summary>
/// <param name="text">The text to encrypt</param>
/// <returns></returns>
public static async System.Threading.Tasks.Task<string> CreateMD5(string text)
{
string output = "";
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
using (var s = GenerateStreamFromString(text))
{
byte[] t = await md5.ComputeHashAsync(s);
output = System.Convert.ToBase64String(t);
}
}
return output;
}
/// <summary>
/// Create SHA256 hash
/// </summary>
/// <param name="text">The text to encrypt</param>
/// <returns></returns>
public static async System.Threading.Tasks.Task<string> CreateSHA256(string text)
{
string output = "";
using (System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create())
{
using (var s = GenerateStreamFromString(text))
{
byte[] t = await sha.ComputeHashAsync(s);
output = System.Convert.ToBase64String(t);
}
}
return output;
}
private static System.IO.Stream GenerateStreamFromString(string s)
{
var stream = new System.IO.MemoryStream();
var writer = new System.IO.StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
}
}

View File

@@ -1,20 +1,36 @@
namespace PluginManager.Others using PluginManager.Interfaces;
{
namespace PluginManager.Others;
/// <summary> /// <summary>
/// A list of operating systems /// A list of operating systems
/// </summary> /// </summary>
public enum OperatingSystem public enum OperatingSystem
{ WINDOWS, LINUX, MAC_OS, UNKNOWN } {
WINDOWS, LINUX, MAC_OS, UNKNOWN
}
/// <summary> /// <summary>
/// A list with all errors /// A list with all errors
/// </summary> /// </summary>
public enum Error public enum Error
{ UNKNOWN_ERROR, GUILD_NOT_FOUND, STREAM_NOT_FOUND, INVALID_USER, INVALID_CHANNEL, INVALID_PERMISSIONS } {
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 { NONE, INFO, WARNING, ERROR, CRITICAL } public enum OutputLogLevel { NONE, INFO, WARNING, ERROR, CRITICAL }
}
/// <summary>
/// Plugin Type
/// </summary>
public enum PluginType { Command, Event, Unknown }
public enum UnzipProgressType { PercentageFromNumberOfFiles, PercentageFromTotalSize }
public enum TableFormat { CENTER_EACH_COLUMN_BASED, CENTER_OVERALL_LENGTH, DEFAULT }
public enum SaveType { NORMAL, BACKUP }
public enum ProgressBarType { NORMAL, NO_END }

View File

@@ -1,94 +0,0 @@
using System;
namespace PluginManager.Others.Exceptions
{
/// <summary>
/// Custom Exception for PluginManager
/// </summary>
[Serializable]
public class APIException : Exception
{
/// <summary>
/// The function where the error occurred
/// </summary>
public string? Function { get; } = "not specified";
/// <summary>
/// The error code
/// </summary>
public Error? ErrorCode { get; } = Error.UNKNOWN_ERROR;
/// <summary>
/// The possible cause that determined the error
/// </summary>
public string? PossibleCause { get; } = "not specified";
/// <summary>
/// The APIException contructor
/// </summary>
/// <param name="message">The error message</param>
/// <param name="function">The function where the message was triggered</param>
/// <param name="possible_cause">The possible cause of the error</param>
/// <param name="error">The error code</param>
public APIException(string message, string? function, string possible_cause, Error error) : base(message)
{
ErrorCode = error;
Function = function;
PossibleCause = possible_cause;
}
/// <summary>
/// The APIException contructor
/// </summary>
/// <param name="message">The error message</param>
/// <param name="function">The function where the message was triggered</param>
/// <param name="errorCode">The error code</param>
public APIException(string message, string? function, Error? errorCode) : base(message)
{
ErrorCode = errorCode;
Function = function;
}
/// <summary>
/// The APIException contructor
/// </summary>
/// <param name="message">The error message</param>
/// <param name="function">The function where the message was triggered</param>
public APIException(string message, string? function) : base(message)
{
Function = function;
}
/// <summary>
/// The APIException contructor
/// </summary>
/// <param name="message">The error message</param>
public APIException(string message) : base(message)
{
}
/// <summary>
/// The APIException constructor
/// </summary>
/// <param name="message">The error message</param>
/// <param name="errorLocation">The class where the error was thrown</param>
public APIException(string message, Type errorLocation) : base(message)
{
Function = errorLocation.FullName;
}
/// <summary>
/// Method to print the error to <see cref="Console"/>
/// </summary>
public void Print()
{
Console.WriteLine("Message Content: " + Message);
Console.WriteLine("Function: " + Function);
Console.WriteLine("Error Code: " + ErrorCode.ToString());
Console.WriteLine("Possible cause: " + PossibleCause);
if (this.StackTrace != null)
Functions.WriteErrFile(this.StackTrace);
}
}
}

View File

@@ -4,6 +4,7 @@ using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Security.Cryptography;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Items; using PluginManager.Items;
using System.Threading; using System.Threading;
@@ -25,22 +26,22 @@ namespace PluginManager.Others
/// <summary> /// <summary>
/// The location for all logs /// The location for all logs
/// </summary> /// </summary>
public static readonly string logFolder = @"./Output/Logs/"; public static readonly string logFolder = @"./Data/Output/Logs/";
/// <summary> /// <summary>
/// The location for all errors /// The location for all errors
/// </summary> /// </summary>
public static readonly string errFolder = @"./Output/Errors/"; public static readonly string errFolder = @"./Data/Output/Errors/";
/// <summary>
/// The location for all languages
/// </summary>
public static readonly string langFolder = @"./Data/Languages/";
/// <summary> /// <summary>
/// Archives folder /// Archives folder
/// </summary> /// </summary>
public static readonly string pakFolder = @"./Data/Resources/PAKS/"; public static readonly string pakFolder = @"./Data/PAKS/";
/// <summary>
/// Beta testing folder
/// </summary>
public static readonly string betaFolder = @"./Data/BetaTest/";
/// <summary> /// <summary>
@@ -49,30 +50,19 @@ namespace PluginManager.Others
/// <param name="FileName">The file name that is inside the archive or its full path</param> /// <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> /// <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> /// <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) public static async Task<Stream?> ReadFromPakAsync(string FileName, string archFile)
{ {
archFile = pakFolder + archFile; archFile = pakFolder + archFile;
Directory.CreateDirectory(pakFolder); Directory.CreateDirectory(pakFolder);
if (!File.Exists(archFile)) throw new FileNotFoundException("Failed to load file !"); if (!File.Exists(archFile)) throw new FileNotFoundException("Failed to load file !");
string? textValue = null; using ZipArchive archive = ZipFile.OpenRead(archFile);
var fs = new FileStream(archFile, FileMode.Open); ZipArchiveEntry? entry = archive.GetEntry(FileName);
var zip = new ZipArchive(fs, ZipArchiveMode.Read); if (entry is null) return Stream.Null;
foreach (var entry in zip.Entries) MemoryStream stream = new MemoryStream();
{ await (entry?.Open()!).CopyToAsync(stream);
if (entry.Name == FileName || entry.FullName == FileName)
{
Stream s = entry.Open();
StreamReader reader = new StreamReader(s);
textValue = await reader.ReadToEndAsync();
reader.Close();
s.Close();
fs.Close();
break;
}
}
return textValue; return stream;
} }
/// <summary> /// <summary>
@@ -81,8 +71,8 @@ namespace PluginManager.Others
/// <param name="LogMessage">The message to be wrote</param> /// <param name="LogMessage">The message to be wrote</param>
public static void WriteLogFile(string LogMessage) public static void WriteLogFile(string LogMessage)
{ {
string logsPath = logFolder + "Log.txt"; string logsPath = logFolder + $"{DateTime.Today.ToShortDateString().Replace("/", "-").Replace("\\", "-")} Log.txt";
if (!Directory.Exists(logFolder)) Directory.CreateDirectory(logFolder); Directory.CreateDirectory(logFolder);
File.AppendAllText(logsPath, LogMessage + " \n"); File.AppendAllText(logsPath, LogMessage + " \n");
} }
@@ -92,11 +82,16 @@ namespace PluginManager.Others
/// <param name="ErrMessage">The message to be wrote</param> /// <param name="ErrMessage">The message to be wrote</param>
public static void WriteErrFile(string ErrMessage) public static void WriteErrFile(string ErrMessage)
{ {
string errPath = errFolder + "Error.txt"; string errPath = errFolder + $"{DateTime.Today.ToShortDateString().Replace("/", "-").Replace("\\", "-")} Error.txt";
if (!Directory.Exists(errFolder)) Directory.CreateDirectory(errFolder); Directory.CreateDirectory(errFolder);
File.AppendAllText(errPath, ErrMessage + " \n"); File.AppendAllText(errPath, ErrMessage + " \n");
} }
public static void WriteErrFile(this Exception ex)
{
WriteErrFile(ex.ToString());
}
/// <summary> /// <summary>
/// Merge one array of strings into one string /// Merge one array of strings into one string
/// </summary> /// </summary>
@@ -173,19 +168,21 @@ namespace PluginManager.Others
/// </summary> /// </summary>
/// <param name="zip">The zip location</param> /// <param name="zip">The zip location</param>
/// <param name="folder">The target 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> /// <returns></returns>
public static async Task ExtractArchive(string zip, string folder, IProgress<float> progress) public static async Task ExtractArchive(string zip, string folder, IProgress<float> progress, UnzipProgressType type)
{ {
if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); Directory.CreateDirectory(folder);
using (ZipArchive archive = ZipFile.OpenRead(zip)) using (ZipArchive archive = ZipFile.OpenRead(zip))
{
if (type == UnzipProgressType.PercentageFromNumberOfFiles)
{ {
int totalZIPFiles = archive.Entries.Count(); int totalZIPFiles = archive.Entries.Count();
int currentZIPFile = 0; int currentZIPFile = 0;
foreach (ZipArchiveEntry entry in archive.Entries) foreach (ZipArchiveEntry entry in archive.Entries)
{ {
if (entry.FullName.EndsWith("/")) if (entry.FullName.EndsWith("/")) // it is a folder
Directory.CreateDirectory(Path.Combine(folder, entry.FullName)); Directory.CreateDirectory(Path.Combine(folder, entry.FullName));
else else
@@ -193,15 +190,49 @@ namespace PluginManager.Others
{ {
entry.ExtractToFile(Path.Combine(folder, entry.FullName), true); entry.ExtractToFile(Path.Combine(folder, entry.FullName), true);
} }
catch catch (Exception ex)
{ {
Console.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}");
} }
currentZIPFile++; currentZIPFile++;
await Task.Delay(10); await Task.Delay(10);
if (progress != null)
progress.Report((float)currentZIPFile / totalZIPFiles * 100); progress.Report((float)currentZIPFile / totalZIPFiles * 100);
} }
} }
else if (type == UnzipProgressType.PercentageFromTotalSize)
{
ulong zipSize = 0;
foreach (ZipArchiveEntry entry in archive.Entries)
zipSize += (ulong)entry.CompressedLength;
ulong currentSize = 0;
foreach (ZipArchiveEntry 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)
{
Console.WriteLine($"Failed to extract {entry.Name}. Exception: {ex.Message}");
}
await Task.Delay(10);
if (progress != null)
progress.Report((float)currentSize / zipSize * 100);
}
}
}
} }
@@ -212,11 +243,22 @@ namespace PluginManager.Others
/// <returns></returns> /// <returns></returns>
public static (double, string) ConvertBytes(long bytes) public static (double, string) ConvertBytes(long bytes)
{ {
if (bytes < 1024) return (bytes, "B"); List<string> units = new List<string>()
if (bytes < 1024 * 1024) return (bytes / 1024.0, "KB"); {
if (bytes < 1024 * 1024 * 1024) return (bytes / 1024.0 / 1024.0, "MB"); "B",
return (bytes / 1024.0 / 1024.0 / 1024.0, "GB"); "KB",
"MB",
"GB",
"TB"
};
int i = 0;
while (bytes >= 1024)
{
i++;
bytes /= 1024;
}
return (bytes, units[i]);
} }
/// <summary> /// <summary>
@@ -228,8 +270,9 @@ namespace PluginManager.Others
/// <returns></returns> /// <returns></returns>
public static async Task SaveToJsonFile<T>(string file, T Data) public static async Task SaveToJsonFile<T>(string file, T Data)
{ {
string jsonText = JsonSerializer.Serialize(Data, typeof(T), new JsonSerializerOptions { WriteIndented = true }); MemoryStream str = new MemoryStream();
await File.WriteAllTextAsync(file, jsonText); await JsonSerializer.SerializeAsync(str, Data, typeof(T), new JsonSerializerOptions { WriteIndented = true });
await File.WriteAllBytesAsync(file, str.ToArray());
} }
/// <summary> /// <summary>
@@ -242,14 +285,42 @@ namespace PluginManager.Others
{ {
Stream text; Stream text;
if (File.Exists(input)) if (File.Exists(input))
text = File.Open(input, FileMode.OpenOrCreate); text = new MemoryStream(await File.ReadAllBytesAsync(input));
else else
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);
text.Close(); text.Close();
return obj; return (obj ?? default)!;
}
/// <summary>
/// Check if all words from <paramref name="str"/> are in <paramref name="baseString"/><br/>
/// This function returns true if<br/>
/// 1. The <paramref name="str"/> is part of <paramref name="baseString"/><br/>
/// 2. The words (split by a space) of <paramref name="str"/> are located (separately) in <paramref name="baseString"/> <br/>
/// <example>
/// The following example will return <see langword="TRUE"/><br/>
/// <c>STRContains("Hello World !", "I type word Hello and then i typed word World !")</c><br/>
/// The following example will return <see langword="TRUE"/><br/>
/// <c>STRContains("Hello World !", "I typed Hello World !" </c><br/>
/// The following example will return <see langword="TRUE"/><br/>
/// <c>STRContains("Hello World", "I type World then Hello")</c><br/>
/// The following example will return <see langword="FALSE"/><br/>
/// <c>STRContains("Hello World !", "I typed Hello World")</c><br/>
/// </example>
/// </summary>
/// <param name="str">The string you are checking</param>
/// <param name="baseString">The main string that should contain <paramref name="str"/></param>
/// <returns></returns>
public static bool STRContains(this string str, string baseString)
{
if (baseString.Contains(str)) return true;
string[] array = str.Split(' ');
foreach (var s in array)
if (!baseString.Contains(s))
return false;
return true;
} }
public static bool TryReadValueFromJson(string input, string codeName, out JsonElement element) public static bool TryReadValueFromJson(string input, string codeName, out JsonElement element)
@@ -266,5 +337,15 @@ namespace PluginManager.Others
var data = jsonObject.RootElement.TryGetProperty(codeName, out element); var data = jsonObject.RootElement.TryGetProperty(codeName, out element);
return data; return data;
} }
public static string CreateMD5(string input)
{
using (MD5 md5 = MD5.Create())
{
byte[] inputBytes = Encoding.ASCII.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
return Convert.ToHexString(hashBytes);
}
}
} }
} }

View File

@@ -1,10 +1,9 @@
using Discord; using System.Linq;
using Discord;
using Discord.WebSocket; using Discord.WebSocket;
using System.Linq; namespace PluginManager.Others.Permissions;
namespace PluginManager.Others.Permissions
{
/// <summary> /// <summary>
/// A class whith all discord permissions /// A class whith all discord permissions
/// </summary> /// </summary>
@@ -16,7 +15,10 @@ namespace PluginManager.Others.Permissions
/// <param name="role">The role</param> /// <param name="role">The role</param>
/// <param name="permission">The permission</param> /// <param name="permission">The permission</param>
/// <returns></returns> /// <returns></returns>
public static bool hasPermission(this IRole role, GuildPermission permission) => role.Permissions.Has(permission); public static bool hasPermission(this IRole role, GuildPermission permission)
{
return role.Permissions.Has(permission);
}
/// <summary> /// <summary>
/// Check if user has the specified role /// Check if user has the specified role
@@ -24,7 +26,10 @@ namespace PluginManager.Others.Permissions
/// <param name="user">The user</param> /// <param name="user">The user</param>
/// <param name="role">The role</param> /// <param name="role">The role</param>
/// <returns></returns> /// <returns></returns>
public static bool hasRole(this SocketGuildUser user, IRole role) => user.Roles.Contains(role); public static bool hasRole(this SocketGuildUser user, IRole role)
{
return user.Roles.Contains(role);
}
/// <summary> /// <summary>
/// Check if user has the specified permission /// Check if user has the specified permission
@@ -33,23 +38,27 @@ namespace PluginManager.Others.Permissions
/// <param name="permission">The permission</param> /// <param name="permission">The permission</param>
/// <returns></returns> /// <returns></returns>
public static bool hasPermission(this SocketGuildUser user, GuildPermission permission) public static bool hasPermission(this SocketGuildUser user, GuildPermission permission)
=> user.Roles.Where(role => role.hasPermission(permission)).Any() || user.Guild.Owner == user; {
/// <summary> return user.Roles.Where(role => role.hasPermission(permission)).Any() || user.Guild.Owner == user;
/// Check if user is administrator of server }
/// </summary>
/// <param name="user">The user</param>
/// <returns></returns>
public static bool isAdmin(this SocketGuildUser user) => user.hasPermission(GuildPermission.Administrator);
/// <summary> /// <summary>
/// Check if user is administrator of server /// Check if user is administrator of server
/// </summary> /// </summary>
/// <param name="user">The user</param> /// <param name="user">The user</param>
/// <returns></returns> /// <returns></returns>
public static bool isAdmin(this SocketUser user) => isAdmin((SocketGuildUser)user); public static bool isAdmin(this SocketGuildUser user)
{
return user.hasPermission(GuildPermission.Administrator);
} }
/// <summary>
/// Check if user is administrator of server
/// </summary>
/// <param name="user">The user</param>
/// <returns></returns>
public static bool isAdmin(this SocketUser user)
{
return isAdmin((SocketGuildUser)user);
}
} }

View File

@@ -16,7 +16,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Discord.Net" Version="3.6.1" /> <PackageReference Include="Discord.Net" Version="3.7.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -5,7 +5,6 @@ This project is based on:
- [.NET 6 (C#)](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) - [.NET 6 (C#)](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)
- [Discord.Net](https://github.com/discord-net/Discord.Net) - [Discord.Net](https://github.com/discord-net/Discord.Net)
- [Avalonia UI](https://avaloniaui.net/) for `DiscordBotUI` extension
## Plugins ## Plugins
@@ -17,7 +16,6 @@ Plugin Types:
1. Commands 1. Commands
2. Events 2. Events
### 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.

Some files were not shown because too many files have changed in this diff Show More