diff --git a/DiscordBot/Entry.cs b/DiscordBot/Entry.cs index ebba9ca..2a2e6bc 100644 --- a/DiscordBot/Entry.cs +++ b/DiscordBot/Entry.cs @@ -6,7 +6,6 @@ using System.Reflection; namespace DiscordBot; - public static class Entry { /// @@ -46,7 +45,7 @@ public static class Entry \___ \ / _ \ __| '_ \ | | | | / __|/ __/ _ \| '__/ _` | | _ < / _ \| __| ____) | __/ |_| | | | | |__| | \__ \ (_| (_) | | | (_| | | |_) | (_) | |_ |_____/ \___|\__|_| |_| |_____/|_|___/\___\___/|_| \__,_| |____/ \___/ \__| - + (Console Application) "; public static void Main(string[] args) diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index db3cefd..6162846 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -65,7 +65,7 @@ public class Program var token = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("token"); var prefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("prefix"); - DiscordBotApplication discordApp = new (token, prefix); + var discordApp = new DiscordBotApplication(token, prefix); await discordApp.StartAsync(); } catch (Exception ex) diff --git a/DiscordBotCore/Database/SqlDatabase.cs b/DiscordBotCore/Database/SqlDatabase.cs index 3548560..84226ce 100644 --- a/DiscordBotCore/Database/SqlDatabase.cs +++ b/DiscordBotCore/Database/SqlDatabase.cs @@ -12,7 +12,7 @@ public class SqlDatabase private readonly SQLiteConnection _Connection; /// - /// Initialize a SQL connection by specifing its private path + /// Initialize a SQL connection by specifying its private path /// /// The path to the database (it is starting from ./Data/Resources/) public SqlDatabase(string fileName) @@ -483,8 +483,7 @@ public class SqlDatabase return null; } - - + /// /// Read data from the result table and return the first row /// @@ -542,7 +541,7 @@ public class SqlDatabase /// The name of the parameter /// The value of the parameter /// The SQLiteParameter that has the name, value and DBType set according to your inputs - private SQLiteParameter? CreateParameter(string name, object value) + private static SQLiteParameter? CreateParameter(string name, object value) { var parameter = new SQLiteParameter(name); parameter.Value = value; @@ -599,7 +598,7 @@ public class SqlDatabase /// /// The parameter raw inputs. The Key is name and the Value is the value of the parameter /// The SQLiteParameter that has the name, value and DBType set according to your inputs - private SQLiteParameter? CreateParameter(KeyValuePair parameterValues) + private static SQLiteParameter? CreateParameter(KeyValuePair parameterValues) { return CreateParameter(parameterValues.Key, parameterValues.Value); } diff --git a/DiscordBotWebUI/Components/App.razor b/DiscordBotWebUI/Components/App.razor index 1fe267c..ba4128a 100644 --- a/DiscordBotWebUI/Components/App.razor +++ b/DiscordBotWebUI/Components/App.razor @@ -9,7 +9,7 @@ - + diff --git a/DiscordBotWebUI/Components/Items/Setup/FinishSetupComponent.razor b/DiscordBotWebUI/Components/Items/Setup/FinishSetupComponent.razor new file mode 100644 index 0000000..ac651d2 --- /dev/null +++ b/DiscordBotWebUI/Components/Items/Setup/FinishSetupComponent.razor @@ -0,0 +1,8 @@ +@code { +[Parameter] public Action CompleteSetup { get; set; } +} + +Final Setup +

Your bot is almost ready! Click 'Finish' to complete the setup.

+ + diff --git a/DiscordBotWebUI/Components/Items/Setup/ModuleSetup.razor b/DiscordBotWebUI/Components/Items/Setup/ModuleSetup.razor deleted file mode 100644 index 0abc6c5..0000000 --- a/DiscordBotWebUI/Components/Items/Setup/ModuleSetup.razor +++ /dev/null @@ -1,16 +0,0 @@ -@using DiscordBotWebUI.Types - - - -@code { - private List Items = new List(); - - protected override void OnInitialized() - { - base.OnInitialized(); - - Items.Clear(); - - // Load items - } -} \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Items/Setup/ModuleSetupComponent.razor b/DiscordBotWebUI/Components/Items/Setup/ModuleSetupComponent.razor new file mode 100644 index 0000000..e984297 --- /dev/null +++ b/DiscordBotWebUI/Components/Items/Setup/ModuleSetupComponent.razor @@ -0,0 +1,48 @@ +@using DiscordBotCore +@using DiscordBotCore.Modules +@using DiscordBotCore.Others.Exceptions +@using DiscordBotWebUI.Types +@code { +[Parameter] public Action NextStep { get; set; } +[Parameter] public ModuleRequirement ModuleRequirementReference { get; set; } + +private List MarketItems = new List(); + +protected override async Task OnInitializedAsync() +{ + await base.OnInitializedAsync(); + + foreach(var requirement in ModuleRequirementReference.RequiredModulesWithTypes) + { + var modulesWithType = await Application.CurrentApplication.ModuleManager.ServerGetAllModules(requirement); + AppendToList(modulesWithType); + } + + foreach (var moduleName in ModuleRequirementReference.RequiredModulesWithNames) + { + var module = await Application.CurrentApplication.ModuleManager.ServerGetModuleWithName(moduleName); + MarketItem item = new MarketItem(module.ModuleName, module.ModuleAuthor, module.ModuleDescription, ItemType.Module); + MarketItems.Add(item); + } +} + +private void AppendToList(List listOfModules) +{ + foreach (var module in listOfModules) + { + MarketItem item = new MarketItem(module.ModuleName, module.ModuleAuthor, module.ModuleDescription, ItemType.Module); + MarketItems.Add(item); + } +} + +} + +Download Dependencies +

The bot needs to download certain files to function properly.

+ +@if (MarketItems.Any()) +{ + +} + + \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Items/Setup/StartupConfigurationComponent.razor b/DiscordBotWebUI/Components/Items/Setup/StartupConfigurationComponent.razor new file mode 100644 index 0000000..6becf1b --- /dev/null +++ b/DiscordBotWebUI/Components/Items/Setup/StartupConfigurationComponent.razor @@ -0,0 +1,60 @@ +@using DiscordBotCore +@code { + [Parameter] public Action NextStep { get; set; } + private string BotToken { get; set; } + private string BotPrefix { get; set; } + private List BotServers { get; set; } + + private string BotServersString { get; set; } + + private async void DoNextStep() + { + if(string.IsNullOrEmpty(BotToken) || string.IsNullOrEmpty(BotPrefix) || string.IsNullOrEmpty(BotServersString)) + { + return; + } + + if(BotServersString.Contains(",")) + { + BotServersString = BotServersString.Replace(",", ";"); + } + + var stringList = BotServersString.Split(';'); + BotServers = new List(); + foreach(var serverId in stringList) + { + if(ulong.TryParse(serverId, out ulong id)) + { + BotServers.Add(id); + } + } + + if (!BotServers.Any()) + { + return; + } + + + Application.CurrentApplication.ApplicationEnvironmentVariables.Add("token", BotToken); + Application.CurrentApplication.ApplicationEnvironmentVariables.Add("prefix", BotPrefix); + Application.CurrentApplication.ApplicationEnvironmentVariables.Add("ServerID", BotServers); + + await Application.CurrentApplication.ApplicationEnvironmentVariables.SaveToFile(); + + NextStep.Invoke(); + } +} + +Basic Configuration +

Please provide some basic settings to get started.

+ + + + + + + + + + + diff --git a/DiscordBotWebUI/Components/Items/Setup/WelcomeComponent.razor b/DiscordBotWebUI/Components/Items/Setup/WelcomeComponent.razor index 7c57860..861139f 100644 --- a/DiscordBotWebUI/Components/Items/Setup/WelcomeComponent.razor +++ b/DiscordBotWebUI/Components/Items/Setup/WelcomeComponent.razor @@ -1,17 +1,7 @@ -
- - - - -
+@code { + [Parameter] public Action NextStep { get; set; } +} -@code { - - private static readonly string _Title = "Welcome to Seth Discord Bot setup page"; - - private static readonly string _Text = -@" -Seth Discord Bot is a small yet powerful Discord Bot that allows you to integrate custom commands and events into your Discord server. -But let's start with the configuration first. Please click the arrow to the right to begin ... -"; -} \ No newline at end of file +Welcome to the Bot Setup Wizard +

This setup wizard will guide you through the process of configuring your bot and downloading the necessary dependencies.

+ diff --git a/DiscordBotWebUI/Components/Pages/Home.razor b/DiscordBotWebUI/Components/Pages/Home.razor deleted file mode 100644 index 137cdf5..0000000 --- a/DiscordBotWebUI/Components/Pages/Home.razor +++ /dev/null @@ -1,72 +0,0 @@ -@page "/" - -@using DiscordBotCore.Others.Exceptions -@using DiscordBotWebUI.Components.Pages.Setup -@using DiscordBotWebUI.DiscordBot - -@inject DialogService DialogService - - - - - -@code { - private string? _TextValue; - - private DiscordBotStartup _DiscordBotStartup = null!; - - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - // Only run after the first render - if(!firstRender) - { - return; - } - - - _DiscordBotStartup = new DiscordBotStartup {RequirementsSolver = FixModules}; - await _DiscordBotStartup.CreateApplication(); - } - - private async Task FixModules(ModuleRequirement requirements) - { - if(!requirements.RequireAny) - { - return; - } - - await DialogService.OpenAsync("Some required modules are not installed. Please install before using the bot ...", new Dictionary() - { - {"Requirements", requirements} - }, new DialogOptions() { Width = "75%", Height = "75%" }); - } - - private async void Initialize() - { - _DiscordBotStartup.Log = async (str, type) => { - _TextValue += $"[{type}] {str} \n"; - await InvokeAsync(StateHasChanged); - - Console.WriteLine(str); - }; - - if (_DiscordBotStartup.LoadComponents()) - { - await _DiscordBotStartup.PrepareBot(); - await _DiscordBotStartup.RefreshPlugins(false); - - return; - } - - while (await DialogService.OpenAsync("Please complete this setup before starting the bot") == false) - { - Console.WriteLine("Failed to complete the setup. Invalid data acquired ..."); - } - - - - await _DiscordBotStartup.PrepareBot(); - await _DiscordBotStartup.RefreshPlugins(false); - } -} \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Pages/Setup/InstallRequiredModules.razor b/DiscordBotWebUI/Components/Pages/Setup/InstallRequiredModules.razor deleted file mode 100644 index feb5a8c..0000000 --- a/DiscordBotWebUI/Components/Pages/Setup/InstallRequiredModules.razor +++ /dev/null @@ -1,45 +0,0 @@ -@using DiscordBotCore -@using DiscordBotCore.Modules -@using DiscordBotCore.Others.Exceptions -@using DiscordBotWebUI.Components.Items -@using DiscordBotWebUI.Types - -@if(MarketItems.Count > 0) -{ - -} - -@code { - [Parameter] - public ModuleRequirement Requirements { get; set; } - private List MarketItems = new List(); - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - - foreach(var requirement in Requirements.RequiredModulesWithTypes) - { - var modulesWithType = await Application.CurrentApplication.ModuleManager.ServerGetAllModules(requirement); - AppendToList(modulesWithType); - } - - foreach (var moduleName in Requirements.RequiredModulesWithNames) - { - var module = await Application.CurrentApplication.ModuleManager.ServerGetModuleWithName(moduleName); - MarketItem item = new MarketItem(module.ModuleName, module.ModuleAuthor, module.ModuleDescription, ItemType.Module); - MarketItems.Add(item); - } - } - - private void AppendToList(List listOfModules) - { - foreach (var module in listOfModules) - { - MarketItem item = new MarketItem(module.ModuleName, module.ModuleAuthor, module.ModuleDescription, ItemType.Module); - MarketItems.Add(item); - } - } - - -} \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Pages/Setup/SetupWizard.razor b/DiscordBotWebUI/Components/Pages/Setup/SetupWizard.razor new file mode 100644 index 0000000..488fc02 --- /dev/null +++ b/DiscordBotWebUI/Components/Pages/Setup/SetupWizard.razor @@ -0,0 +1,51 @@ +@page "/setup-wizard" +@inject DialogService DialogService + +@using DiscordBotCore +@using DiscordBotCore.Others.Exceptions +@using DiscordBotWebUI.Components.Items.Setup + + + + + + + + + +
+ @if (currentStep == 0) + { + + } + else if (currentStep == 1) + { + + } + else if (currentStep == 2) + { + + } + else if (currentStep == 3) + { + + } +
+
+ +@code { + [Parameter] public ModuleRequirement RequirementsToDownload { get; set; } + + private int currentStep = 0; + + private void NextStep() + { + currentStep++; + StateHasChanged(); + } + + private void FinishSetup() + { + DialogService.Close(true); + } +} \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Pages/Setup/Welcome.razor b/DiscordBotWebUI/Components/Pages/Setup/Welcome.razor deleted file mode 100644 index d40ccea..0000000 --- a/DiscordBotWebUI/Components/Pages/Setup/Welcome.razor +++ /dev/null @@ -1,19 +0,0 @@ -@page "/welcome" -@using DiscordBotWebUI.Components.Items.Setup -@inject NavigationManager Navigation - - - - - -@code { - // Method to navigate to a new page - private void GoToNextPage() - { - Navigation.NavigateTo("/settings"); - } -} \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Pages/Error.razor b/DiscordBotWebUI/Components/Pages/SidebarPages/Error.razor similarity index 100% rename from DiscordBotWebUI/Components/Pages/Error.razor rename to DiscordBotWebUI/Components/Pages/SidebarPages/Error.razor diff --git a/DiscordBotWebUI/Components/Pages/SidebarPages/Home.razor b/DiscordBotWebUI/Components/Pages/SidebarPages/Home.razor new file mode 100644 index 0000000..7f15b84 --- /dev/null +++ b/DiscordBotWebUI/Components/Pages/SidebarPages/Home.razor @@ -0,0 +1,64 @@ +@page "/" + +@using DiscordBotCore.Others +@using DiscordBotCore.Others.Exceptions +@using DiscordBotWebUI.Components.Pages.Setup +@using DiscordBotWebUI.DiscordBot + +@inject DialogService DialogService + + + + + +@code { + private string? _TextValue; + + private async Task Solver(ModuleRequirement moduleRequirement) + { + while (await DialogService.OpenAsync("Setup Wizard", new Dictionary {{"RequirementsToDownload", moduleRequirement}}) != true) + { + Console.WriteLine("Failed to complete the setup. Invalid data acquired ..."); + } + } + + private async Task Initialize() + { + Action logging = async (str, type) => { + _TextValue += $"[{type}] {str} \n"; + await InvokeAsync(StateHasChanged); + }; + + var discordApplication = new DiscordApplication(logging, Solver); + await discordApplication.Start(); + } + + // private async void Initialize() + // { + // _DiscordBotStartup = new DiscordBotStartup { RequirementsSolver = default! }; + // await _DiscordBotStartup.CreateApplication(); + // + // _DiscordBotStartup.Log = async (str, type) => { + // _TextValue += $"[{type}] {str} \n"; + // await InvokeAsync(StateHasChanged); + // + // Console.WriteLine(str); + // }; + // + // if (_DiscordBotStartup.LoadComponents()) + // { + // await _DiscordBotStartup.PrepareBot(); + // await _DiscordBotStartup.RefreshPlugins(false); + // + // return; + // } + // + // while (await DialogService.OpenAsync("Please complete this setup before starting the bot") == false) + // { + // Console.WriteLine("Failed to complete the setup. Invalid data acquired ..."); + // } + // + // await _DiscordBotStartup.PrepareBot(); + // await _DiscordBotStartup.RefreshPlugins(false); + // } +} \ No newline at end of file diff --git a/DiscordBotWebUI/Components/Pages/ModulesMarket.razor b/DiscordBotWebUI/Components/Pages/SidebarPages/ModulesMarket.razor similarity index 100% rename from DiscordBotWebUI/Components/Pages/ModulesMarket.razor rename to DiscordBotWebUI/Components/Pages/SidebarPages/ModulesMarket.razor diff --git a/DiscordBotWebUI/Components/Pages/PluginsMarket.razor b/DiscordBotWebUI/Components/Pages/SidebarPages/PluginsMarket.razor similarity index 100% rename from DiscordBotWebUI/Components/Pages/PluginsMarket.razor rename to DiscordBotWebUI/Components/Pages/SidebarPages/PluginsMarket.razor diff --git a/DiscordBotWebUI/Components/Pages/Settings.razor b/DiscordBotWebUI/Components/Pages/SidebarPages/Settings.razor similarity index 100% rename from DiscordBotWebUI/Components/Pages/Settings.razor rename to DiscordBotWebUI/Components/Pages/SidebarPages/Settings.razor diff --git a/DiscordBotWebUI/DiscordBot/DiscordBotStartup.cs b/DiscordBotWebUI/DiscordBot/DiscordApplication.cs similarity index 69% rename from DiscordBotWebUI/DiscordBot/DiscordBotStartup.cs rename to DiscordBotWebUI/DiscordBot/DiscordApplication.cs index 7d80770..4a92606 100644 --- a/DiscordBotWebUI/DiscordBot/DiscordBotStartup.cs +++ b/DiscordBotWebUI/DiscordBot/DiscordApplication.cs @@ -6,26 +6,24 @@ using DiscordBotCore.Others.Exceptions; namespace DiscordBotWebUI.DiscordBot; -public class DiscordBotStartup +public class DiscordApplication { - public required Func RequirementsSolver { get; set; } + public bool IsRunning { get; private set; } + private Action LogWriter { get; set; } + private Func RequirementsSolver { get; set; } - internal delegate void LogEventHandler(string message, LogType type); - internal LogEventHandler Log; - - private void WriteLog(string message, LogType logType) + public DiscordApplication(Action logWriter, Func requirementsSolver) { - Log?.Invoke(message, logType); + this.LogWriter = logWriter; + this.RequirementsSolver = requirementsSolver; + IsRunning = false; + } - public async Task CreateApplication() + private async Task LoadComponents() { - await Application.CreateApplication(RequirementsSolver); - } - - public bool LoadComponents() - { - Application.Logger.SetOutFunction(WriteLog); + await Application.CreateApplication(RequirementsSolver); // This is a placeholder for the RequirementsSolver delegate + Application.Logger.SetOutFunction(LogWriter); return Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("ServerID") && Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("token") && @@ -33,13 +31,23 @@ public class DiscordBotStartup } - public async Task PrepareBot() + public async Task Start() { + + if (!await LoadComponents()) + { + return; + } + var token = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("token"); var prefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("prefix"); - DiscordBotApplication app = new DiscordBotApplication(token, prefix); - await app.StartAsync(); + var coreApplication = new DiscordBotApplication(token, prefix); + await coreApplication.StartAsync(); + + await RefreshPlugins(false); + + IsRunning = true; } public async Task RefreshPlugins(bool quiet) @@ -47,7 +55,7 @@ public class DiscordBotStartup await LoadPlugins(quiet ? ["-q"] : null); await InitializeInternalActionManager(); } - + private async Task LoadPlugins(string[]? args) { var loader = new PluginLoader(Application.CurrentApplication.DiscordBotClient.Client); @@ -74,10 +82,9 @@ public class DiscordBotStartup await loader.LoadPlugins(); } - + private async Task InitializeInternalActionManager() { await Application.CurrentApplication.InternalActionManager.Initialize(); } - }