فهرست منبع

Merge branch 'main' into PleskIntegration

Marcel Baumgartner 2 سال پیش
والد
کامیت
74fa8af744

+ 13 - 0
Moonlight/App/Helpers/DiscordMaintenanceToggle.cs

@@ -0,0 +1,13 @@
+using Discord.WebSocket;
+using Moonlight.App.Services.DiscordBot;
+
+namespace Moonlight.App.Helpers;
+
+public class DiscordMaintenanceToggle
+{
+    private Task MaintenanceModeToggle(SocketSlashCommand command)
+    {
+        DiscordBotService.MaintenanceMode = !DiscordBotService.MaintenanceMode;
+        return Task.CompletedTask;
+    }
+}

+ 44 - 0
Moonlight/App/Repositories/LoadingMessageRepository.cs

@@ -0,0 +1,44 @@
+using Microsoft.EntityFrameworkCore;
+using Moonlight.App.Database;
+using Moonlight.App.Database.Entities;
+
+namespace Moonlight.App.Repositories;
+
+public class LoadingMessageRepository : IDisposable
+{
+    private readonly DataContext DataContext;
+
+    public LoadingMessageRepository(DataContext dataContext)
+    {
+        DataContext = dataContext;
+    }
+
+    public DbSet<LoadingMessage> Get()
+    {
+        return DataContext.LoadingMessages;
+    }
+
+    public LoadingMessage Add(LoadingMessage loadingMessage)
+    {
+        var x = DataContext.LoadingMessages.Add(loadingMessage);
+        DataContext.SaveChanges();
+        return x.Entity;
+    }
+
+    public void Update(LoadingMessage loadingMessage)
+    {
+        DataContext.LoadingMessages.Update(loadingMessage);
+        DataContext.SaveChanges();
+    }
+
+    public void Delete(LoadingMessage loadingMessage)
+    {
+        DataContext.LoadingMessages.Remove(loadingMessage);
+        DataContext.SaveChanges();
+    }
+    
+    public void Dispose()
+    {
+        DataContext.Dispose();
+    }
+}

+ 4 - 2
Moonlight/App/Services/DiscordBot/BaseModule.cs

@@ -2,12 +2,14 @@
 
 namespace Moonlight.App.Services.DiscordBot;
 
-public class BaseModule
+public abstract class BaseModule
 {
     public DiscordSocketClient Client { get; set; }
     public ConfigService ConfigService { get; set; }
     public IServiceScope Scope { get; set; }
-
+    
+    public abstract Task RegisterCommands();
+    
     public BaseModule(
         DiscordSocketClient client,
         ConfigService configService,

+ 65 - 12
Moonlight/App/Services/DiscordBot/DiscordBotService.cs

@@ -1,22 +1,28 @@
-using Discord;
+using System.Diagnostics;
+using Discord;
 using Discord.WebSocket;
 using Logging.Net;
+using Moonlight.App.Repositories;
+using Moonlight.App.Services.DiscordBot.Commands;
+using Moonlight.App.Services.DiscordBot.Modules;
 
 namespace Moonlight.App.Services.DiscordBot;
 
 public class DiscordBotService
 {
+    public static bool MaintenanceMode = false;
+
     private readonly IServiceScopeFactory ServiceScopeFactory;
     private readonly ConfigService ConfigService;
-    
+
     private IServiceScope ServiceScope;
 
     private readonly DiscordSocketClient Client;
-    
-    // Add here references so e.g.
-    // public ExampleModule ExampleModule { get; private set; }
 
-    public DiscordBotService(
+    // References
+    public ActivityStatusModule ActivityStatusModule { get; private set; }
+
+public DiscordBotService(
         IServiceScopeFactory serviceScopeFactory,
         ConfigService configService)
     {
@@ -34,24 +40,71 @@ public class DiscordBotService
         var discordConfig = ConfigService
             .GetSection("Moonlight")
             .GetSection("DiscordBot");
-        
-        if(!discordConfig.GetValue<bool>("Enable"))
+
+        if (!discordConfig.GetValue<bool>("Enable"))
             return;
-        
+
         Client.Log += Log;
-        
-        // Init here the modules e.g.
-        // ExampleModule = new(Client, ConfigService, Scope)
+        Client.Ready += OnReady;
+
+        //Commands
+
+        //Module
+        ActivityStatusModule = new(Client, ConfigService, ServiceScope);
+
+        await ActivityStatusModule.UpdateActivityStatusList();
 
         await Client.LoginAsync(TokenType.Bot, discordConfig.GetValue<string>("Token"));
         await Client.StartAsync();
 
         await Task.Delay(-1);
     }
+    private async Task OnReady()
+    {
+        //await Client.SetGameAsync(name: "https://endelon-hosting.de", type: ActivityType.Watching);
+        await Client.SetStatusAsync(UserStatus.Idle);
+
+        Logger.Info($"Invite link: https://discord.com/api/oauth2/authorize?client_id={Client.CurrentUser.Id}&permissions=1099511696391&scope=bot%20applications.commands");
+        Logger.Info($"Login as {Client.CurrentUser.Username}#{Client.CurrentUser.DiscriminatorValue}");
+        
+        Task.Run(ActivityStatusModule.ActivityStatusScheduler);
+    }
 
     private Task Log(LogMessage message)
     {
         Logger.Debug(message.Message);
         return Task.CompletedTask;
     }
+
+    public async Task CreateCommands()
+    {
+        Stopwatch stopwatch = new Stopwatch();
+        stopwatch.Start();
+
+        var type = this.GetType();
+        var properties = type.GetProperties();
+        Logger.Debug("Start Initializing Commands");
+        foreach (var property in properties)
+        {
+            if (property.PropertyType.IsSubclassOf(typeof(BaseModule)))
+            {
+                try
+                {
+                    var instance = (BaseModule)property.GetValue(this)!;
+                    await instance.RegisterCommands();
+                    Logger.Debug("Registered" + instance);
+                    await Task.Delay(TimeSpan.FromMilliseconds(1000));
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error($"Module Error {ex.Message}");
+                    Logger.Error(ex.InnerException);
+                }
+            }
+        }
+
+        stopwatch.Stop();
+        Logger.Info($"Registered all commands. Done in {stopwatch.ElapsedMilliseconds}ms");
+    }
+
 }

+ 39 - 0
Moonlight/App/Services/DiscordBot/Modules/ActivityStatusModule.cs

@@ -0,0 +1,39 @@
+using Discord;
+using Discord.WebSocket;
+using Moonlight.App.Database.Entities;
+using Moonlight.App.Repositories;
+
+namespace Moonlight.App.Services.DiscordBot.Modules;
+
+public class ActivityStatusModule : BaseModule
+{
+    
+    private List<LoadingMessage> LoadingMessages;
+    
+    private readonly PeriodicTimer Timer = new(TimeSpan.FromMinutes(1));
+
+    public ActivityStatusModule(DiscordSocketClient client, ConfigService configService, IServiceScope scope) : base(client, configService, scope)
+        { }
+    public override Task RegisterCommands()
+        { return Task.CompletedTask; }
+    
+    public Task UpdateActivityStatusList()
+    {
+        var loadingMessageRepo = Scope.ServiceProvider.GetRequiredService<LoadingMessageRepository>();
+        LoadingMessages = loadingMessageRepo.Get().ToList();
+        
+        return Task.CompletedTask;
+    }
+
+    public async void ActivityStatusScheduler()
+    {
+        while (await Timer.WaitForNextTickAsync())
+        {
+            Random rand = new Random();
+            LoadingMessage random = LoadingMessages[rand.Next(LoadingMessages.Count)];
+            
+            await Client.SetGameAsync(random.Message, "https://www.endelon.team", ActivityType.Streaming);
+        }
+    }
+
+}

+ 34 - 0
Moonlight/App/Services/DiscordBot/Modules/RemoveCommandsModuels.cs

@@ -0,0 +1,34 @@
+using System.Diagnostics;
+using Discord;
+using Discord.WebSocket;
+using Logging.Net;
+
+namespace Moonlight.App.Services.DiscordBot.Commands;
+
+public class RemoveCommandsModuels : BaseModule
+{
+    public RemoveCommandsModuels(DiscordSocketClient client, ConfigService configService, IServiceScope scope) : base(client, configService, scope) {}
+    public override Task RegisterCommands()
+        { return Task.CompletedTask; }
+    
+    private async void VoidCommands()
+    {
+        Stopwatch stopwatch = new Stopwatch();
+        stopwatch.Start();
+        
+        var commands = await Client.GetGlobalApplicationCommandsAsync();
+        if (commands == null) return;
+
+        foreach (var slashCommand in commands)
+        {
+            if(slashCommand.Name == "commands") continue;
+            
+            await slashCommand.DeleteAsync();
+            Logger.Debug($"Deleted {slashCommand.Name}, {slashCommand.Id}");
+            await Task.Delay(TimeSpan.FromMilliseconds(1000));
+        }
+        
+        stopwatch.Stop();
+        Logger.Info($"Deleted all commands. Done in {stopwatch.ElapsedMilliseconds}ms");
+    }
+}

+ 0 - 1
Moonlight/Moonlight.csproj

@@ -67,7 +67,6 @@
     <Folder Include="App\Http\Middleware" />
     <Folder Include="App\Models\Daemon\Requests" />
     <Folder Include="App\Models\Google\Resources" />
-    <Folder Include="App\Services\DiscordBot\Modules" />
     <Folder Include="resources\lang" />
   </ItemGroup>
 

+ 3 - 2
Moonlight/Program.cs

@@ -62,6 +62,7 @@ namespace Moonlight
             builder.Services.AddScoped<SubscriptionRepository>();
             builder.Services.AddScoped<PleskServerRepository>();
             builder.Services.AddScoped<WebsiteRepository>();
+            builder.Services.AddScoped<LoadingMessageRepository>();
 
             builder.Services.AddScoped<AuditLogEntryRepository>();
             builder.Services.AddScoped<ErrorLogEntryRepository>();
@@ -129,7 +130,6 @@ namespace Moonlight
             builder.Services.AddSingleton<DiscordBotService>();
 
             // Third party services
-
             builder.Services.AddBlazorTable();
             builder.Services.AddSweetAlert2(options => { options.Theme = SweetAlertTheme.Dark; });
             builder.Services.AddBlazorContextMenu();
@@ -157,8 +157,9 @@ namespace Moonlight
             // Support service
             var supportServerService = app.Services.GetRequiredService<SupportServerService>();
             
-            // cleanup service
+            // AutoStart services
             _ = app.Services.GetRequiredService<CleanupService>();
+            _ = app.Services.GetRequiredService<DiscordBotService>();
             
             // Discord bot service
             //var discordBotService = app.Services.GetRequiredService<DiscordBotService>();

+ 17 - 3
Moonlight/Shared/Views/Admin/Sys/DiscordBot.razor

@@ -6,20 +6,34 @@
 
 <OnlyAdmin>
     <AdminSystemNavigation Index="6"/>
-    
+
     <div class="mt-3 card card-body">
         <WButton Text="Register commands"
                  WorkingText="Working"
                  CssClasses="btn-primary"
                  OnClick="RegisterCommands">
         </WButton>
+
+        <WButton Text="Void commands"
+                 WorkingText="Working"
+                 CssClasses="mt-3 btn-danger"
+                 OnClick="VoidCommands">
+        </WButton>
     </div>
 </OnlyAdmin>
 
-@code 
+@code
 {
+    //ToDo: Ole muss ins Bett gehen
+    //ToDo: Bot Info Card with Name, Bot Avatar, (RichPresence) Game Status, Activity Status
+    
     private async Task RegisterCommands()
     {
-        
+        await DiscordBotService.CreateCommands();
+    }
+    
+    private Task VoidCommands()
+    {
+        return Task.CompletedTask;
     }
 }

+ 7 - 7
Moonlight/Shared/Views/Domain/Index.razor → Moonlight/Shared/Views/Domain/View.razor

@@ -60,7 +60,7 @@
                             <input class="form-control" type="number" placeholder="@(SmartTranslateService.Translate("Priority"))" @bind="NewRecord.Priority"/>
                         </div>
                     </div>
-                    <div class="d-flex">
+                    <div class="d-flex me-2">
                         <div class="mt-3 ms-auto">
                             <WButton Text="@(SmartTranslateService.Translate("Add"))"
                                      WorkingText="@(SmartTranslateService.Translate("Adding"))"
@@ -79,7 +79,7 @@
                                 <div class="separator"></div>
                                 <div class="accordion-item">
                                     <h2 class="accordion-header" id="heading@(record.Id)">
-                                        <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse@(record.Id)" aria-expanded="false" aria-controls="collapse@(record.Id)">
+                                        <button class="accordion-button ps-6 collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse@(record.Id)" aria-expanded="false" aria-controls="collapse@(record.Id)">
                                             <div class="row w-100">
                                                 <div class="ms-5 col">
                                                     @(record.Type.ToString().ToUpper())
@@ -103,7 +103,7 @@
                                         </button>
                                     </h2>
                                     <div id="collapse@(record.Id)" class="accordion-collapse collapse" aria-labelledby="heading@(record.Id)" data-bs-parent="#accordionDomain">
-                                        <div class="accordion-body">
+                                        <div class="accordion-body ms-3 me-3">
                                             <div class="w-100 d-flex flex-row justify-content-between align-items-center">
                                                 <div class="p-2">
                                                     <input class="form-control" type="text" value="@(record.Type.ToString().ToUpper())" disabled=""/>
@@ -129,8 +129,8 @@
                                             </div>
                                         </div>
                                         <div class="separator mx-5"></div>
-                                        <div class="accordion-body">
-                                            <div class="d-flex">
+                                        <div class="accordion-body me-0 ms-5">
+                                            <div class="d-flex me-2">
                                                 <div class="me-auto">
                                                     <WButton Text="@(SmartTranslateService.Translate("Delete"))"
                                                              WorkingText="@(SmartTranslateService.Translate("Deleting"))"
@@ -138,9 +138,9 @@
                                                              OnClick="() => Delete(record)">
                                                     </WButton>
                                                 </div>
-                                                <div>
+                                                <div class="me-3 ms-3">
                                                     <button class="btn btn-light" data-bs-toggle="collapse" data-bs-target="#collapse@(record.Id)">
-                                                        <TL>Cancle</TL>
+                                                        <TL>Cancel</TL>
                                                     </button>
                                                     <WButton Text="@(SmartTranslateService.Translate("Save"))"
                                                              WorkingText="@(SmartTranslateService.Translate("Saving"))"

+ 49 - 0
Moonlight/Shared/Views/Domains.razor

@@ -1,2 +1,51 @@
 @page "/domains"
 
+@using Moonlight.App.Repositories.Domains
+@using Moonlight.App.Database.Entities
+@using Microsoft.EntityFrameworkCore
+@using BlazorTable
+@using Moonlight.App.Services
+@using domain = Moonlight.App.Database.Entities.Domain
+
+@inject DomainRepository DomainRepository
+@inject DomainService DomainService
+@inject SmartTranslateService SmartTranslateService
+
+<LazyLoader Load="Load">
+    @foreach (var domain in domains)
+    {
+        <div class="row px-5 mb-5">
+            <div class="card card-body">
+                <div class="row">
+                    <div class="col">
+                        <div class="d-flex align-items-center">
+                            <div class="symbol symbol-50px me-3">
+                                <i class="bx bx-md bx-purchase-tag"></i>
+                            </div>
+                            <div class="d-flex justify-content-start flex-column">
+                                <a href="/domain/@domain.Id" class="text-gray-800 text-hover-primary mb-1 fs-5">@domain.Name.@domain.SharedDomain.Name</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    }
+</LazyLoader>
+
+@code {
+    [CascadingParameter]
+    public User? User { get; set; }
+    
+    private domain[] domains { get; set; }
+    
+    public async Task Load(LazyLoader loader)
+    {
+        domains = DomainRepository
+            .Get()
+            .Include(x => x.SharedDomain)
+            .Include(x => x.Owner)
+            .Where(x => x.Owner == User)
+            .ToArray();
+    }
+}