diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..cd967fc --- /dev/null +++ b/.dockerignore @@ -0,0 +1,25 @@ +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/.idea +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md \ No newline at end of file diff --git a/.gitignore b/.gitignore index e63ac4f..b4d0336 100644 --- a/.gitignore +++ b/.gitignore @@ -453,4 +453,5 @@ $RECYCLE.BIN/ !.vscode/launch.json !.vscode/extensions.json -/DiscordBotWebUI/Data \ No newline at end of file +/DiscordBotWebUI/Data +/DiscordBot/Data \ No newline at end of file diff --git a/DiscordBot/DiscordBot.csproj b/DiscordBot/DiscordBot.csproj index 05d2631..f4f4341 100644 --- a/DiscordBot/DiscordBot.csproj +++ b/DiscordBot/DiscordBot.csproj @@ -11,6 +11,7 @@ False 1.0.4.0 false + Linux full @@ -42,4 +43,9 @@ + + + .dockerignore + + \ No newline at end of file diff --git a/DiscordBot/Dockerfile b/DiscordBot/Dockerfile new file mode 100644 index 0000000..179b370 --- /dev/null +++ b/DiscordBot/Dockerfile @@ -0,0 +1,24 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 5055 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["DiscordBot/DiscordBot.csproj", "DiscordBot/"] +COPY ["DiscordBotCore/DiscordBotCore.csproj", "DiscordBotCore/"] +RUN dotnet restore "DiscordBot/DiscordBot.csproj" +COPY . . +WORKDIR "/src/DiscordBot" +RUN dotnet build "DiscordBot.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "DiscordBot.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +EXPOSE 5055 +ENTRYPOINT ["dotnet", "DiscordBot.dll"] diff --git a/DiscordBot/Program.cs b/DiscordBot/Program.cs index a3fc606..9f4edda 100644 --- a/DiscordBot/Program.cs +++ b/DiscordBot/Program.cs @@ -24,6 +24,7 @@ public class Program await LoadComponents(args); await PrepareConsole(); await PluginMethods.RefreshPlugins(false); + await ConsoleInputHandler(); } @@ -55,7 +56,6 @@ public class Program AnsiConsole.MarkupLine("[yellow]Git SethBot: https://github.com/andreitdr/SethDiscordBot [/]"); AnsiConsole.MarkupLine("[yellow]Remember to close the bot using the shutdown command ([/][red]exit[/][yellow]) or some settings won't be saved[/]"); - AnsiConsole.MarkupLine($"[yellow]Running on [/][magenta]{(OperatingSystem.IsWindows() ? "Windows" : "Linux")}[/]"); AnsiConsole.MarkupLine("[yellow]===== Seth Discord Bot =====[/]"); @@ -118,7 +118,9 @@ public class Program if (!Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("ServerID") || !Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("token") || !Application.CurrentApplication.ApplicationEnvironmentVariables.ContainsKey("prefix")) + { await Installer.GenerateStartupConfig(); + } if (args.Length > 0) { @@ -127,7 +129,7 @@ public class Program if(args.Contains("--socket-api")) Application.InitializeThreadedSockets(); } - + } diff --git a/DiscordBotCore/Application.cs b/DiscordBotCore/Application.cs index 470826e..78307c0 100644 --- a/DiscordBotCore/Application.cs +++ b/DiscordBotCore/Application.cs @@ -57,7 +57,7 @@ namespace DiscordBotCore { if (!await OnlineFunctions.IsInternetConnected()) { - Console.WriteLine("No internet connection detected. Exiting ..."); + Console.WriteLine("The main repository server is not reachable. Please check your internet connection."); Environment.Exit(0); } @@ -95,6 +95,24 @@ namespace DiscordBotCore CurrentApplication.InternalActionManager = new InternalActionManager(); await CurrentApplication.InternalActionManager.Initialize(); + if (OperatingSystem.IsWindows()) + { + CurrentApplication.ApplicationEnvironmentVariables.Add("console.terminal", "cmd"); + CurrentApplication.ApplicationEnvironmentVariables.Add("console.cmd_prefix", "/c "); + } + + if(OperatingSystem.IsLinux()) + { + CurrentApplication.ApplicationEnvironmentVariables.Add("console.terminal", "bash"); + CurrentApplication.ApplicationEnvironmentVariables.Add("console.cmd_prefix", string.Empty); + } + + if(OperatingSystem.IsMacOS()) + { + CurrentApplication.ApplicationEnvironmentVariables.Add("console.terminal", "sh"); + CurrentApplication.ApplicationEnvironmentVariables.Add("console.cmd_prefix", string.Empty); + } + IsRunning = true; } @@ -146,5 +164,10 @@ namespace DiscordBotCore var result = Path.Combine(_PluginsFolder, path); return result; } + + public static void Log(string message, LogType? logType = LogType.Info) + { + CurrentApplication.Logger.Log(message, logType); + } } } diff --git a/DiscordBotCore/Online/Helpers/OnlineFunctions.cs b/DiscordBotCore/Online/Helpers/OnlineFunctions.cs index 02868d9..820ca80 100644 --- a/DiscordBotCore/Online/Helpers/OnlineFunctions.cs +++ b/DiscordBotCore/Online/Helpers/OnlineFunctions.cs @@ -114,7 +114,7 @@ internal static class OnlineFunctions try { using var client = new HttpClient(); - await client.GetStringAsync("https://www.google.com"); + await client.GetStringAsync("files.wizzy-server.ro"); result = true; } catch diff --git a/DiscordBotCore/Online/PluginManager.cs b/DiscordBotCore/Online/PluginManager.cs index 324fef6..db1e93c 100644 --- a/DiscordBotCore/Online/PluginManager.cs +++ b/DiscordBotCore/Online/PluginManager.cs @@ -13,8 +13,9 @@ namespace DiscordBotCore.Online; public sealed class PluginManager { + private static readonly string _LibrariesBaseFolder = "Libraries"; private readonly PluginRepository _PluginRepository; - internal InstallingPluginInformation InstallingPluginInformation { get; private set; } + internal InstallingPluginInformation? InstallingPluginInformation { get; private set; } public PluginManager(PluginRepository pluginRepository) { @@ -41,8 +42,7 @@ public sealed class PluginManager { return null; } - - // try to get the best matching plugin using the pluginName as a search query + PluginOnlineInfo? result = plugins.Find(pl => pl.Name.Contains(pluginName, StringComparison.CurrentCultureIgnoreCase)); if (result is null) { @@ -62,9 +62,20 @@ public sealed class PluginManager public async Task ExecutePluginInstallScripts(List listOfDependencies) { - string consoleType = OperatingSystem.IsWindows() ? "cmd.exe" : "bash"; + string? console = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("console.terminal"); + if (string.IsNullOrEmpty(console)) + { + return; + } + + string? cmd_prefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("console.cmd_prefix"); + if (string.IsNullOrEmpty(cmd_prefix)) + { + return; + } + foreach (var script in listOfDependencies) - await ServerCom.RunConsoleCommand(consoleType, "/c " + script.ScriptContent); + await ServerCom.RunConsoleCommand(console, $"{cmd_prefix}{script.ScriptContent}"); } public async Task AppendPluginToDatabase(PluginInfo pluginData) @@ -147,8 +158,8 @@ public sealed class PluginManager await RemovePluginFromDatabase(pluginInfo.PluginName); - if (Directory.Exists($"Libraries/{pluginInfo.PluginName}")) - Directory.Delete($"Libraries/{pluginInfo.PluginName}", true); + if (Directory.Exists($"{_LibrariesBaseFolder}/{pluginInfo.PluginName}")) + Directory.Delete($"{_LibrariesBaseFolder}/{pluginInfo.PluginName}", true); } public async Task GetDependencyLocation(string dependencyName) @@ -186,7 +197,7 @@ public sealed class PluginManager public string GenerateDependencyRelativePath(string pluginName, string dependencyPath) { - string relative = $"./Libraries/{pluginName}/{dependencyPath}"; + string relative = $"./{_LibrariesBaseFolder}/{pluginName}/{dependencyPath}"; return relative; } @@ -242,11 +253,19 @@ public sealed class PluginManager { foreach (var scriptDependency in pluginData.ScriptDependencies) { - string console = OperatingSystem.IsWindows() ? "start cmd.exe" : "bash"; - string arguments = OperatingSystem.IsWindows() - ? $"/c {scriptDependency.ScriptContent}" - : scriptDependency.ScriptContent; + string? console = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("console.terminal"); + if (string.IsNullOrEmpty(console)) + { + return; + } + + string? cmdPrefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("console.cmd_prefix"); + if (string.IsNullOrEmpty(cmdPrefix)) + { + return; + } + string arguments = $"{cmdPrefix}{scriptDependency.ScriptContent}"; await ServerCom.RunConsoleCommand(console, arguments); } } @@ -288,14 +307,27 @@ public sealed class PluginManager } if (pluginData.HasScriptDependencies) + { foreach (var scriptDependency in pluginData.ScriptDependencies) { + string? console = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("console.terminal"); + if (string.IsNullOrEmpty(console)) + { + return; + } + + string? cmdPrefix = Application.CurrentApplication.ApplicationEnvironmentVariables.Get("console.cmd_prefix"); + if (string.IsNullOrEmpty(cmdPrefix)) + { + return; + } - string console = OperatingSystem.IsWindows() ? "start cmd.exe" : "bash"; - string arguments = OperatingSystem.IsWindows() ? $"/c {scriptDependency.ScriptContent}" : scriptDependency.ScriptContent; + string arguments = $"{cmdPrefix}{scriptDependency.ScriptContent}"; await ServerCom.RunConsoleCommand(console, arguments); } + + } PluginInfo pluginInfo = PluginInfo.FromOnlineInfo(pluginData); diff --git a/DiscordBotCore/Repository/PluginRepository.cs b/DiscordBotCore/Repository/PluginRepository.cs index 356c8e6..c7a9f1e 100644 --- a/DiscordBotCore/Repository/PluginRepository.cs +++ b/DiscordBotCore/Repository/PluginRepository.cs @@ -6,7 +6,7 @@ namespace DiscordBotCore.Repository; public sealed class PluginRepository : RepositoryBase { - public static readonly PluginRepository Default = new PluginRepository("Testing", "https://wizzy-server.ro/SethDiscordBot/PluginsRepo", "PluginsList.json"); + public static readonly PluginRepository Default = new PluginRepository("Testing", "https://files.wizzy-server.ro/SethDiscordBot/PluginsRepo", "PluginsList.json"); private PluginRepository(string repositoryName, string repositoryUrl, string databaseFile) : base(repositoryName, repositoryUrl, databaseFile) { diff --git a/DiscordBotWebUI/DiscordBotWebUI.csproj b/DiscordBotWebUI/DiscordBotWebUI.csproj index af46a9e..55babe1 100644 --- a/DiscordBotWebUI/DiscordBotWebUI.csproj +++ b/DiscordBotWebUI/DiscordBotWebUI.csproj @@ -21,6 +21,9 @@ + + .dockerignore + diff --git a/DiscordBotWebUI/Dockerfile b/DiscordBotWebUI/Dockerfile new file mode 100644 index 0000000..ca692ad --- /dev/null +++ b/DiscordBotWebUI/Dockerfile @@ -0,0 +1,23 @@ +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER $APP_UID +WORKDIR /app +EXPOSE 8080 +EXPOSE 8081 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["DiscordBotWebUI/DiscordBotWebUI.csproj", "DiscordBotWebUI/"] +RUN dotnet restore "DiscordBotWebUI/DiscordBotWebUI.csproj" +COPY . . +WORKDIR "/src/DiscordBotWebUI" +RUN dotnet build "DiscordBotWebUI.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "DiscordBotWebUI.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "DiscordBotWebUI.dll"] diff --git a/DiscordBotWebUI/Program.cs b/DiscordBotWebUI/Program.cs index 5d7c2ea..f2e55e1 100644 --- a/DiscordBotWebUI/Program.cs +++ b/DiscordBotWebUI/Program.cs @@ -13,7 +13,7 @@ string logo = \___ \ / _ \ __| '_ \ | | | | / __|/ __/ _ \| '__/ _` | | _ < / _ \| __| ____) | __/ |_| | | | | |__| | \__ \ (_| (_) | | | (_| | | |_) | (_) | |_ |_____/ \___|\__|_| |_| |_____/|_|___/\___\___/|_| \__,_| |____/ \___/ \__| - (WEB Edition) + (Official Web UI) "; diff --git a/docker-compose.yml b/docker-compose.yml index 637364b..b5a85d5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,22 @@ services: - discordbotwebui: + discord-bot-client: + build: + context: . + dockerfile: DiscordBot/Dockerfile + tty: true + stdin_open: true + + discord-bot-webui: build: context: . dockerfile: DiscordBotWebUI/Dockerfile + + +networks: + custom_bridge: + driver: bridge + ipam: + driver: default + config: + - subnet: "172.20.100.0/24" + gateway: "172.20.100.1" \ No newline at end of file