diff --git a/.idea/.idea.Moonlight/.idea/material_theme_project_new.xml b/.idea/.idea.Moonlight/.idea/material_theme_project_new.xml new file mode 100644 index 0000000..1a83bdf --- /dev/null +++ b/.idea/.idea.Moonlight/.idea/material_theme_project_new.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/Moonlight/Core/Http/Controllers/AvatarController.cs b/Moonlight/Core/Http/Controllers/AvatarController.cs index 617363d..1b235ff 100644 --- a/Moonlight/Core/Http/Controllers/AvatarController.cs +++ b/Moonlight/Core/Http/Controllers/AvatarController.cs @@ -55,9 +55,9 @@ public class AvatarController : Controller if (!IdentityService.IsLoggedIn) return StatusCode(403); - if (ConfigService.Get().Security.EnforceAvatarPrivacy && - id != IdentityService.CurrentUser.Id && - IdentityService.CurrentUser.Permissions < 1000) + if (ConfigService.Get().Security.EnforceAvatarPrivacy && // Do we need to enforce privacy? + id != IdentityService.CurrentUser.Id && // is the user not viewing his own image? + IdentityService.CurrentUser.Permissions < 1000) // and not an admin? { return StatusCode(403); } diff --git a/Moonlight/Core/Services/DiagnoseService.cs b/Moonlight/Core/Services/DiagnoseService.cs index a38bbe3..b76bbc2 100644 --- a/Moonlight/Core/Services/DiagnoseService.cs +++ b/Moonlight/Core/Services/DiagnoseService.cs @@ -22,13 +22,16 @@ public class DiagnoseService { using var scope = ServiceProvider.CreateScope(); + // Create in memory zip archive using var dataStream = new MemoryStream(); var zipArchive = new ZipArchive(dataStream, ZipArchiveMode.Create, true); + // Call every plugin to perform their modifications to the file await PluginService.ExecuteFuncAsync( async x => await x.GenerateReport(zipArchive, scope.ServiceProvider) ); + // Add a timestamp await zipArchive.AddText("exported_at.txt", Formatter.FormatDate(DateTime.UtcNow)); zipArchive.Dispose(); diff --git a/Moonlight/Core/Services/UnloadService.cs b/Moonlight/Core/Services/UnloadService.cs index 6da5863..d62ced4 100644 --- a/Moonlight/Core/Services/UnloadService.cs +++ b/Moonlight/Core/Services/UnloadService.cs @@ -5,7 +5,7 @@ using MoonCore.Helpers; namespace Moonlight.Core.Services; /// -/// This class provides a event to execute code when a user leaves the page +/// This class provides an event to execute code when a user leaves the page /// [Scoped] diff --git a/Moonlight/Features/Servers/Helpers/ServerConsole.cs b/Moonlight/Features/Servers/Helpers/ServerConsole.cs index b1b9ec7..cd10375 100644 --- a/Moonlight/Features/Servers/Helpers/ServerConsole.cs +++ b/Moonlight/Features/Servers/Helpers/ServerConsole.cs @@ -2,12 +2,11 @@ using MoonCore.Helpers; using Moonlight.Features.Servers.Api.Packets; using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Models.Abstractions; using Moonlight.Features.Servers.Models.Enums; namespace Moonlight.Features.Servers.Helpers; -public class ServerConsole +public class ServerConsole : IDisposable { public SmartEventHandler OnStateChange { get; set; } = new(); public SmartEventHandler OnStatsChange { get; set; } = new(); @@ -23,7 +22,7 @@ public class ServerConsole private readonly Server Server; private ClientWebSocket WebSocket; - private WsPacketConnection PacketConnection; + private AdvancedWebsocketStream WebsocketStream; private CancellationTokenSource Cancellation = new(); @@ -50,11 +49,11 @@ public class ServerConsole wsUrl = $"ws://{Server.Node.Fqdn}:{Server.Node.HttpPort}/servers/{Server.Id}/ws"; await WebSocket.ConnectAsync(new Uri(wsUrl), CancellationToken.None); - PacketConnection = new WsPacketConnection(WebSocket); + WebsocketStream = new AdvancedWebsocketStream(WebSocket); - await PacketConnection.RegisterPacket("output"); - await PacketConnection.RegisterPacket("state"); - await PacketConnection.RegisterPacket("stats"); + WebsocketStream.RegisterPacket(1); + WebsocketStream.RegisterPacket(2); + WebsocketStream.RegisterPacket(3); Task.Run(Worker); } @@ -65,7 +64,7 @@ public class ServerConsole { try { - var packet = await PacketConnection.Receive(); + var packet = await WebsocketStream.ReceivePacket(); if (packet == null) continue; @@ -100,9 +99,11 @@ public class ServerConsole } catch (Exception e) { - if (e is not WebSocketException) + if (e is WebSocketException) + Logger.Warn($"Lost connection to daemon server websocket: {e.Message}"); + else { - Logger.Warn("Lost connection to daemon server websocket"); + Logger.Warn("Server console ws disconnected because of application error:"); Logger.Warn(e); } @@ -111,7 +112,7 @@ public class ServerConsole } await OnDisconnected.Invoke(); - await PacketConnection.Close(); + await WebsocketStream.Close(); } public async Task Close() @@ -119,8 +120,8 @@ public class ServerConsole if(!Cancellation.IsCancellationRequested) Cancellation.Cancel(); - if(PacketConnection != null) - await PacketConnection.Close(); + if(WebsocketStream != null) + await WebsocketStream.Close(); } private string[] GetMessageCache() @@ -128,4 +129,14 @@ public class ServerConsole lock (MessageCache) return MessageCache.ToArray(); } + + public async void Dispose() + { + MessageCache.Clear(); + + if (WebSocket.State == WebSocketState.Open) + await WebsocketStream.Close(); + + WebSocket.Dispose(); + } } \ No newline at end of file diff --git a/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs b/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs index 9a7199b..67ff35e 100644 --- a/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs +++ b/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs @@ -36,9 +36,9 @@ public class ServersControllers : Controller var websocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); // Build connection wrapper - var wsPacketConnection = new WsPacketConnection(websocket); - await wsPacketConnection.RegisterPacket("amount"); - await wsPacketConnection.RegisterPacket("serverConfiguration"); + var websocketStream = new AdvancedWebsocketStream(websocket); + websocketStream.RegisterPacket(1); + websocketStream.RegisterPacket(2); // Read server data for the node var node = (HttpContext.Items["Node"] as ServerNode)!; @@ -62,13 +62,13 @@ public class ServersControllers : Controller .ToArray(); // Send the amount of configs the node will receive - await wsPacketConnection.Send(servers.Length); + await websocketStream.SendPacket(servers.Length); // Send the server configurations foreach (var serverConfiguration in serverConfigurations) - await wsPacketConnection.Send(serverConfiguration); + await websocketStream.SendPacket(serverConfiguration); - await wsPacketConnection.WaitForClose(); + await websocketStream.WaitForClose(); return Ok(); } diff --git a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor index 905cfab..815e9df 100644 --- a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor +++ b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor @@ -113,13 +113,7 @@
- @if (IsInstalling) - { -
- -
- } - else if (IsConsoleDisconnected) + @if (IsConsoleDisconnected) { We lost the connection to the server. Please refresh the page in order to retry. If this error persists please contact the support @@ -137,6 +131,12 @@ The node this server is on is still booting. Please refresh the page in order to retry. If this error persists please contact the support } + else if (IsInstalling) + { +
+ +
+ } else { @@ -217,37 +217,7 @@ Console = new ServerConsole(Server); // Configure - Console.OnStateChange += async state => - { - // General rerender to update the state text in the ui - // NOTE: Obsolete because of the update timer - //await InvokeAsync(StateHasChanged); - - // Change from offline to installing - // This will trigger the initialisation of the install view - if (state == ServerState.Installing && !IsInstalling) - { - IsInstalling = true; - - // After this call, we should have access to the install terminal reference - await InvokeAsync(StateHasChanged); - - Console.OnNewMessage += OnInstallConsoleMessage; - } - // Change from installing to offline - // This will trigger the destruction of the install view - else if (state == ServerState.Offline && IsInstalling) - { - IsInstalling = false; - - Console.OnNewMessage -= OnInstallConsoleMessage; - - // After this call, the install terminal will disappear - await InvokeAsync(StateHasChanged); - - await ToastService.Info("Server installation complete"); - } - }; + Console.OnStateChange += async state => await HandleStateChange(state); Console.OnDisconnected += async () => { @@ -267,7 +237,7 @@ await InvokeAsync(StateHasChanged); return; } - + // We want to check if its an connection error, if yes we want to show the user that its an error with the connection // If not we proceed with the throwing for the soft error handler. @@ -288,6 +258,41 @@ } UpdateTimer = new Timer(async _ => { await InvokeAsync(StateHasChanged); }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1)); + + var state = await ServerService.GetState(Server); + await HandleStateChange(state); + } + + private async Task HandleStateChange(ServerState state) + { + // General rerender to update the state text in the ui + // NOTE: Obsolete because of the update timer + //await InvokeAsync(StateHasChanged); + + // Change from offline to installing + // This will trigger the initialisation of the install view + if (state == ServerState.Installing && !IsInstalling) + { + IsInstalling = true; + + // After this call, we should have access to the install terminal reference + await InvokeAsync(StateHasChanged); + + Console.OnNewMessage += OnInstallConsoleMessage; + } + // Change from installing to offline + // This will trigger the destruction of the install view + else if (state == ServerState.Offline && IsInstalling) + { + IsInstalling = false; + + Console.OnNewMessage -= OnInstallConsoleMessage; + + // After this call, the install terminal will disappear + await InvokeAsync(StateHasChanged); + + await ToastService.Info("Server installation complete"); + } } private async Task OnInstallConsoleMessage(string message) @@ -308,7 +313,10 @@ await UpdateTimer.DisposeAsync(); if (Console != null) + { await Console.Close(); + Console.Dispose(); + } } private int GetIndex() @@ -331,7 +339,7 @@ case "/network": return 2; - + case "/schedules": return 7; diff --git a/Moonlight/Features/Servers/UI/UserViews/Console.razor b/Moonlight/Features/Servers/UI/UserViews/Console.razor index 79544e3..fe50781 100644 --- a/Moonlight/Features/Servers/UI/UserViews/Console.razor +++ b/Moonlight/Features/Servers/UI/UserViews/Console.razor @@ -1,4 +1,3 @@ -@using Moonlight.Features.Servers.Models.Abstractions @using Moonlight.Features.Servers.Services @using Moonlight.Features.Servers.UI.Components @using Moonlight.Features.Servers.Entities @@ -6,7 +5,6 @@ @using Moonlight.Features.Servers.Api.Packets @using Moonlight.Features.Servers.Models.Enums @using MoonCore.Helpers -@using ApexCharts @inject ServerService ServerService @@ -79,13 +77,14 @@ var text = ""; foreach (var line in ServerConsole.Messages.TakeLast(50)) - text += line + "\n\r"; + { + var lineModified = line.Replace("\n", "\n\r"); + text += lineModified + "\n\r"; + } await Terminal.Write(text); - ServerConsole.OnNewMessage += OnMessage; - ServerConsole.OnStatsChange += HandleStats; ServerConsole.OnStateChange += HandleState; } @@ -108,7 +107,7 @@ private async Task OnMessage(string message) { - await Terminal.WriteLine(message); + await Terminal.Write(message + "\n\r"); } private async Task SendCommand() diff --git a/Moonlight/Moonlight.csproj b/Moonlight/Moonlight.csproj index f140329..df200a7 100644 --- a/Moonlight/Moonlight.csproj +++ b/Moonlight/Moonlight.csproj @@ -74,8 +74,7 @@ - - + @@ -90,7 +89,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -114,6 +113,7 @@ <_ContentIncludedByDefault Remove="Features\FileManager\UI\Components\FileManager.razor" /> <_ContentIncludedByDefault Remove="Features\FileManager\UI\Components\FileUploader.razor" /> <_ContentIncludedByDefault Remove="Features\FileManager\UI\Components\FileView.razor" /> + <_ContentIncludedByDefault Remove="storage\configs\core.json" />