Switched to new routing for the server manage page

This commit is contained in:
Marcel Baumgartner
2023-06-16 17:43:48 +02:00
parent 880cce060f
commit 125e72fa58
24 changed files with 51 additions and 58 deletions

View File

@@ -1,10 +0,0 @@
<div class="alert alert-primary d-flex rounded p-6">
<div class="d-flex flex-stack flex-grow-1 flex-wrap flex-md-nowrap">
<div class="mb-3 mb-md-0 fw-semibold">
<h4 class="text-gray-900 fw-bold"><TL>Addons</TL></h4>
<div class="fs-6 text-gray-700 pe-7">
<TL>This feature is currently not available</TL>
</div>
</div>
</div>
</div>

View File

@@ -1,300 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Helpers
@using Logging.Net
@using BlazorContextMenu
@using Moonlight.App.Database.Entities
@using Moonlight.App.Events
@using Moonlight.App.Services.Interop
@inject ServerService ServerService
@inject NavigationManager NavigationManager
@inject AlertService AlertService
@inject ToastService ToastService
@inject ClipboardService ClipboardService
@inject EventSystem Event
@inject SmartTranslateService SmartTranslateService
@implements IDisposable
<LazyLoader @ref="LazyLoader" Load="Refresh">
@if (3 > AllBackups.Length)
{
<WButton
Text="@(SmartTranslateService.Translate("Create"))"
WorkingText="@(SmartTranslateService.Translate("Creating"))"
CssClasses="btn-primary mb-2"
OnClick="Create"></WButton>
}
else
{
<button class="btn btn-primary disabled mb-2" disabled=""><TL>Delete</TL></button>
}
<div class="table-responsive">
<table class="table align-middle table-row-dashed fs-6 gy-5 dataTable no-footer">
<thead>
</thead>
<tbody class="fw-semibold text-gray-600">
@foreach (var backup in AllBackups)
{
<tr class="odd">
<td>
<div class="d-flex align-items-center">
<div class="ms-5">
<a class="text-gray-800 text-hover-primary fs-5 fw-bold">@(backup.Name)</a>
</div>
</div>
</td>
<td class="text-end pe-0">
<span class="fw-bold">@(backup.Uuid)</span>
</td>
<td class="text-end pe-0">
<span class="fw-bold">@(Formatter.FormatSize(backup.Bytes))</span>
</td>
<td class="text-end pe-0">
<span class="fw-bold ms-3">@backup.CreatedAt.Date.ToLongDateString(), @backup.CreatedAt.Date.ToLongTimeString()</span>
</td>
<td class="text-end">
@if (backup.Created)
{
<ContextMenuTrigger MenuId="triggerMenu" MouseButtonTrigger="MouseButtonTrigger.Both" Data="backup">
<button class="btn btn-sm btn-icon btn-light btn-active-light-primary me-2">
<span class="svg-icon svg-icon-5 m-0">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="10" y="10" width="4" height="4" rx="2" fill="currentColor"></rect>
<rect x="17" y="10" width="4" height="4" rx="2" fill="currentColor"></rect>
<rect x="3" y="10" width="4" height="4" rx="2" fill="currentColor"></rect>
</svg>
</span>
</button>
</ContextMenuTrigger>
}
else
{
<span class="fw-bold">
<TL>Backup is going to be created</TL>
</span>
}
</td>
</tr>
}
</tbody>
</table>
</div>
<ContextMenu Id="triggerMenu" CssClass="bg-secondary z-10">
<Item Id="restore" OnClick="OnContextMenuClick">
<TL>Restore</TL>
</Item>
<Item Id="copyurl" OnClick="OnContextMenuClick">
<TL>Copy url</TL>
</Item>
<Item Id="download" OnClick="OnContextMenuClick">
<TL>Download</TL>
</Item>
<Item Id="delete" OnClick="OnContextMenuClick">
<TL>Delete</TL>
</Item>
</ContextMenu>
</LazyLoader>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private ServerBackup[]? AllBackups;
private LazyLoader LazyLoader;
protected override void OnInitialized()
{
Event.On<ServerBackup>("wings.backups.create", this, async (backup) =>
{
if (AllBackups == null)
return;
if (AllBackups.Any(x => x.Id == backup.Id))
{
await Task.Delay(TimeSpan.FromSeconds(1));
await ToastService.Success(SmartTranslateService.Translate("Backup successfully created"));
await LazyLoader.Reload();
}
});
Event.On<ServerBackup>("wings.backups.createFailed", this, async (backup) =>
{
if (AllBackups == null)
return;
if (AllBackups.Any(x => x.Id == backup.Id))
{
await ToastService.Error(SmartTranslateService.Translate("Backup creation failed"));
await LazyLoader.Reload();
}
});
Event.On<ServerBackup>("wings.backups.delete", this, async (backup) =>
{
if (AllBackups == null)
return;
if (AllBackups.Any(x => x.Id == backup.Id))
{
await ToastService.Success(SmartTranslateService.Translate("Backup successfully deleted"));
await LazyLoader.Reload();
}
});
Event.On<ServerBackup>("wings.backups.restore", this, async (backup) =>
{
if (AllBackups == null)
return;
if (AllBackups.Any(x => x.Id == backup.Id))
{
await ToastService.Success(SmartTranslateService.Translate("Backup successfully restored"));
}
});
}
private async Task Refresh(LazyLoader lazyLoader)
{
await InvokeAsync(StateHasChanged);
await lazyLoader.SetText(SmartTranslateService.Translate("Loading backups"));
AllBackups = await ServerService.GetBackups(CurrentServer, true);
await InvokeAsync(StateHasChanged);
}
private async Task Download(ServerBackup serverBackup)
{
var url = await ServerService.DownloadBackup(CurrentServer, serverBackup);
NavigationManager.NavigateTo(url);
await ToastService.Success(SmartTranslateService.Translate("Backup download successfully started"));
/*
try
{
}
catch (Exception e)
{
Logger.Warn("Error starting backup download");
Logger.Warn(e);
await ToastService.Error(SmartTranslateService.Translate("Backup download failed"));
}*/
}
private async Task CopyUrl(ServerBackup serverBackup)
{
var url = await ServerService.DownloadBackup(CurrentServer, serverBackup);
await ClipboardService.Copy(url);
await AlertService.Success(
SmartTranslateService.Translate("Success"),
SmartTranslateService.Translate("Backup URL successfully copied to your clipboard"));
/*
try
{
}
catch (Exception e)
{
Logger.Warn("Error copying backup url");
Logger.Warn(e);
await ToastService.Error(SmartTranslateService.Translate("An unknown error occured while generating backup url"));
}*/
}
private async Task Delete(ServerBackup serverBackup)
{
await ToastService.Info(SmartTranslateService.Translate("Backup deletion started"));
await ServerService.DeleteBackup(CurrentServer, serverBackup);
/*
try
{
}
catch (Exception e)
{
Logger.Warn("Error deleting backup");
Logger.Warn(e);
await ToastService.Error(SmartTranslateService.Translate("An unknown error occured while starting backup deletion"));
}*/
}
private async Task Restore(ServerBackup serverBackup)
{
await ServerService.RestoreBackup(CurrentServer, serverBackup);
await ToastService.Info(SmartTranslateService.Translate("Backup restore started"));
/*
try
{
}
catch (Exception e)
{
Logger.Warn("Error restoring backup");
Logger.Warn(e);
await ToastService.Error(SmartTranslateService.Translate("An unknown error occured while restoring a backup"));
}*/
}
private async Task Create()
{
await ToastService.Info(SmartTranslateService.Translate("Started backup creation"));
await ServerService.CreateBackup(CurrentServer);
await LazyLoader.Reload();
/*
try
{
// Modify the backup list so no reload needed. Also the create event will work
//var list = AllBackups!.ToList();
//list.Add(backup);
//AllBackups = list.ToArray();
}
catch (Exception e)
{
Logger.Warn("Error creating backup");
Logger.Warn(e);
await ToastService.Error(SmartTranslateService.Translate("An unknown error has occured while creating a backup"));
}*/
}
private async Task OnContextMenuClick(ItemClickEventArgs args)
{
var backup = (ServerBackup)args.Data;
switch (args.MenuItem.Id)
{
case "delete":
await Delete(backup);
break;
case "copyurl":
await CopyUrl(backup);
break;
case "restore":
await Restore(backup);
break;
case "download":
await Download(backup);
break;
}
await Refresh(LazyLoader);
}
public async void Dispose()
{
await Event.Off("wings.backups.create", this);
await Event.Off("wings.backups.createFailed", this);
await Event.Off("wings.backups.restore", this);
await Event.Off("wings.backups.delete", this);
}
}

View File

@@ -1,108 +0,0 @@
@using Moonlight.App.Helpers
@using Moonlight.App.Repositories
@using Moonlight.App.Services
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers.Wings
@using Moonlight.App.Helpers.Wings.Data
@using Moonlight.App.Services.Interop
@using Moonlight.Shared.Components.Xterm
@implements IDisposable
@inject ClipboardService ClipboardService
@inject AlertService AlertService
@inject SmartTranslateService TranslationService
<div class="card card-body rounded bg-black p-3">
<div class="d-flex flex-column">
<Terminal @ref="Terminal" RunOnFirstRender="RunOnFirstRender"></Terminal>
<div class="input-group">
<script suppress-error="BL9992">
function checkEnter(event)
{
if (event.keyCode === 13) {
event.preventDefault();
document.getElementById("sendCmd").click();
}
}
</script>
<input @bind="@CommandInput" class="form-control rounded-start" onkeyup="checkEnter(event)" placeholder="@(TranslationService.Translate("Enter command"))"/>
<button id="sendCmd" @onclick="SendCommand" class="input-group-text btn btn-primary">@(TranslationService.Translate("Execute"))</button>
</div>
</div>
</div>
@code
{
[CascadingParameter]
public WingsConsole Console { get; set; }
[CascadingParameter]
public Server CurrentServer { get; set; }
private Terminal? Terminal;
private string CommandInput = "";
protected override void OnInitialized()
{
Console.OnMessage += OnMessage;
}
private async void OnMessage(object? sender, ConsoleMessage message)
{
if (Terminal != null)
{
if (message.IsInternal)
{
await Terminal.WriteLine("\x1b[38;5;16;48;5;135m\x1b[39m\x1b[1m Moonlight \x1b[0m " + message.Content + "\x1b[0m");
}
else
{
var s = message.Content;
if (s.Contains("Moonlight Daemon") || s.Contains("Pterodactyl Daemon"))
{
s = s.Replace("[39m", "\x1b[0m");
s = s.Replace("[33m", "[38;5;16;48;5;135m\x1b[39m");
}
s = s.Replace("[Pterodactyl Daemon]:", " Moonlight ");
s = s.Replace("[Moonlight Daemon]:", " Moonlight ");
s = s.Replace("Checking server disk space usage, this could take a few seconds...", TranslationService.Translate("Checking disk space"));
s = s.Replace("Updating process configuration files...", TranslationService.Translate("Updating config files"));
s = s.Replace("Ensuring file permissions are set correctly, this could take a few seconds...", TranslationService.Translate("Checking file permissions"));
s = s.Replace("Pulling Docker container image, this could take a few minutes to complete...", TranslationService.Translate("Downloading server image"));
s = s.Replace("Finished pulling Docker container image", TranslationService.Translate("Downloaded server image"));
s = s.Replace("container@pterodactyl~", "server@moonlight >");
await Terminal.WriteLine(s);
}
}
}
public void Dispose()
{
Console.OnMessage -= OnMessage;
Terminal!.Dispose();
}
private async Task SendCommand()
{
CommandInput = CommandInput.Replace("\n", "");
await Console.EnterCommand(CommandInput);
CommandInput = "";
StateHasChanged();
}
private void RunOnFirstRender()
{
lock (Console.Messages)
{
foreach (var message in Console.Messages)
{
OnMessage(null, message);
}
}
}
}

View File

@@ -1,29 +0,0 @@
@using Moonlight.Shared.Components.FileManagerPartials
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Helpers.Files
@using Moonlight.App.Services
@using Moonlight.App.ApiClients.Wings
@using Moonlight.App.Helpers.Wings
@inject WingsApiHelper WingsApiHelper
@inject WingsJwtHelper WingsJwtHelper
@inject ConfigService ConfigService
<FileManager Access="FileAccess"></FileManager>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
[CascadingParameter]
public User User { get; set; }
private FileAccess FileAccess;
protected override void OnInitialized()
{
FileAccess = new WingsFileAccess(WingsApiHelper, WingsJwtHelper, CurrentServer, ConfigService, User);
}
}

View File

@@ -1,219 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Helpers.Wings
@using Moonlight.App.Helpers.Wings.Enums
@inject SmartTranslateService TranslationService
<div class="align-items-center">
<div class="row">
<div class="card card-body me-6">
<div class="row">
<div class="col-8">
<div class="d-flex align-items-center">
<div class="symbol symbol-circle me-5">
<div class="symbol-label bg-transparent text-primary border border-secondary border-dashed">
<i class="bx bx-server bx-md"></i>
</div>
</div>
<div class="d-flex flex-column">
<div class="mb-1 fs-4">@(CurrentServer.Name)</div>
<div class="text-muted fs-5">@(CurrentServer.Cpu <= 100 ? Math.Round(CurrentServer.Cpu / 100f, 2) + $" {TranslationService.Translate("Core")}" : Math.Round(CurrentServer.Cpu / 100f, 2) + $" {TranslationService.Translate("Cores")}") / @(Math.Round(CurrentServer.Memory / 1024f, 2)) GB @(TranslationService.Translate("Memory")) / @(Math.Round(CurrentServer.Disk / 1024f, 2)) GB @(TranslationService.Translate("Disk")) / @(CurrentServer.Node.Name) - <span class="text-muted">@(CurrentServer.Image.Name)</span></div>
</div>
</div>
</div>
<div class="col-4 d-flex flex-column flex-end mb-1">
<div class="btn-group btn-group-sm">
<button class="w-100 nav-link btn btn-sm btn-success fw-bold px-4 me-1 @(Console.ServerState == ServerState.Offline ? "" : "disabled")" aria-selected="true" role="tab" @onclick="Start"><TL>Start</TL></button>
<button class="w-100 nav-link btn btn-sm btn-primary fw-bold px-4 me-1 @(Console.ServerState == ServerState.Running ? "" : "disabled")" aria-selected="true" role="tab" @onclick="Restart"><TL>Restart</TL></button>
@if (Console.ServerState == ServerState.Stopping)
{
<button class="w-100 nav-link btn btn-sm btn-danger fw-bold px-4 me-1" aria-selected="true" role="tab" @onclick="Kill"><TL>Kill</TL></button>
}
else
{
<button class="w-100 nav-link btn btn-sm btn-danger fw-bold px-4 me-1 @(Console.ServerState == ServerState.Running || Console.ServerState == ServerState.Starting ? "" : "disabled")"
aria-selected="true" role="tab" @onclick="Stop">
<TL>Stop</TL>
</button>
}
</div>
</div>
</div>
</div>
<div class="row">
<div class="separator my-5"></div>
</div>
<div class="row">
<div class="card card-body">
<div class="row align-items-center">
<div class="col fs-5">
<span class="fw-bold"><TL>Shared IP</TL>:</span>
<span class="ms-1 text-muted">@($"{CurrentServer.Node.Fqdn}:{CurrentServer.MainAllocation.Port}")</span>
</div>
<div class="col fs-5">
<span class="fw-bold"><TL>Server ID</TL>:</span>
<span class="ms-1 text-muted">
@if (User.Admin)
{
<a href="/admin/servers/view/@(CurrentServer.Id)">@(CurrentServer.Id)</a>
}
else
{
@(CurrentServer.Id)
}
</span>
</div>
<div class="col fs-5">
<span class="fw-bold"><TL>Status</TL>:</span>
<span class="ms-1 text-muted">
@switch (Console.ServerState)
{
case ServerState.Offline:
<span class="text-danger"><TL>Offline</TL></span>
break;
case ServerState.Starting:
<span class="text-warning"><TL>Starting</TL></span>
<span class="text-gray-700 pt-1 fw-semibold">(@(Formatter.FormatUptime(Console.Resource.Uptime)))</span>
break;
case ServerState.Stopping:
<span class="text-warning"><TL>Stopping</TL></span>
<span class="text-gray-700 pt-1 fw-semibold">(@(Formatter.FormatUptime(Console.Resource.Uptime)))</span>
break;
case ServerState.Running:
<span class="text-success"><TL>Online</TL></span>
<span class="text-gray-700 pt-1 fw-semibold">(@(Formatter.FormatUptime(Console.Resource.Uptime)))</span>
break;
}
</span>
</div>
<div class="col fs-5">
<span class="fw-bold"><TL>Cpu</TL>:</span>
<span class="ms-1 text-muted">@(Math.Round(Console.Resource.CpuAbsolute / (CurrentServer.Cpu / 100f), 2))%</span>
</div>
<div class="col fs-5">
<span class="fw-bold"><TL>Memory</TL>:</span>
<span class="ms-1 text-muted">@(Formatter.FormatSize(Console.Resource.MemoryBytes)) / @(Formatter.FormatSize(Console.Resource.MemoryLimitBytes))</span>
</div>
<div class="col fs-5">
<span class="fw-bold"><TL>Disk</TL>:</span>
<span class="ms-1 text-muted">@(Formatter.FormatSize(Console.Resource.DiskBytes)) / @(Math.Round(CurrentServer.Disk / 1024f, 2)) GB</span>
</div>
</div>
</div>
</div>
<div class="mt-5 row">
<div class="d-flex flex-column flex-md-row card card-body p-10">
<ul class="nav nav-tabs nav-pills flex-row border-0 flex-md-column me-5 mb-3 mb-md-0 fs-6 min-w-lg-200px">
<li class="nav-item w-100 me-0 mb-md-2">
<a href="/server/@(CurrentServer.Uuid)/" class="nav-link w-100 btn btn-flex @(Index == 0 ? "active" : "") btn-active-light-primary">
<i class="bx bx-terminal bx-sm me-2"></i>
<span class="d-flex flex-column align-items-start">
<span class="fs-5"><TL>Console</TL></span>
</span>
</a>
</li>
<li class="nav-item w-100 me-0 mb-md-2">
<a href="/server/@(CurrentServer.Uuid)/files" class="nav-link w-100 btn btn-flex @(Index == 1 ? "active" : "") btn-active-light-primary">
<i class="bx bx-folder bx-sm me-2"></i>
<span class="d-flex flex-column align-items-start">
<span class="fs-5"><TL>Files</TL></span>
</span>
</a>
</li>
<li class="nav-item w-100 me-0 mb-md-2">
<a href="/server/@(CurrentServer.Uuid)/backups" class="nav-link w-100 btn btn-flex @(Index == 2 ? "active" : "") btn-active-light-primary">
<i class="bx bx-box bx-sm me-2"></i>
<span class="d-flex flex-column align-items-start">
<span class="fs-5"><TL>Backups</TL></span>
</span>
</a>
</li>
<li class="nav-item w-100 me-0 mb-md-2">
<a href="/server/@(CurrentServer.Uuid)/network" class="nav-link w-100 btn btn-flex @(Index == 3 ? "active" : "") btn-active-light-primary">
<i class="bx bx-wifi bx-sm me-2"></i>
<span class="d-flex flex-column align-items-start">
<span class="fs-5"><TL>Network</TL></span>
</span>
</a>
</li>
<li class="nav-item w-100 me-0 mb-md-2">
<a href="/server/@(CurrentServer.Uuid)/addons" class="nav-link w-100 btn btn-flex @(Index == 4 ? "active" : "") btn-active-light-primary">
<i class="bx bx-plug bx-sm me-2"></i>
<span class="d-flex flex-column align-items-start">
<span class="fs-5"><TL>Addons</TL></span>
</span>
</a>
</li>
<li class="nav-item w-100 me-0 mb-md-2">
<a href="/server/@(CurrentServer.Uuid)/settings" class="nav-link w-100 btn btn-flex @(Index == 5 ? "active" : "") btn-active-light-primary">
<i class="bx bx-cog bx-sm me-2"></i>
<span class="d-flex flex-column align-items-start">
<span class="fs-5"><TL>Settings</TL></span>
</span>
</a>
</li>
</ul>
<div class="tab-content w-100">
<div class="tab-pane fade show active">
@ChildContent
</div>
</div>
</div>
</div>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
[CascadingParameter]
public User User { get; set; }
[CascadingParameter]
public WingsConsole Console { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public int Index { get; set; } = 0;
//TODO: NodeIpService which loads and caches raw ips for nodes (maybe)
protected override void OnInitialized()
{
Console.OnServerStateUpdated += async (_, _) => { await InvokeAsync(StateHasChanged); };
Console.OnResourceUpdated += async (_, _) => { await InvokeAsync(StateHasChanged); };
}
#region Power Actions
private async Task Start()
{
await Console.SetPowerState("start");
}
private async Task Stop()
{
await Console.SetPowerState("stop");
}
private async Task Kill()
{
await Console.SetPowerState("kill");
}
private async Task Restart()
{
await Console.SetPowerState("restart");
}
#endregion
}

View File

@@ -1,41 +0,0 @@
@using Moonlight.App.Repositories
@using Moonlight.Shared.Components.Partials
@using Task = System.Threading.Tasks.Task
@using Logging.Net
@using Moonlight.App.Database.Entities
@inject NodeRepository NodeRepository
@foreach (var allocation in CurrentServer.Allocations)
{
<div class="row align-items-center">
<div class="col-1 me-4">
<i class="text-primary bx bx-wifi bx-md"></i>
</div>
<div class="col-7">
<span class="h4">
@(CurrentServer.Node.Fqdn):@(allocation.Port)
</span>
</div>
<div class="col-1 align-items-end">
@if (allocation.Id == CurrentServer.MainAllocation.Id)
{
<button class="btn btn-primary">
<TL>Primary</TL>
</button>
}
else
{
<button class="btn btn-danger">
<TL>Delete</TL>
</button>
}
</div>
</div>
}
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
}

View File

@@ -1,87 +0,0 @@
@using Moonlight.App.Database.Entities
@using Moonlight.Shared.Components.ServerControl.Settings
@using Microsoft.AspNetCore.Components.Rendering
<LazyLoader Load="Load">
<div class="accordion" id="serverSetting">
@foreach (var setting in Settings)
{
<div class="accordion-item">
<h2 class="accordion-header" id="serverSetting-header@(setting.GetHashCode())">
<button class="accordion-button fs-4 fw-semibold" type="button" data-bs-toggle="collapse" data-bs-target="#serverSetting-body@(setting.GetHashCode())" aria-expanded="true" aria-controls="serverSetting-body@(setting.GetHashCode())">
<TL>@(setting.Key)</TL>
</button>
</h2>
<div id="serverSetting-body@(setting.GetHashCode())" class="accordion-collapse collapse" aria-labelledby="serverSetting-header@(setting.GetHashCode())" data-bs-parent="#serverSetting">
<div class="accordion-body">
@(GetComponent(setting.Value))
</div>
</div>
</div>
}
</div>
</LazyLoader>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
[CascadingParameter]
public string[] Tags { get; set; }
private Dictionary<string, Type> Settings = new();
private Task Load(LazyLoader lazyLoader)
{
if(Tags.Contains("paperversion"))
Settings.Add("Paper version", typeof(PaperVersionSetting));
if(Tags.Contains("forgeversion"))
Settings.Add("Forge version", typeof(ForgeVersionSetting));
if(Tags.Contains("fabricversion"))
Settings.Add("Fabric version", typeof(FabricVersionSetting));
if(Tags.Contains("join2start"))
Settings.Add("Join2Start", typeof(Join2StartSetting));
if(Tags.Contains("javascriptversion"))
Settings.Add("Javascript version", typeof(JavascriptVersionSetting));
if(Tags.Contains("javascriptfile"))
Settings.Add("Javascript file", typeof(JavascriptFileSetting));
if(Tags.Contains("pythonversion"))
Settings.Add("Python version", typeof(PythonVersionSetting));
if(Tags.Contains("javaversion"))
Settings.Add("Java version", typeof(JavaRuntimeVersionSetting));
if(Tags.Contains("dotnetversion"))
Settings.Add("Dotnet version", typeof(DotnetVersionSetting));
if(Tags.Contains("pythonfile"))
Settings.Add("Python file", typeof(PythonFileSetting));
if(Tags.Contains("javafile"))
Settings.Add("Jar file", typeof(JavaFileSetting));
if(Tags.Contains("dotnetfile"))
Settings.Add("Dll file", typeof(DotnetFileSetting));
Settings.Add("Rename", typeof(ServerRenameSetting));
Settings.Add("Reset", typeof(ServerResetSetting));
Settings.Add("Delete", typeof(ServerDeleteSetting));
return Task.CompletedTask;
}
private RenderFragment GetComponent(Type type) => builder =>
{
builder.OpenComponent(0, type);
builder.CloseComponent();
};
}

View File

@@ -1,85 +0,0 @@
@using Task = System.Threading.Tasks.Task
@using Moonlight.App.Repositories.Servers
@using Moonlight.Shared.Components.FileManagerPartials
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Helpers.Files
@using Moonlight.App.Services
@inject ServerRepository ServerRepository
@inject ServerService ServerService
@inject SmartTranslateService SmartTranslateService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="me-2 form-label">
<TL>Dll file</TL>
</label>
<table class="w-100">
<tr>
<td class="w-100">
<input type="text" class="form-control disabled" disabled="" value="@(PathAndFile)"/>
</td>
<td>
<button @onclick="Show" class="btn btn-primary ms-2"><TL>Change</TL></button>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
<FileSelectModal @ref="FileSelectModal"
Access="Access"
Filter="@(x => !x.IsFile || x.Name.EndsWith(".dll"))"
Title="@(SmartTranslateService.Translate("Select dll to execute on start"))"
OnlyFolder="false"
OnCancel="() => { return Task.CompletedTask; }"
OnSubmit="OnSubmit">
</FileSelectModal>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string PathAndFile;
private FileAccess Access;
private FileSelectModal FileSelectModal;
private LazyLoader LazyLoader;
protected override async Task OnInitializedAsync()
{
Access = await ServerService.CreateFileAccess(CurrentServer, null!);
}
private async Task Load(LazyLoader lazyLoader)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "MAIN_DLL");
PathAndFile = v != null ? v.Value : "";
await InvokeAsync(StateHasChanged);
}
private async Task Show()
{
await FileSelectModal.Show();
}
private async Task OnSubmit(string path)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "MAIN_DLL");
if (v != null)
{
v.Value = path.TrimStart("/"[0]);
ServerRepository.Update(CurrentServer);
}
await LazyLoader.Reload();
}
}

View File

@@ -1,89 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Helpers
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="mb-2 form-label"><TL>Dotnet version</TL></label>
<table class="w-100">
<tr>
<td class="w-100">
<select @bind="ImageIndex" class="form-select">
@foreach (var image in DockerImages)
{
if (image.Id == SelectedImage.Id)
{
<option value="@(image.Id)" selected="selected">
@(ParseHelper.ToDotnetVersionName(image.Name))
</option>
}
else
{
<option value="@(image.Id)">
@(ParseHelper.ToDotnetVersionName(image.Name))
</option>
}
}
</select>
</td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary ms-2">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private LazyLoader LazyLoader;
private List<DockerImage> DockerImages;
private DockerImage SelectedImage;
private int ImageIndex
{
get => SelectedImage.Id;
set { SelectedImage = DockerImages.First(x => x.Id == value); }
}
private Task Load(LazyLoader lazyLoader)
{
var image = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
DockerImages = image.DockerImages;
SelectedImage = DockerImages[CurrentServer.DockerImageIndex];
return Task.CompletedTask;
}
private async Task Save()
{
CurrentServer.DockerImageIndex = DockerImages.IndexOf(SelectedImage);
ServerRepository.Update(CurrentServer);
await LazyLoader.Reload();
}
}

View File

@@ -1,205 +0,0 @@
@using Moonlight.App.Services
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Moonlight.App.Helpers
@using Moonlight.App.Services.Minecraft
@inject ServerService ServerService
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject FabricService FabricService
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader Load="Load">
<table class="w-100">
<tr>
<td colspan="2">
<label class="form-label mb-0">
<TL>Fabric version</TL>
</label>
</td>
</tr>
<tr>
<td class="w-100" colspan="2">
<input class="mb-2 form-control" disabled="" value="@(FabricVersion)"/>
</td>
</tr>
<tr>
<td colspan="2">
<label class="form-label mb-0">
<TL>Fabric loader version</TL>
</label>
</td>
</tr>
<tr>
<td class="w-100" colspan="2">
<input class="mb-2 form-control" disabled="" value="@(LoaderVersion)"/>
</td>
</tr>
<tr>
<td colspan="2">
<label class="form-label mb-0">
<TL>Minecraft version</TL>
</label>
</td>
</tr>
<tr>
<td class="w-100" colspan="2">
<select class="mb-2 form-select" @bind="CurrentVersion">
@foreach (var version in Versions)
{
if (version == CurrentVersion)
{
<option value="@(version)" selected="">@(version)</option>
}
else
{
<option value="@(version)">@(version)</option>
}
}
</select>
</td>
</tr>
<tr>
<td class="w-100"></td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary mt-2">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string[] Versions = Array.Empty<string>();
private string CurrentVersion = "";
private string FabricVersion = "";
private string LoaderVersion = "";
private async Task Load(LazyLoader lazyLoader)
{
// Fabric version
var fabricVersion = LiveMigrateVar(
"FABRIC_VERSION",
await FabricService.GetLatestInstallerVersion(),
true
);
FabricVersion = fabricVersion.Value;
// Fabric loader version
var loaderVersion = LiveMigrateVar(
"LOADER_VERSION",
await FabricService.GetLatestLoaderVersion(),
true
);
LoaderVersion = loaderVersion.Value;
// Minecraft versions
Versions = await FabricService.GetGameVersions();
var mcVersion = LiveMigrateVar(
"MC_VERSION",
Versions.First()
);
CurrentVersion = mcVersion.Value;
await InvokeAsync(StateHasChanged);
}
private ServerVariable LiveMigrateVar(string key, string value, bool overwrite = false)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == key);
if (v == null)
{
CurrentServer.Variables.Add(new()
{
Key = key,
Value = value
});
ServerRepository.Update(CurrentServer);
return CurrentServer.Variables.First(x => x.Key == key);
}
else
{
if (string.IsNullOrEmpty(v.Value) || overwrite)
{
v.Value = value;
ServerRepository.Update(CurrentServer);
}
return v;
}
}
private async Task Save()
{
var vars = CurrentServer.Variables;
var versionVar = vars.First(x => x.Key == "MC_VERSION");
versionVar.Value = CurrentVersion;
// This searches for the display name of a version using the constructed full version
var version = ParseHelper.MinecraftToInt(CurrentVersion);
var serverImage = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
var dockerImages = serverImage.DockerImages;
var dockerImageToUpdate = dockerImages.Last();
if (version < 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("8"));
}
if (version >= 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("11"));
}
if (version >= 1170)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("16"));
}
if (version >= 1190)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("17"));
}
CurrentServer.DockerImageIndex = dockerImages.IndexOf(dockerImageToUpdate);
ServerRepository.Update(CurrentServer);
await ServerService.Reinstall(CurrentServer);
}
}

View File

@@ -1,156 +0,0 @@
@using Moonlight.App.Services
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Logging.Net
@using Moonlight.App.Helpers
@using Moonlight.App.Services.Minecraft
@inject ServerService ServerService
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject ForgeService ForgeService
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader Load="Load">
<label class="mb-2 form-label"><TL>Forge version</TL></label>
<table class="w-100">
<tr>
<td class="w-100">
<select class="form-select" @bind="CurrentVersion">
@foreach (var version in Versions.Keys)
{
if (DisplayToData(version) == CurrentVersion)
{
<option value="@(DisplayToData(version))" selected="">@(version)</option>
}
else
{
<option value="@(DisplayToData(version))">@(version)</option>
}
}
</select>
</td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary ms-2">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private Dictionary<string, string> Versions = new();
private string CurrentVersion = "";
private async Task Load(LazyLoader lazyLoader)
{
Versions = await ForgeService.GetVersions();
var vars = CurrentServer.Variables;
var versionVar = vars.FirstOrDefault(x => x.Key == "FORGE_VERSION");
// Live migration
if (versionVar == null)
{
CurrentServer.Variables.Add(new ()
{
Key = "FORGE_VERSION",
Value = LatestVersion()
});
ServerRepository.Update(CurrentServer);
versionVar = vars.First(x => x.Key == "FORGE_VERSION");
}
else
{
if (string.IsNullOrEmpty(versionVar.Value))
{
versionVar.Value = LatestVersion();
ServerRepository.Update(CurrentServer);
}
}
CurrentVersion = versionVar.Value;
await InvokeAsync(StateHasChanged);
}
private string DisplayToData(string display)
{
return display
.Replace("-recommended", "")
.Replace("-latest", "") + "-" + Versions[display];
}
private string LatestVersion()
{
var versionsSorted = Versions.Keys
.OrderByDescending(ParseHelper.MinecraftToInt);
return DisplayToData(versionsSorted.First());
}
private async Task Save()
{
var vars = CurrentServer.Variables;
var versionVar = vars.First(x => x.Key == "FORGE_VERSION");
versionVar.Value = CurrentVersion;
// This searches for the display name of a version using the constructed full version
var version = ParseHelper.MinecraftToInt(
Versions.First(
x => DisplayToData(x.Key) == CurrentVersion).Key);
var serverImage = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
var dockerImages = serverImage.DockerImages;
var dockerImageToUpdate = dockerImages.Last();
if (version < 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("8"));
}
if (version >= 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("11"));
}
if (version >= 1170)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("16"));
}
if (version >= 1190)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("17"));
}
CurrentServer.DockerImageIndex = dockerImages.IndexOf(dockerImageToUpdate);
ServerRepository.Update(CurrentServer);
await ServerService.Reinstall(CurrentServer);
}
}

View File

@@ -1,85 +0,0 @@
@using Task = System.Threading.Tasks.Task
@using Moonlight.App.Repositories.Servers
@using Moonlight.Shared.Components.FileManagerPartials
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Helpers.Files
@using Moonlight.App.Services
@inject ServerRepository ServerRepository
@inject ServerService ServerService
@inject SmartTranslateService SmartTranslateService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="me-2 form-label">
<TL>Jar file</TL>
</label>
<table class="w-100">
<tr>
<td class="w-100">
<input type="text" class="form-control disabled" disabled="" value="@(PathAndFile)"/>
</td>
<td>
<button @onclick="Show" class="btn btn-primary ms-2"><TL>Change</TL></button>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
<FileSelectModal @ref="FileSelectModal"
Access="Access"
Filter="@(x => !x.IsFile || x.Name.EndsWith(".jar"))"
Title="@(SmartTranslateService.Translate("Select jar to execute on start"))"
OnlyFolder="false"
OnCancel="() => { return Task.CompletedTask; }"
OnSubmit="OnSubmit">
</FileSelectModal>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string PathAndFile;
private FileAccess Access;
private FileSelectModal FileSelectModal;
private LazyLoader LazyLoader;
protected override async Task OnInitializedAsync()
{
Access = await ServerService.CreateFileAccess(CurrentServer, null!);
}
private async Task Load(LazyLoader lazyLoader)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "JARFILE");
PathAndFile = v != null ? v.Value : "";
await InvokeAsync(StateHasChanged);
}
private async Task Show()
{
await FileSelectModal.Show();
}
private async Task OnSubmit(string path)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "JARFILE");
if (v != null)
{
v.Value = path.TrimStart("/"[0]);
ServerRepository.Update(CurrentServer);
}
await LazyLoader.Reload();
}
}

View File

@@ -1,89 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Helpers
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="mb-2 form-label"><TL>Java version</TL></label>
<table class="w-100">
<tr>
<td class="w-100">
<select @bind="ImageIndex" class="form-select">
@foreach (var image in DockerImages)
{
if (image.Id == SelectedImage.Id)
{
<option value="@(image.Id)" selected="selected">
Java @(ParseHelper.FirstPartStartingWithNumber(image.Name))
</option>
}
else
{
<option value="@(image.Id)">
Java @(ParseHelper.FirstPartStartingWithNumber(image.Name))
</option>
}
}
</select>
</td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary ms-2">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private LazyLoader LazyLoader;
private List<DockerImage> DockerImages;
private DockerImage SelectedImage;
private int ImageIndex
{
get => SelectedImage.Id;
set { SelectedImage = DockerImages.First(x => x.Id == value); }
}
private Task Load(LazyLoader lazyLoader)
{
var image = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
DockerImages = image.DockerImages;
SelectedImage = DockerImages[CurrentServer.DockerImageIndex];
return Task.CompletedTask;
}
private async Task Save()
{
CurrentServer.DockerImageIndex = DockerImages.IndexOf(SelectedImage);
ServerRepository.Update(CurrentServer);
await LazyLoader.Reload();
}
}

View File

@@ -1,84 +0,0 @@
@using Task = System.Threading.Tasks.Task
@using Moonlight.App.Repositories.Servers
@using Moonlight.Shared.Components.FileManagerPartials
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers.Files
@using Moonlight.App.Services
@inject ServerRepository ServerRepository
@inject SmartTranslateService SmartTranslateService
@inject ServerService ServerService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="mb-2 form-label">
<TL>Javascript file</TL>
</label>
<table class="w-100">
<tr>
<td class="w-100">
<input type="text" class="form-control disabled" disabled="" value="@(PathAndFile)"/>
</td>
<td>
<button @onclick="Show" class="ms-2 btn btn-primary"><TL>Change</TL></button>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
<FileSelectModal @ref="FileSelectModal"
Access="Access"
Filter="@(x => !x.IsFile || x.Name.EndsWith(".js"))"
Title="@(SmartTranslateService.Translate("Select javascript file to execute on start"))"
OnlyFolder="false"
OnCancel="() => { return Task.CompletedTask; }"
OnSubmit="OnSubmit">
</FileSelectModal>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string PathAndFile;
private FileAccess Access;
private FileSelectModal FileSelectModal;
private LazyLoader LazyLoader;
protected override async Task OnInitializedAsync()
{
Access = await ServerService.CreateFileAccess(CurrentServer, null!);
}
private async Task Load(LazyLoader lazyLoader)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "BOT_JS_FILE");
PathAndFile = v != null ? v.Value : "";
await InvokeAsync(StateHasChanged);
}
private async Task Show()
{
await FileSelectModal.Show();
}
private async Task OnSubmit(string path)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "BOT_JS_FILE");
if (v != null)
{
v.Value = path.TrimStart("/"[0]);
ServerRepository.Update(CurrentServer);
}
await LazyLoader.Reload();
}
}

View File

@@ -1,88 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Helpers
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="mb-2 form-label"><TL>Javascript version</TL></label>
<table class="w-100">
<tr>
<td class="w-100">
<select @bind="ImageIndex" class="form-select ">
@foreach (var image in DockerImages)
{
if (image.Id == SelectedImage.Id)
{
<option value="@(image.Id)" selected="selected">
@(ParseHelper.FirstPartStartingWithNumber(image.Name))
</option>
}
else
{
<option value="@(image.Id)">
@(ParseHelper.FirstPartStartingWithNumber(image.Name))
</option>
}
}
</select>
</td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="ms-2 btn-primary">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private LazyLoader LazyLoader;
private List<DockerImage> DockerImages;
private DockerImage SelectedImage;
private int ImageIndex
{
get => SelectedImage.Id;
set { SelectedImage = DockerImages.First(x => x.Id == value); }
}
private Task Load(LazyLoader lazyLoader)
{
var image = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
DockerImages = image.DockerImages;
SelectedImage = DockerImages[CurrentServer.DockerImageIndex];
return Task.CompletedTask;
}
private async Task Save()
{
CurrentServer.DockerImageIndex = DockerImages.IndexOf(SelectedImage);
ServerRepository.Update(CurrentServer);
await LazyLoader.Reload();
}
}

View File

@@ -1,80 +0,0 @@
@using Moonlight.App.Services
@using Task = System.Threading.Tasks.Task
@using Moonlight.Shared.Components.Partials
@using Moonlight.App.Helpers
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Logging.Net
@using Moonlight.App.ApiClients.Wings
@using Moonlight.App.Database.Entities
@inject ServerRepository ServerRepository
@inject ServerService ServerService
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="Loader" Load="Load">
<table class="w-100">
<tr>
<td class="w-100">
<div class="form-check form-check-custom form-check-solid mb-3">
<input @bind="Value" class="form-check-input" type="checkbox" value="1" id="j2sCheck"/>
<label class="form-check-label" for="j2sCheck">
<TL>Join2Start</TL>
</label>
</div>
</td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private bool Value;
private LazyLoader Loader;
private async Task Load(LazyLoader lazyLoader)
{
Value = CurrentServer.Variables.First(x => x.Key == "J2S").Value == "1";
await InvokeAsync(StateHasChanged);
}
private async Task Save()
{
CurrentServer.Variables.First(x => x.Key == "J2S").Value = Value ? "1" : "0";
ServerRepository.Update(CurrentServer);
var details = await ServerService.GetDetails(CurrentServer);
// For better user experience, we start the j2s server right away when the user enables j2s
if (details.State == "offline")
{
await ServerService.SetPowerState(CurrentServer, PowerSignal.Start);
}
// For better user experience, we kill the j2s server right away when the user disables j2s and the server is starting
if (details.State == "starting")
{
await ServerService.SetPowerState(CurrentServer, PowerSignal.Kill);
}
await Loader.Reload();
}
}

View File

@@ -1,204 +0,0 @@
@using Moonlight.App.Services
@using Task = System.Threading.Tasks.Task
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Moonlight.App.Services.Minecraft
@inject ServerService ServerService
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject PaperService PaperService
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader Load="Load">
<table class="w-100">
<tr>
<td colspan="2">
<label class="mb-0 form-label"><TL>Minecraft version</TL></label>
</td>
</tr>
<tr>
<td colspan="2">
<select class="mb-2 form-select" @bind="InputVersion">
@foreach (var version in Versions)
{
if (version == Version)
{
<option value="@(version)" selected="">@(version)</option>
}
else
{
<option value="@(version)">@(version)</option>
}
}
</select>
</td>
</tr>
<tr>
<td colspan="2">
<label class="mb-0 form-label"><TL>Build version</TL></label>
</td>
</tr>
<tr>
<td colspan="2">
<select class="mb-2 form-select" @bind="InputBuild">
@foreach (var build in Builds)
{
if (build == Build)
{
<option value="@(build)" selected="">@(build)</option>
}
else
{
<option value="@(build)">@(build)</option>
}
}
</select>
</td>
</tr>
<tr>
<td class="w-100"></td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary mt-2"></WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string[] Versions;
private string Version;
private string[] Builds;
private string Build;
// Form
private string InputVersion
{
get { return Version; }
set
{
Version = value;
RefreshBuilds();
Build = Builds.First();
InvokeAsync(StateHasChanged);
}
}
private string InputBuild
{
get { return Build; }
set { Build = value; }
}
private async Task RefreshVersions()
{
Versions = (await PaperService.GetVersions()).Reverse().ToArray();
}
private async Task RefreshBuilds()
{
Builds = (await PaperService.GetBuilds(Version)).Reverse().ToArray();
}
private async Task Load(LazyLoader lazyLoader)
{
var vars = CurrentServer.Variables;
await RefreshVersions();
Version = vars.First(x => x.Key == "MINECRAFT_VERSION").Value;
Build = vars.First(x => x.Key == "BUILD_NUMBER").Value;
if (string.IsNullOrEmpty(Version))
Version = "latest";
if (string.IsNullOrEmpty(Build))
Version = "latest";
if (Version == "latest") // Live migration
{
Version = Versions.First();
CurrentServer.Variables.First(x => x.Key == "MINECRAFT_VERSION").Value = Version;
ServerRepository.Update(CurrentServer);
}
await RefreshBuilds();
if (Build == "latest") // Live migration
{
Build = Builds.First();
CurrentServer.Variables.First(x => x.Key == "BUILD_NUMBER").Value = Build;
ServerRepository.Update(CurrentServer);
}
await InvokeAsync(StateHasChanged);
}
private async Task Save()
{
CurrentServer.Variables.First(x => x.Key == "MINECRAFT_VERSION").Value = Version;
CurrentServer.Variables.First(x => x.Key == "BUILD_NUMBER").Value = Build;
ServerRepository.Update(CurrentServer);
var versionWithoutPre = Version.Split("-")[0];
if (versionWithoutPre.Count(x => x == "."[0]) == 1)
versionWithoutPre += ".0";
var version = int.Parse(versionWithoutPre.Replace(".", ""));
var serverImage = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
var dockerImages = serverImage.DockerImages;
var dockerImageToUpdate = dockerImages.Last();
if (version < 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("8"));
}
if (version >= 1130)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("11"));
}
if (version >= 1170)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("16"));
}
if (version >= 1190)
{
dockerImageToUpdate = dockerImages.First(x => x.Name.Contains("17"));
}
CurrentServer.DockerImageIndex = dockerImages.IndexOf(dockerImageToUpdate);
ServerRepository.Update(CurrentServer);
await ServerService.Reinstall(CurrentServer);
}
}

View File

@@ -1,87 +0,0 @@
@using Task = System.Threading.Tasks.Task
@using Moonlight.App.Repositories.Servers
@using Moonlight.Shared.Components.FileManagerPartials
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Helpers.Files
@using Moonlight.App.Services
@inject ServerRepository ServerRepository
@inject ServerService ServerService
@inject SmartTranslateService SmartTranslateService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="mb-2 form-label">
<TL>Python file</TL>
</label>
<table class="w-100">
<tr>
<td class="w-100">
<input type="text" class="form-control disabled" disabled="" value="@(PathAndFile)"/>
</td>
<td>
<button @onclick="Show" class="ms-2 btn btn-primary"><TL>Change</TL></button>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
<FileSelectModal @ref="FileSelectModal"
Access="Access"
Filter="@(x => !x.IsFile || x.Name.EndsWith(".py"))"
Title="@(SmartTranslateService.Translate("Select python file to execute on start"))"
OnlyFolder="false"
OnCancel="() => { return Task.CompletedTask; }"
OnSubmit="OnSubmit">
</FileSelectModal>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private string PathAndFile;
private FileAccess Access;
private FileSelectModal FileSelectModal;
private LazyLoader LazyLoader;
protected override async Task OnInitializedAsync()
{
Access = await ServerService.CreateFileAccess(CurrentServer, null!);
}
private async Task Load(LazyLoader lazyLoader)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "BOT_PY_FILE");
PathAndFile = v != null ? v.Value : "";
await InvokeAsync(StateHasChanged);
}
private async Task Show()
{
await FileSelectModal.Show();
}
private async Task OnSubmit(string path)
{
var v = CurrentServer.Variables.FirstOrDefault(x => x.Key == "BOT_PY_FILE");
if (v != null)
{
v.Value = path.TrimStart("/"[0]);
ServerRepository.Update(CurrentServer);
}
await LazyLoader.Reload();
}
}

View File

@@ -1,88 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Helpers
@using Moonlight.App.Repositories
@using Moonlight.App.Repositories.Servers
@using Microsoft.EntityFrameworkCore
@using Moonlight.App.Database.Entities
@inject ServerRepository ServerRepository
@inject ImageRepository ImageRepository
@inject SmartTranslateService TranslationService
<div class="col">
<div class="card card-body p-0">
<LazyLoader @ref="LazyLoader" Load="Load">
<label class="mb-2 form-label"><TL>Python version</TL></label>
<table class="w-100">
<tr>
<td class="w-100">
<select @bind="ImageIndex" class="form-select">
@foreach (var image in DockerImages)
{
if (image.Id == SelectedImage.Id)
{
<option value="@(image.Id)" selected="selected">
@(ParseHelper.FirstPartStartingWithNumber(image.Name))
</option>
}
else
{
<option value="@(image.Id)">
@(ParseHelper.FirstPartStartingWithNumber(image.Name))
</option>
}
}
</select>
</td>
<td>
<WButton
OnClick="Save"
Text="@(TranslationService.Translate("Change"))"
WorkingText="@(TranslationService.Translate("Changing"))"
CssClasses="btn-primary ms-2">
</WButton>
</td>
</tr>
</table>
</LazyLoader>
</div>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private LazyLoader LazyLoader;
private List<DockerImage> DockerImages;
private DockerImage SelectedImage;
private int ImageIndex
{
get => SelectedImage.Id;
set { SelectedImage = DockerImages.First(x => x.Id == value); }
}
private Task Load(LazyLoader lazyLoader)
{
var image = ImageRepository
.Get()
.Include(x => x.DockerImages)
.First(x => x.Id == CurrentServer.Image.Id);
DockerImages = image.DockerImages;
SelectedImage = DockerImages[CurrentServer.DockerImageIndex];
return Task.CompletedTask;
}
private async Task Save()
{
CurrentServer.DockerImageIndex = DockerImages.IndexOf(SelectedImage);
ServerRepository.Update(CurrentServer);
await LazyLoader.Reload();
}
}

View File

@@ -1,29 +0,0 @@
@using Moonlight.App.Database.Entities
@using Moonlight.App.Services
@using Moonlight.App.Services.Interop
@inject SmartTranslateService SmartTranslateService
@inject AlertService AlertService
@inject NavigationManager NavigationManager
@inject ServerService ServerService
<WButton Text="@(SmartTranslateService.Translate("Delete"))"
WorkingText="@(SmartTranslateService.Translate("Deleting"))"
CssClasses="btn-danger"
OnClick="OnClick">
</WButton>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private async Task OnClick()
{
if (await AlertService.ConfirmMath())
{
await ServerService.Delete(CurrentServer);
NavigationManager.NavigateTo("/servers");
}
}
}

View File

@@ -1,41 +0,0 @@
@using Moonlight.App.Repositories.Servers
@using Moonlight.App.Database.Entities
@using Moonlight.App.Models.Forms
@inject ServerRepository ServerRepository
<div class="input-group mb-3">
<LazyLoader @ref="LazyLoader" Load="Load">
<SmartForm CssClass="w-100" Model="Model" OnValidSubmit="Rename">
<div class="input-group mb-3 w-100">
<InputText @bind-Value="Model.Name" type="text" class="form-control"></InputText>
<button class="btn btn-primary" type="submit"><TL>Rename</TL></button>
</div>
</SmartForm>
</LazyLoader>
</div>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private ServerRenameDataModel Model = new();
private LazyLoader LazyLoader;
private Task Load(LazyLoader arg)
{
Model.Name = CurrentServer.Name;
return Task.CompletedTask;
}
private async Task Rename()
{
CurrentServer.Name = Model.Name;
ServerRepository.Update(CurrentServer);
await LazyLoader.Reload();
}
}

View File

@@ -1,54 +0,0 @@
@using Moonlight.App.Services
@using Moonlight.App.Database.Entities
@using Moonlight.App.Helpers
@using Moonlight.App.Helpers.Files
@using Moonlight.App.Services.Interop
@inject SmartTranslateService SmartTranslateService
@inject AlertService AlertService
@inject ToastService ToastService
@inject ServerService ServerService
<WButton Text="@(SmartTranslateService.Translate("Reset"))"
WorkingText="@(SmartTranslateService.Translate("Resetting"))"
CssClasses="btn-danger"
OnClick="OnClick">
</WButton>
@code
{
[CascadingParameter]
public Server CurrentServer { get; set; }
private async Task OnClick()
{
var b = await AlertService.YesNo(
SmartTranslateService.Translate("Are you sure you want to reset this server?"),
SmartTranslateService.Translate("Are you sure? This cannot be undone"),
SmartTranslateService.Translate("Yes"),
SmartTranslateService.Translate("No")
);
if (b)
{
await ToastService.CreateProcessToast("serverReset", SmartTranslateService.Translate("Resetting server"));
var access = await ServerService.CreateFileAccess(CurrentServer, null!);
var files = await access.Ls();
int i = 1;
foreach (var file in files)
{
await access.Delete(file);
await ToastService.UpdateProcessToast("serverReset", $"{SmartTranslateService.Translate("Deleted file")} {i}/{files.Length}");
i++;
}
await ToastService.UpdateProcessToast("serverReset", SmartTranslateService.Translate("Reinstalling server"));
await ServerService.Reinstall(CurrentServer);
await ToastService.RemoveProcessToast("serverReset");
}
}
}