diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index 53d88f6..7334cb5 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -33,7 +33,7 @@ body:
attributes:
label: Panel Version
description: Version number of your Panel (latest is not a version)
- placeholder: 1.4.0
+ placeholder: v2 EA
validations:
required: true
@@ -42,16 +42,7 @@ body:
attributes:
label: Daemon Version
description: Version number of your Daemon (latest is not a version)
- placeholder: 1.4.2
- validations:
- required: true
-
-- type: input
- id: wings-version
- attributes:
- label: Wings Version
- description: Version number of your Wings (latest is not a version)
- placeholder: 1.4.2
+ placeholder: v2 EA
validations:
required: true
@@ -93,4 +84,4 @@ body:
- label: I have provided all relevant details, including the specific game and Docker images I am using if this issue is related to running a server.
required: true
- label: I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system.
- required: true
\ No newline at end of file
+ required: true
diff --git a/.gitignore b/.gitignore
index 6cfd4f4..1cd56bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -400,4 +400,5 @@ FodyWeavers.xsd
storage/
.idea/.idea.Moonlight/.idea/dataSources.xml
Moonlight/wwwroot/css/theme.css
-Moonlight/wwwroot/css/theme.css.map
\ No newline at end of file
+Moonlight/wwwroot/css/theme.css.map
+.idea/.idea.Moonlight/.idea/discord.xml
diff --git a/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor b/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor
index 927e6d5..f6c4400 100644
--- a/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor
+++ b/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor
@@ -7,7 +7,7 @@
@inherits ErrorBoundaryBase
-@if (Crashed || CurrentException != null)
+@if (Crashed || Exception != null)
{
if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || (IdentityService.IsLoggedIn && IdentityService.CurrentUser.Permissions >= 9000))
{
diff --git a/Moonlight/Core/UI/Components/Partials/StatCard.razor b/Moonlight/Core/UI/Components/Partials/StatCard.razor
index 3cf844d..dd5f143 100644
--- a/Moonlight/Core/UI/Components/Partials/StatCard.razor
+++ b/Moonlight/Core/UI/Components/Partials/StatCard.razor
@@ -11,14 +11,14 @@
else
{
-
+
-
+
@Value
-
diff --git a/Moonlight/Core/UI/Views/Admin/Index.razor b/Moonlight/Core/UI/Views/Admin/Index.razor
index 713a618..0b6399a 100644
--- a/Moonlight/Core/UI/Views/Admin/Index.razor
+++ b/Moonlight/Core/UI/Views/Admin/Index.razor
@@ -34,7 +34,7 @@
private async Task Load(LazyLoader arg)
{
- await arg.SetText("Loading Information...");
+ await arg.SetText("Loading statistics...");
var componentImplementations = await PluginService.GetImplementations
();
diff --git a/Moonlight/Features/FileManager/FileManagerFeature.cs b/Moonlight/Features/FileManager/FileManagerFeature.cs
index c3171a6..eb80a64 100644
--- a/Moonlight/Features/FileManager/FileManagerFeature.cs
+++ b/Moonlight/Features/FileManager/FileManagerFeature.cs
@@ -54,9 +54,12 @@ public class FileManagerFeature : MoonlightFeature
await pluginService.RegisterImplementation(new RenameContextAction());
await pluginService.RegisterImplementation(new MoveContextAction());
await pluginService.RegisterImplementation(new DownloadContextAction());
+ await pluginService.RegisterImplementation(new ArchiveContextAction());
+ await pluginService.RegisterImplementation(new ExtractContextAction());
await pluginService.RegisterImplementation(new DeleteContextAction());
await pluginService.RegisterImplementation(new MoveSelectionAction());
+ await pluginService.RegisterImplementation(new ArchiveSelectionAction());
await pluginService.RegisterImplementation(new DeleteSelectionAction());
await pluginService.RegisterImplementation(new CreateFileAction());
diff --git a/Moonlight/Features/FileManager/Implementations/ArchiveContextAction.cs b/Moonlight/Features/FileManager/Implementations/ArchiveContextAction.cs
new file mode 100644
index 0000000..f2045a7
--- /dev/null
+++ b/Moonlight/Features/FileManager/Implementations/ArchiveContextAction.cs
@@ -0,0 +1,59 @@
+using MoonCore.Exceptions;
+using MoonCore.Helpers;
+using MoonCoreUI.Services;
+using Moonlight.Features.FileManager.Interfaces;
+using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
+
+namespace Moonlight.Features.FileManager.Implementations;
+
+public class ArchiveContextAction : IFileManagerContextAction
+{
+ public string Name => "Archive";
+ public string Icon => "bxs-archive-in";
+ public string Color => "warning";
+ public Func Filter => _ => true;
+
+ public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry,
+ IServiceProvider provider)
+ {
+ var archiveAccess = access.Actions as IArchiveFileActions;
+
+ if (archiveAccess == null)
+ throw new DisplayException("This file access does not support archiving");
+
+ var alertService = provider.GetRequiredService();
+
+ var fileName = await alertService.Text("Enter the archive file name", "",
+ Formatter.FormatDate(DateTime.UtcNow) + ".tar.gz");
+
+ if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled
+ return;
+
+ var toastService = provider.GetRequiredService();
+
+ await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient");
+
+ try
+ {
+ await archiveAccess.Archive(
+ access.CurrentDirectory + fileName,
+ new[] { access.CurrentDirectory + entry.Name }
+ );
+
+ await toastService.Success("Successfully created archive");
+ }
+ catch (Exception e)
+ {
+ Logger.Warn($"An error occured while archiving item ({entry.Name}):");
+ Logger.Warn(e);
+
+ await toastService.Danger("An unknown error occured while creating archive");
+ }
+ finally
+ {
+ await toastService.RemoveProgress("fileManagerArchive");
+ }
+
+ await fileManager.View.Refresh();
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs b/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs
index 135823d..240372e 100644
--- a/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs
+++ b/Moonlight/Features/FileManager/Implementations/ArchiveSelectionAction.cs
@@ -14,10 +14,7 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction
public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry[] entries,
IServiceProvider provider)
{
- if (!access.Actions.GetType().IsAssignableFrom(typeof(IArchiveFileActions)))
- throw new DisplayException("This file access does not support archiving");
-
- var archiveAccess = access as IArchiveFileActions;
+ var archiveAccess = access.Actions as IArchiveFileActions;
if (archiveAccess == null)
throw new DisplayException("This file access does not support archiving");
@@ -29,10 +26,30 @@ public class ArchiveSelectionAction : IFileManagerSelectionAction
if (string.IsNullOrEmpty(fileName) || fileName.Contains("..")) // => canceled
return;
+
+ var toastService = provider.GetRequiredService();
- await archiveAccess.Archive(
- access.CurrentDirectory + fileName,
- entries.Select(x => access.CurrentDirectory + x.Name).ToArray()
- );
+ await toastService.CreateProgress("fileManagerArchive", "Archiving... Please be patient");
+
+ try
+ {
+ await archiveAccess.Archive(
+ access.CurrentDirectory + fileName,
+ entries.Select(x => access.CurrentDirectory + x.Name).ToArray()
+ );
+
+ await toastService.Success("Successfully created archive");
+ }
+ catch (Exception e)
+ {
+ Logger.Warn($"An error occured while archiving items ({entries.Length}):");
+ Logger.Warn(e);
+
+ await toastService.Danger("An unknown error occured while creating archive");
+ }
+ finally
+ {
+ await toastService.RemoveProgress("fileManagerArchive");
+ }
}
}
\ No newline at end of file
diff --git a/Moonlight/Features/FileManager/Implementations/ExtractContextAction.cs b/Moonlight/Features/FileManager/Implementations/ExtractContextAction.cs
new file mode 100644
index 0000000..2b8735f
--- /dev/null
+++ b/Moonlight/Features/FileManager/Implementations/ExtractContextAction.cs
@@ -0,0 +1,52 @@
+using MoonCore.Exceptions;
+using MoonCore.Helpers;
+using MoonCoreUI.Services;
+using Moonlight.Features.FileManager.Interfaces;
+using Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
+
+namespace Moonlight.Features.FileManager.Implementations;
+
+public class ExtractContextAction : IFileManagerContextAction
+{
+ public string Name => "Extract";
+ public string Icon => "bxs-archive-out";
+ public string Color => "warning";
+ public Func Filter => entry => entry.IsFile && entry.Name.EndsWith(".tar.gz");
+ public async Task Execute(BaseFileAccess access, UI.Components.FileManager fileManager, FileEntry entry, IServiceProvider provider)
+ {
+ var archiveAccess = access.Actions as IArchiveFileActions;
+
+ if (archiveAccess == null)
+ throw new DisplayException("This file access does not support archiving");
+
+ await fileManager.OpenFolderSelect("Select where you want to extract the content of the archive", async destination =>
+ {
+ var toastService = provider.GetRequiredService();
+
+ await toastService.CreateProgress("fileManagerExtract", "Extracting... Please be patient");
+
+ try
+ {
+ await archiveAccess.Extract(
+ access.CurrentDirectory + entry.Name,
+ destination
+ );
+
+ await toastService.Success("Successfully extracted archive");
+ }
+ catch (Exception e)
+ {
+ Logger.Warn($"An error occured while extracting archive ({entry.Name}):");
+ Logger.Warn(e);
+
+ await toastService.Danger("An unknown error occured while extracting archive");
+ }
+ finally
+ {
+ await toastService.RemoveProgress("fileManagerExtract");
+ }
+
+ await fileManager.View.Refresh();
+ });
+ }
+}
\ No newline at end of file
diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs
index 988bd16..ed35594 100644
--- a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs
+++ b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IArchiveFileActions.cs
@@ -3,4 +3,5 @@ namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess;
public interface IArchiveFileActions
{
public Task Archive(string path, string[] files);
+ public Task Extract(string path, string destination);
}
\ No newline at end of file
diff --git a/Moonlight/Features/FileManager/UI/Components/FileManager.razor b/Moonlight/Features/FileManager/UI/Components/FileManager.razor
index 16e3701..e51c145 100644
--- a/Moonlight/Features/FileManager/UI/Components/FileManager.razor
+++ b/Moonlight/Features/FileManager/UI/Components/FileManager.razor
@@ -95,7 +95,8 @@ else
OnEntryClicked="OnEntryClicked"
OnNavigateUpClicked="OnNavigateUpClicked"
OnSelectionChanged="OnSelectionChanged"
- EnableContextMenu="true">
+ EnableContextMenu="true"
+ ShowUploadPrompt="true">
@foreach (var action in ContextActions)
{
diff --git a/Moonlight/Features/FileManager/UI/Components/FileView.razor b/Moonlight/Features/FileManager/UI/Components/FileView.razor
index 8970f4d..aabdae0 100644
--- a/Moonlight/Features/FileManager/UI/Components/FileView.razor
+++ b/Moonlight/Features/FileManager/UI/Components/FileView.razor
@@ -210,7 +210,7 @@
- @if (Entries.Length == 0)
+ @if (Entries.Length == 0 && ShowUploadPrompt)
{
@@ -240,6 +240,7 @@
[Parameter] public bool ShowDate { get; set; } = true;
[Parameter] public bool ShowSelect { get; set; } = true;
[Parameter] public bool ShowNavigateUp { get; set; } = true;
+ [Parameter] public bool ShowUploadPrompt { get; set; } = false;
[Parameter] public RenderFragment? ContextMenuTemplate { get; set; }
[Parameter] public bool EnableContextMenu { get; set; } = false;
diff --git a/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs b/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs
index 21e4692..8f4c451 100644
--- a/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs
+++ b/Moonlight/Features/Servers/Helpers/ServerApiFileActions.cs
@@ -47,6 +47,11 @@ public class ServerApiFileActions : IFileActions, IArchiveFileActions
{
await ApiClient.Post($"archive?path={path}&provider=tar.gz", files);
}
+
+ public async Task Extract(string path, string destination)
+ {
+ await ApiClient.Post($"extract?path={path}&destination={destination}&provider=tar.gz");
+ }
public IFileActions Clone() => new ServerApiFileActions(Endpoint, Token, ServerId);
diff --git a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor
index 43e08ff..64e6150 100644
--- a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor
+++ b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor
@@ -13,11 +13,13 @@
@using MoonCore.Exceptions
@using Moonlight.Features.Servers.Configuration
@using MoonCore.Services
+@using Moonlight.Core.Services
@inject Repository ServerRepository
@inject ServerService ServerService
@inject ToastService ToastService
@inject AlertService AlertService
+@inject IdentityService IdentityService
@inject ConfigService ConfigService
@implements IDisposable
@@ -217,6 +219,12 @@
.Include(x => x.Owner)
.First(x => x.Id == Id);
+ if (Server.Owner.Id != IdentityService.CurrentUser.Id && IdentityService.CurrentUser.Permissions < 5000)
+ {
+ Server = null!;
+ return;
+ }
+
await lazyLoader.SetText("Establishing a connection to the server");
// Create console wrapper