Removed UI and Added IsDisabled plugin property

This commit is contained in:
2024-07-04 16:12:55 +03:00
parent d186efcdaf
commit 79c6daa11a
21 changed files with 126 additions and 894 deletions

View File

@@ -48,7 +48,7 @@ namespace DiscordBot.Bot.Actions
}
FileInfo fileInfo = new FileInfo(path);
PluginInfo pluginInfo = new PluginInfo(args[0], new(1, 0, 0), [], false, true);
PluginInfo pluginInfo = new PluginInfo(args[0], new(1, 0, 0), [], false, true, false);
await Application.CurrentApplication.PluginManager.AppendPluginToDatabase(pluginInfo);
}
}

View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using DiscordBot.Utilities;
using DiscordBotCore;
using DiscordBotCore.Interfaces.PluginManager;
using DiscordBotCore.Loaders;
using DiscordBotCore.Online;
using DiscordBotCore.Others;
@@ -19,15 +20,17 @@ namespace DiscordBot.Bot.Actions.Extra;
internal static class PluginMethods
{
internal static async Task List(PluginManager manager)
internal static async Task List()
{
Console.WriteLine($"Fetching plugin list from branch {manager.Branch} ...");
var data = await ConsoleUtilities.ExecuteWithProgressBar(manager.GetPluginsList(), "Reading remote database");
Console.WriteLine($"Fetching plugin list from branch {Application.CurrentApplication.PluginManager.Branch} ...");
var data = await ConsoleUtilities.ExecuteWithProgressBar(Application.CurrentApplication.PluginManager.GetPluginsList(), "Reading remote database");
TableData tableData = new(["Name", "Description", "Version", "Is Installed", "Dependencies"]);
var installedPlugins = await ConsoleUtilities.ExecuteWithProgressBar(manager.GetInstalledPlugins(), "Reading local database ");
var installedPlugins = await ConsoleUtilities.ExecuteWithProgressBar(Application.CurrentApplication.PluginManager.GetInstalledPlugins(), "Reading local database ");
foreach (var plugin in data)
{
@@ -87,9 +90,19 @@ internal static class PluginMethods
}
internal static async Task DownloadPlugin(PluginManager manager, string pluginName)
internal static async Task DisablePlugin(string pluginName)
{
var pluginData = await manager.GetPluginDataByName(pluginName);
await Application.CurrentApplication.PluginManager.SetDisabledStatus(pluginName, true);
}
internal static async Task EnablePlugin(string pluginName)
{
await Application.CurrentApplication.PluginManager.SetDisabledStatus(pluginName, false);
}
internal static async Task DownloadPlugin(string pluginName)
{
var pluginData = await Application.CurrentApplication.PluginManager.GetPluginDataByName(pluginName);
if (pluginData is null)
{
Console.WriteLine($"Plugin {pluginName} not found. Please check the spelling and try again.");
@@ -127,12 +140,12 @@ internal static class PluginMethods
if (pluginData.HasScriptDependencies)
{
Console.WriteLine("Executing post install scripts ...");
await manager.ExecutePluginInstallScripts(pluginData.ScriptDependencies);
await Application.CurrentApplication.PluginManager.ExecutePluginInstallScripts(pluginData.ScriptDependencies);
}
PluginInfo pluginInfo = new(pluginName, pluginData.Version, []);
Console.WriteLine("Finished installing " + pluginName + " successfully");
await manager.AppendPluginToDatabase(pluginInfo);
await Application.CurrentApplication.PluginManager.AppendPluginToDatabase(pluginInfo);
await RefreshPlugins(false);
return;
}
@@ -175,7 +188,7 @@ internal static class PluginMethods
await Parallel.ForEachAsync(downloadTasks, options, async (tuple, token) =>
{
tuple.Item1.IsIndeterminate = false;
string downloadLocation = manager.GenerateDependencyLocation(pluginName, tuple.Item4);
string downloadLocation = Application.CurrentApplication.PluginManager.GenerateDependencyLocation(pluginName, tuple.Item4);
await ServerCom.DownloadFileAsync(tuple.Item3, downloadLocation, tuple.Item2);
}
);
@@ -189,10 +202,10 @@ internal static class PluginMethods
if(pluginData.HasScriptDependencies)
{
Console.WriteLine("Executing post install scripts ...");
await manager.ExecutePluginInstallScripts(pluginData.ScriptDependencies);
await Application.CurrentApplication.PluginManager.ExecutePluginInstallScripts(pluginData.ScriptDependencies);
}
await manager.AppendPluginToDatabase(PluginInfo.FromOnlineInfo(pluginData));
await Application.CurrentApplication.PluginManager.AppendPluginToDatabase(PluginInfo.FromOnlineInfo(pluginData));
await RefreshPlugins(false);
}

View File

@@ -29,6 +29,12 @@ public class Plugin: ICommandAction
new InternalActionOption("branch", "Sets a plugin option", [
new InternalActionOption("set", "Sets the branch"),
new InternalActionOption("get", "Gets the branch")
]),
new InternalActionOption("enable", "Enables a plugin", [
new InternalActionOption("name", "The name of the plugin to enable")
]),
new InternalActionOption("disable", "Disables a plugin", [
new InternalActionOption("name", "The name of the plugin to disable")
])
};
@@ -36,20 +42,40 @@ public class Plugin: ICommandAction
public async Task Execute(string[] args)
{
if (args is null || args.Length == 0 || args[0] == "help")
if (args is null || args.Length == 0)
{
Console.WriteLine("Usage : plugin [help|list|load|install]");
Console.WriteLine("help : Displays this message");
Console.WriteLine("list : Lists all plugins");
Console.WriteLine("load : Loads all plugins");
Console.WriteLine("install : Installs a plugin");
Console.WriteLine("refresh : Refreshes the plugin list");
await Application.CurrentApplication.InternalActionManager.Execute("help", ActionName);
return;
}
switch (args[0])
{
case "enable":
{
if (args.Length < 2)
{
Console.WriteLine("Usage : plugin enable <plugin name>");
return;
}
string pluginName = string.Join(' ', args, 1, args.Length - 1);
await Application.CurrentApplication.PluginManager.SetDisabledStatus(pluginName, false);
break;
}
case "disable":
{
if (args.Length < 2)
{
Console.WriteLine("Usage : plugin disable <plugin name>");
return;
}
string pluginName = string.Join(' ', args, 1, args.Length - 1);
await Application.CurrentApplication.PluginManager.SetDisabledStatus(pluginName, true);
break;
}
case "branch":
if (args.Length < 2)
{
@@ -87,14 +113,15 @@ public class Plugin: ICommandAction
break;
case "uninstall":
{
string plugName = string.Join(' ', args, 1, args.Length - 1);
bool result = await Application.CurrentApplication.PluginManager.MarkPluginToUninstall(plugName);
if (result)
Console.WriteLine($"Marked to uninstall plugin {plugName}. Please restart the bot");
break;
}
case "list":
await PluginMethods.List(Application.CurrentApplication.PluginManager);
await PluginMethods.List();
break;
case "load":
if (pluginsLoaded)
@@ -113,6 +140,7 @@ public class Plugin: ICommandAction
break;
case "install":
{
var pluginName = string.Join(' ', args, 1, args.Length - 1);
if (string.IsNullOrEmpty(pluginName) || pluginName.Length < 2)
{
@@ -126,8 +154,10 @@ public class Plugin: ICommandAction
}
}
await PluginMethods.DownloadPlugin(Application.CurrentApplication.PluginManager, pluginName);
await PluginMethods.DownloadPlugin(pluginName);
break;
}
}
}
}

View File

@@ -3,9 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace DiscordBot;
@@ -20,23 +17,13 @@ public static class Entry
{
File.Delete(plugin);
}
File.Delete("./Data/Resources/plugins.json");
Directory.Delete("./Libraries/", true);
})
];
private static readonly string logo =
#if DEBUG
@"
_____ _ _ _____ _ _ ____ _
/ ____| | | | | | __ \(_) | | | _ \ | |
| (___ ___| |_| |__ | | | |_ ___ ___ ___ _ __ __| | | |_) | ___ | |_
\___ \ / _ \ __| '_ \ | | | | / __|/ __/ _ \| '__/ _` | | _ < / _ \| __|
____) | __/ |_| | | | | |__| | \__ \ (_| (_) | | | (_| | | |_) | (_) | |_
|_____/ \___|\__|_| |_| |_____/|_|___/\___\___/|_| \__,_| |____/ \___/ \__|
(Debug)
";
#else
@"
_____ _ _ _____ _ _ ____ _
@@ -48,7 +35,6 @@ public static class Entry
";
#endif
public static void Main(string[] args)
{
#if DEBUG
@@ -82,6 +68,7 @@ public static class Entry
}
Program.Startup(args).Wait();
}

View File

@@ -1,4 +1,5 @@
using DiscordBotCore.Online;
using DiscordBotCore.Interfaces.PluginManager;
using DiscordBotCore.Online;
using DiscordBotCore.Others;
using DiscordBotCore.Others.Actions;
using DiscordBotCore.Others.Logger;
@@ -36,7 +37,7 @@ namespace DiscordBotCore
public SettingsDictionary<string, string> ApplicationEnvironmentVariables { get; private set; }
public InternalActionManager InternalActionManager { get; private set; }
public PluginManager PluginManager { get; private set; }
public IPluginManager PluginManager { get; private set; }
public Logger Logger { get; private set; }
public Bot.App DiscordBotClient { get; internal set; }

View File

@@ -21,7 +21,7 @@ internal class Loader
internal async Task Load()
{
var installedPlugins = await Application.CurrentApplication.PluginManager.GetInstalledPlugins();
var files = installedPlugins.Select(plugin => plugin.FilePath).ToArray();
var files = installedPlugins.Where(plugin=>!plugin.IsDisabled).Select(plugin => plugin.FilePath).ToArray();
foreach (var file in files)
{

View File

@@ -3,13 +3,14 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using DiscordBotCore.Interfaces.PluginManager;
using DiscordBotCore.Others;
using DiscordBotCore.Plugin;
using DiscordBotCore.Updater.Plugins;
namespace DiscordBotCore.Online;
public class PluginManager
public class PluginManager : IPluginManager
{
private static readonly string _DefaultBranch = "releases";
private static readonly string _DefaultBaseUrl = "https://raw.githubusercontent.com/andreitdr/SethPlugins";
@@ -197,7 +198,8 @@ public class PluginManager
float currentProgress = 0f;
IProgress<float> progress = new Progress<float>((p) => {
IProgress<float> progress = new Progress<float>((p) =>
{
installProgress?.Report(currentProgress + stepProgress * p);
});
@@ -228,6 +230,18 @@ public class PluginManager
await AppendPluginToDatabase(pluginInfo);
}
public async Task SetDisabledStatus(string pluginName, bool status)
{
var plugins = await GetInstalledPlugins();
var plugin = plugins.Find(p => p.PluginName == pluginName);
if (plugin == null)
return;
plugin.IsDisabled = status;
await RemovePluginFromDatabase(pluginName);
await AppendPluginToDatabase(plugin);
}
}

View File

@@ -13,9 +13,10 @@ public class PluginInfo
public Dictionary<string, string> ListOfDependancies {get; private set;}
public bool IsMarkedToUninstall {get; internal set;}
public bool IsOfflineAdded { get; internal set; }
public bool IsDisabled { get; internal set; }
[JsonConstructor]
public PluginInfo(string pluginName, PluginVersion pluginVersion, Dictionary<string, string> listOfDependancies, bool isMarkedToUninstall, bool isOfflineAdded)
public PluginInfo(string pluginName, PluginVersion pluginVersion, Dictionary<string, string> listOfDependancies, bool isMarkedToUninstall, bool isOfflineAdded, bool isDisabled)
{
PluginName = pluginName;
PluginVersion = pluginVersion;
@@ -23,6 +24,7 @@ public class PluginInfo
IsMarkedToUninstall = isMarkedToUninstall;
FilePath = $"{Application.CurrentApplication.ApplicationEnvironmentVariables["PluginFolder"]}/{pluginName}.dll";
IsOfflineAdded = isOfflineAdded;
IsDisabled = isDisabled;
}
public PluginInfo(string pluginName, PluginVersion pluginVersion, Dictionary<string, string> listOfDependancies)
@@ -32,6 +34,8 @@ public class PluginInfo
ListOfDependancies = listOfDependancies;
IsMarkedToUninstall = false;
FilePath = $"{Application.CurrentApplication.ApplicationEnvironmentVariables["PluginFolder"]}/{pluginName}.dll";
IsOfflineAdded = false;
IsDisabled = false;
}
public static PluginInfo FromOnlineInfo(PluginOnlineInfo onlineInfo)

View File

@@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DiscordBotUI_Windows
{
internal class Config
{
internal static DiscordBotCore.Others.SettingsDictionary<string, string> ApplicationSettings = new DiscordBotCore.Others.SettingsDictionary<string, string>(DiscordBotCore.Application.GetResourceFullPath("DiscordBotUI/config.json"));
internal static ThemeManager ThemeManager = new ThemeManager();
}
}

View File

@@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<StartupObject></StartupObject>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\DiscordBotCore\DiscordBotCore.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,120 +0,0 @@
using Discord.WebSocket;
using DiscordBotCore.Interfaces;
using DiscordBotCore.Others;
using DiscordBotCore.Others.Actions;
using DiscordBotUI_Windows;
using DiscordBotUI_Windows.WindowsForms;
namespace DiscordBotUI
{
public class DiscordUICommand : ICommandAction
{
public string ActionName => "ui";
public string? Description => "UI Set of actions";
public string? Usage => "ui <option>";
public IEnumerable<InternalActionOption> ListOfOptions => [
new InternalActionOption("start", "Starts the UI")
];
public InternalActionRunType RunType => InternalActionRunType.BOTH;
public async Task Execute(string[]? args)
{
if (args == null || args.Length == 0)
{
Directory.CreateDirectory(Path.Combine(DiscordBotCore.Application.GetResourceFullPath(), "DiscordBotUI"));
await StartUI();
}
if (args[0] == "theme")
{
if (args.Length == 1)
{
Console.WriteLine("Please provide a theme name");
return;
}
if (args[1] == "save")
{
if (args.Length == 2)
{
Console.WriteLine("Please provide a theme name");
return;
}
await Config.ThemeManager.SaveThemeToFile(args[2]);
Console.WriteLine("Theme saved");
}
if (args[1] == "set")
{
if (args.Length == 2)
{
Console.WriteLine("Please provide a theme name");
return;
}
Config.ThemeManager.SetTheme(args[2]);
}
if (args[1] == "list")
{
foreach (var theme in Config.ThemeManager._InstalledThemes)
{
Console.WriteLine(theme.Name);
}
}
return;
}
if (args[0] == "start")
{
await StartUI();
}
}
private async Task StartUI()
{
await Config.ApplicationSettings.LoadFromFile();
await Config.ThemeManager.LoadThemesFromThemesFolder();
if (Config.ApplicationSettings.ContainsKey("AppTheme"))
{
Config.ThemeManager.SetTheme(Config.ApplicationSettings["AppTheme"]);
}
else Config.ApplicationSettings.Add("AppTheme", "Default");
await Config.ApplicationSettings.SaveToFile();
Thread thread = new Thread(() =>
{
MainWindow mainWindow = new MainWindow();
Config.ThemeManager.SetFormTheme(Config.ThemeManager.CurrentTheme, mainWindow);
Application.Run(mainWindow);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
}
public class DiscordEventUI2 : DBEvent
{
public string Name => "DiscordUI";
public bool RequireOtherThread => true;
public string Description => "Discord UI desc";
public async void Start(DiscordSocketClient client)
{
}
}
}

View File

@@ -1,115 +0,0 @@
using DiscordBotUI_Windows.Theming;
namespace DiscordBotUI_Windows
{
internal class ThemeManager
{
private readonly string _ThemesFolder = "DiscordBotUI/Themes";
private readonly Theme _DefaultTheme = new Theme
{
Name = "Default",
Description = "Default theme",
Type = ThemeType.Undefined,
ThemeValues = new Dictionary<string, string>
{
{ "BackgroundColor", "#36393F" },
{ "TextColor", "#000000" }
}
};
internal Theme CurrentTheme { get; private set; }
internal IList<Theme> _InstalledThemes { get; private set; }
internal ThemeManager()
{
_InstalledThemes = new List<Theme>();
CurrentTheme = _DefaultTheme;
}
private void SetControlTheme(Control control, Theme theme, bool doChildToo)
{
control.BackColor = ColorTranslator.FromHtml(theme.ThemeValues["BackgroundColor"]);
control.ForeColor = ColorTranslator.FromHtml(theme.ThemeValues["TextColor"]);
// Fix for data grid view
if (control is DataGridView dataGridView)
{
dataGridView.BackgroundColor = control.BackColor;
dataGridView.DefaultCellStyle.BackColor = control.BackColor;
dataGridView.DefaultCellStyle.ForeColor = control.ForeColor;
dataGridView.DefaultCellStyle.SelectionBackColor = control.BackColor;
dataGridView.DefaultCellStyle.SelectionForeColor = control.ForeColor;
dataGridView.ColumnHeadersDefaultCellStyle.BackColor = control.BackColor;
dataGridView.ColumnHeadersDefaultCellStyle.ForeColor = control.ForeColor;
dataGridView.ColumnHeadersDefaultCellStyle.SelectionBackColor = control.BackColor;
dataGridView.ColumnHeadersDefaultCellStyle.SelectionForeColor = control.ForeColor;
}
if (doChildToo)
{
foreach (Control childControl in control.Controls)
{
SetControlTheme(childControl, theme, true);
}
}
}
internal void SetFormTheme(Theme theme, Form windowsForm)
{
CurrentTheme = theme;
SetControlTheme(windowsForm, theme, true);
Config.ApplicationSettings["AppTheme"] = theme.Name;
}
internal void SetTheme(string themeName)
{
CurrentTheme = _InstalledThemes.FirstOrDefault(x => x.Name == themeName, _DefaultTheme);
Config.ApplicationSettings["AppTheme"] = themeName;
}
private async Task<Theme> LoadThemeFromFile(string fileName)
{
return await DiscordBotCore.Others.JsonManager.ConvertFromJson<Theme>(fileName);
}
internal async Task SaveThemeToFile(string themeName)
{
Theme? theme = _InstalledThemes.FirstOrDefault(x => x.Name == themeName);
if (theme == null)
throw new Exception("Theme not found");
string basefolderPath = DiscordBotCore.Application.GetResourceFullPath(_ThemesFolder);
Directory.CreateDirectory(basefolderPath);
string filePath = Path.Combine(basefolderPath, $"{themeName}.json");
await DiscordBotCore.Others.JsonManager.SaveToJsonFile(filePath, theme);
}
internal async Task<int> LoadThemesFromThemesFolder()
{
string basefolderPath = DiscordBotCore.Application.GetResourceFullPath(_ThemesFolder);
Directory.CreateDirectory(basefolderPath);
var files = Directory.GetFiles(basefolderPath, "*.json");
_InstalledThemes.Clear();
if(files.Length == 0)
{
_InstalledThemes.Add(_DefaultTheme);
return 1;
}
foreach (var file in files)
{
var theme = await LoadThemeFromFile(file);
_InstalledThemes.Add(theme);
}
return _InstalledThemes.Count;
}
}
}

View File

@@ -1,20 +0,0 @@
using System.Text.Json.Serialization;
namespace DiscordBotUI_Windows.Theming
{
internal class Theme
{
public string Name { get; set; }
public string Description { get; set; }
public ThemeType Type { get; set; }
public IDictionary<string, string> ThemeValues { get; set; }
internal void SetThemeValue(string key, string value)
{
if (ThemeValues.ContainsKey(key))
{
ThemeValues[key] = value;
}
}
}
}

View File

@@ -1,9 +0,0 @@
namespace DiscordBotUI_Windows.Theming
{
public enum ThemeType
{
Undefined,
Light,
Dark
}
}

View File

@@ -1,79 +0,0 @@
namespace DiscordBotUI_Windows.WindowsForms
{
partial class MainWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
menuStrip1 = new MenuStrip();
pluginListToolStripMenuItem = new ToolStripMenuItem();
themesToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
// menuStrip1
//
menuStrip1.Items.AddRange(new ToolStripItem[] { pluginListToolStripMenuItem, themesToolStripMenuItem });
menuStrip1.Location = new Point(0, 0);
menuStrip1.Name = "menuStrip1";
menuStrip1.Size = new Size(800, 24);
menuStrip1.TabIndex = 0;
menuStrip1.Text = "menuStrip1";
//
// pluginListToolStripMenuItem
//
pluginListToolStripMenuItem.Name = "pluginListToolStripMenuItem";
pluginListToolStripMenuItem.Size = new Size(74, 20);
pluginListToolStripMenuItem.Text = "Plugin List";
//
// themesToolStripMenuItem
//
themesToolStripMenuItem.Name = "themesToolStripMenuItem";
themesToolStripMenuItem.Size = new Size(60, 20);
themesToolStripMenuItem.Text = "Themes";
//
// MainWindow
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(menuStrip1);
MainMenuStrip = menuStrip1;
Name = "MainWindow";
Text = "MainWindow";
menuStrip1.ResumeLayout(false);
menuStrip1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private MenuStrip menuStrip1;
private ToolStripMenuItem pluginListToolStripMenuItem;
private ToolStripMenuItem themesToolStripMenuItem;
}
}

View File

@@ -1,32 +0,0 @@
namespace DiscordBotUI_Windows.WindowsForms
{
public partial class MainWindow : Form
{
internal MainWindow()
{
InitializeComponent();
Load += (_, _) => MainWindowLoad();
FormClosed += async (_, _) =>
{
await Config.ApplicationSettings.SaveToFile();
};
}
private void MainWindowLoad()
{
pluginListToolStripMenuItem.Click += (_, _) =>
{
var form = new PluginListWindow();
Config.ThemeManager.SetFormTheme(Config.ThemeManager.CurrentTheme, form);
form.Show();
};
themesToolStripMenuItem.Click += (_, _) => {
themesToolStripMenuItem.DropDownItems.Clear();
foreach(var theme in Config.ThemeManager._InstalledThemes)
{
themesToolStripMenuItem.DropDownItems.Add(theme.Name, null, (_, _) => Config.ThemeManager.SetFormTheme(theme, this));
}
};
}
}
}

View File

@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -1,73 +0,0 @@
namespace DiscordBotUI_Windows.WindowsForms
{
partial class PluginListWindow
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
dataGridView1 = new DataGridView();
labelInstalling = new Label();
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
SuspendLayout();
//
// dataGridView1
//
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
dataGridView1.Dock = DockStyle.Top;
dataGridView1.Location = new Point(0, 0);
dataGridView1.Name = "dataGridView1";
dataGridView1.Size = new Size(800, 438);
dataGridView1.TabIndex = 0;
//
// labelInstalling
//
labelInstalling.AutoSize = true;
labelInstalling.Location = new Point(0, 441);
labelInstalling.Name = "labelInstalling";
labelInstalling.Size = new Size(67, 15);
labelInstalling.TabIndex = 1;
labelInstalling.Text = "Installing ...";
//
// PluginListWindow
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 457);
Controls.Add(labelInstalling);
Controls.Add(dataGridView1);
Name = "PluginListWindow";
Text = "PluginListWindow";
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private DataGridView dataGridView1;
private Label labelInstalling;
}
}

View File

@@ -1,88 +0,0 @@
using DiscordBotCore.Loaders;
using DiscordBotCore.Online;
namespace DiscordBotUI_Windows.WindowsForms
{
public partial class PluginListWindow : Form
{
public PluginListWindow()
{
InitializeComponent();
Load += async (_,_) => await PluginListWindowLoad();
}
private async Task PluginListWindowLoad()
{
labelInstalling.Visible = false;
var listOfPlugins = await DiscordBotCore.Application.CurrentApplication.PluginManager.GetPluginsList();
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
dataGridView1.Columns.Add("Name", "Name");
dataGridView1.Columns.Add("Description", "Description");
dataGridView1.Columns.Add("Dependencies", "Has Dependencies");
dataGridView1.Columns.Add("Version", "Version");
dataGridView1.Columns.Add("IsInstalled", "IsInstalled");
dataGridView1.Columns.Add("Install", "Install");
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
foreach(var plugin in listOfPlugins)
{
bool isInstalled = await DiscordBotCore.Application.CurrentApplication.PluginManager.IsPluginInstalled(plugin.Name);
string isInstalledMessage = isInstalled ? "Installed" : "Not Installed";
int rowIndex = dataGridView1.Rows.Add(plugin.Name, plugin.Description, plugin.HasFileDependencies, plugin.Version, isInstalledMessage);
dataGridView1.Rows[rowIndex].Cells["Install"] = new DataGridViewButtonCell()
{
Value = isInstalled ? "Remove" : "Install",
Style = { BackColor = isInstalled ? System.Drawing.Color.LightGray : default }
};
}
dataGridView1.ReadOnly = true;
dataGridView1.CellContentClick += async (sender, e) =>
{
var senderGrid = (DataGridView)sender;
if (e.ColumnIndex == 5 && e.RowIndex >= 0)
{
var pluginName = (string)senderGrid.Rows[e.RowIndex].Cells["Name"].Value;
var isInstalled = (string)senderGrid.Rows[e.RowIndex].Cells["Install"].Value == "Remove";
if (isInstalled)
{
await DiscordBotCore.Application.CurrentApplication.PluginManager.MarkPluginToUninstall(pluginName);
dataGridView1.Rows[e.RowIndex].Cells["Install"] = new DataGridViewButtonCell()
{
Value = "Install",
Style = { BackColor = default }
};
}
else
{
labelInstalling.Visible = true;
labelInstalling.Text = "Installing " + pluginName;
var result = await DiscordBotCore.Application.CurrentApplication.PluginManager.GetPluginDataByName(pluginName);
await DiscordBotCore.Application.CurrentApplication.PluginManager.InstallPlugin(result!, null);
labelInstalling.Visible = false;
dataGridView1.Rows[e.RowIndex].Cells["Install"] = new DataGridViewButtonCell()
{
Value = "Remove",
Style = { BackColor = System.Drawing.Color.LightGray }
};
}
}
dataGridView1.Refresh();
dataGridView1.Update();
};
}
}
}

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -6,8 +6,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBot", "DiscordBot\Di
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBotCore", "DiscordBotCore\DiscordBotCore.csproj", "{5A99BFC3-EB39-4AEF-8D61-3CE22D013B02}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBotUI_Windows", "DiscordBotUI\DiscordBotUI_Windows.csproj", "{95AD2D0C-D1EB-47B9-8DB4-F11CBAF15704}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -22,16 +20,10 @@ Global
{5A99BFC3-EB39-4AEF-8D61-3CE22D013B02}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A99BFC3-EB39-4AEF-8D61-3CE22D013B02}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A99BFC3-EB39-4AEF-8D61-3CE22D013B02}.Release|Any CPU.Build.0 = Release|Any CPU
{95AD2D0C-D1EB-47B9-8DB4-F11CBAF15704}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95AD2D0C-D1EB-47B9-8DB4-F11CBAF15704}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95AD2D0C-D1EB-47B9-8DB4-F11CBAF15704}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95AD2D0C-D1EB-47B9-8DB4-F11CBAF15704}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3FB3C5DE-ED21-4D2E-ABDD-3A00EE4A2FFF}
EndGlobalSection