277 lines
No EOL
10 KiB
Text
277 lines
No EOL
10 KiB
Text
@page "/Servers/Add"
|
|
@page "/Servers/{id:guid}"
|
|
@page "/Servers/{id:guid}/General"
|
|
@attribute [Authorize(Roles = RoleService.AdministratorRoleName)]
|
|
@using System.Runtime.InteropServices
|
|
@using LANCommander.SDK.Enums
|
|
@using LANCommander.Server.Services.ServerEngines
|
|
@using LANCommander.Server.Settings
|
|
@using LANCommander.Server.Settings.Enums
|
|
@using LANCommander.Server.Settings.Models
|
|
@using LANCommander.Server.UI.Pages.Servers.Components
|
|
@using Microsoft.Extensions.Options
|
|
@inject ServerService ServerService
|
|
@inject GameService GameService
|
|
@inject DockerServerEngine DockerServerEngine
|
|
@inject RemoteServerEngine RemoteServerEngine
|
|
@inject IOptions<Settings> Settings
|
|
@inject NavigationManager NavigationManager
|
|
@inject IMessageService MessageService
|
|
@inject ModalService ModalService
|
|
@inject ILogger<General> Logger
|
|
|
|
<ServerEditView Id="Id">
|
|
<TitleTemplate>
|
|
@if (context.Id == Guid.Empty)
|
|
{
|
|
<Text>Add New Server</Text>
|
|
}
|
|
else
|
|
{
|
|
<Text>General</Text>
|
|
}
|
|
</TitleTemplate>
|
|
<TitleExtraTemplate>
|
|
<Flex Align="FlexAlign.Center" Justify="FlexJustify.End" Wrap="FlexWrap.NoWrap" Gap="FlexGap.Small">
|
|
@if (context != null && context.Id != Guid.Empty)
|
|
{
|
|
<ServerControl ServerId="context.Id"/>
|
|
|
|
@if (context != null && context.Id != Guid.Empty)
|
|
{
|
|
<Button OnClick="OpenExportDialog" Loading="_openingExportDialog">Export</Button>
|
|
}
|
|
}
|
|
|
|
<Button Type="ButtonType.Primary" OnClick="() => Save(context)">Save</Button>
|
|
</Flex>
|
|
</TitleExtraTemplate>
|
|
|
|
<ChildContent>
|
|
<Form Model="@context" Layout="@FormLayout.Vertical" Context="formContext">
|
|
<FormItem Label="Name">
|
|
<Input @bind-Value="@context.Name" AutoFocus="context.Id == Guid.Empty" />
|
|
</FormItem>
|
|
<FormItem Label="Game">
|
|
<Select TItem="Game"
|
|
TItemValue="Guid?"
|
|
DataSource="@Games.OrderBy(g => String.IsNullOrWhiteSpace(g.SortTitle) ? g.Title : g.SortTitle)"
|
|
@bind-Value="@context.GameId"
|
|
LabelName="Title"
|
|
ValueName="Id"
|
|
Placeholder="Select a Game"
|
|
DefaultActiveFirstOption="false"
|
|
EnableSearch>
|
|
<ItemTemplate Context="game">
|
|
@game.Title
|
|
</ItemTemplate>
|
|
</Select>
|
|
</FormItem>
|
|
|
|
<FormItem Label="Engine">
|
|
<EnumSelect TEnum="ServerEngine" @bind-Value="context.Engine" />
|
|
</FormItem>
|
|
|
|
@if (context.Engine == ServerEngine.Docker)
|
|
{
|
|
<FormItem Label="Docker Host">
|
|
<Select
|
|
TItem="ServerEngineConfiguration"
|
|
TItemValue="Guid?"
|
|
DataSource="Settings.Value.Server.GameServers.ServerEngines"
|
|
LabelName="Name"
|
|
ValueName="Id"
|
|
@bind-Value="context.DockerHostId"
|
|
OnSelectedItemChanged="ChangeDockerHost"></Select>
|
|
</FormItem>
|
|
|
|
<FormItem Label="Container">
|
|
<Select
|
|
TItem="DockerContainer"
|
|
TItemValue="string"
|
|
DataSource="Containers"
|
|
Disabled="!Containers.Any()"
|
|
LabelName="Name"
|
|
ValueName="Id"
|
|
@bind-Value="context.ContainerId"></Select>
|
|
</FormItem>
|
|
}
|
|
|
|
@if (context.Engine == ServerEngine.Remote)
|
|
{
|
|
<FormItem Label="Remote Host">
|
|
<Select TItem="ServerEngineConfiguration"
|
|
TItemValue="Guid?"
|
|
DataSource="@Settings.Value.Server.GameServers.ServerEngines.Where(e => e.Type == ServerEngine.Remote)"
|
|
LabelName="Name"
|
|
ValueName="Id"
|
|
@bind-Value="context.RemoteHostId"
|
|
OnSelectedItemChanged="ChangeRemoteHost" />
|
|
</FormItem>
|
|
|
|
<FormItem Label="Remote Server">
|
|
<Select TItem="SDK.Models.Server"
|
|
TItemValue="Guid?"
|
|
DataSource="RemoteServers"
|
|
Disabled="!RemoteServers.Any()"
|
|
LabelName="Name"
|
|
ValueName="Id"
|
|
@bind-Value="context.RemoteServerId" />
|
|
</FormItem>
|
|
}
|
|
|
|
@if (context.Engine != ServerEngine.Remote)
|
|
{
|
|
<FormItem Label="Executable Path">
|
|
<FilePicker Root="@RootPath" EntrySelectable="x => x is FileManagerFile" @bind-Value="@context.Path" OnSelected="(path) => context.WorkingDirectory = Path.GetDirectoryName(path)" />
|
|
</FormItem>
|
|
<FormItem Label="Arguments">
|
|
<Input @bind-Value="@context.Arguments" />
|
|
</FormItem>
|
|
<FormItem Label="Working Directory">
|
|
<FilePicker Root="@RootPath" Title="Choose Working Directory" OkText="Select Directory" EntrySelectable="x => x is FileManagerDirectory" @bind-Value="@context.WorkingDirectory" />
|
|
</FormItem>
|
|
}
|
|
<FormItem Label="Host">
|
|
<Input @bind-Value="@context.Host" />
|
|
</FormItem>
|
|
<FormItem Label="Port" HasFeedback="@PortInUse" Help="@(PortInUse ? "Another server may already be bound to this port" : "")" ValidateStatus="@(PortInUse ? FormValidateStatus.Warning : FormValidateStatus.Default)">
|
|
<ServerPortInput @bind-Value="@context.Port" @bind-PortInUse="PortInUse" ServerId="context.Id" />
|
|
</FormItem>
|
|
@if (context.Engine != ServerEngine.Remote)
|
|
{
|
|
<FormItem>
|
|
<LabelTemplate>
|
|
Use Shell Execute
|
|
<Tooltip Title="This option specifies whether you would like to run the server using the shell. Some servers may require this as they will have a UI or won't output logs to stdout">
|
|
<Icon Type="@IconType.Outline.QuestionCircle" Theme="@IconThemeType.Outline" />
|
|
</Tooltip>
|
|
</LabelTemplate>
|
|
<ChildContent>
|
|
<Switch @bind-Checked="context.UseShellExecute" />
|
|
</ChildContent>
|
|
</FormItem>
|
|
<FormItem Label="Termination Method">
|
|
<Select @bind-Value="context.ProcessTerminationMethod" TItem="ProcessTerminationMethod" TItemValue="ProcessTerminationMethod" DataSource="AllowedProcessTerminationMethods" />
|
|
</FormItem>
|
|
}
|
|
</Form>
|
|
</ChildContent>
|
|
</ServerEditView>
|
|
|
|
@code {
|
|
[Parameter] public Guid Id { get; set; }
|
|
|
|
IEnumerable<Game> Games = new List<Game>();
|
|
IEnumerable<DockerContainer> Containers = new List<DockerContainer>();
|
|
IEnumerable<SDK.Models.Server> RemoteServers = new List<SDK.Models.Server>();
|
|
|
|
Guid GameId;
|
|
|
|
string RootPath = Path.GetPathRoot(Directory.GetCurrentDirectory());
|
|
bool PortInUse = false;
|
|
|
|
bool _openingExportDialog;
|
|
|
|
IEnumerable<ProcessTerminationMethod> AllowedProcessTerminationMethods
|
|
{
|
|
get
|
|
{
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
|
return new ProcessTerminationMethod[]
|
|
{
|
|
ProcessTerminationMethod.SIGHUP,
|
|
ProcessTerminationMethod.SIGINT,
|
|
ProcessTerminationMethod.SIGKILL,
|
|
ProcessTerminationMethod.SIGTERM
|
|
};
|
|
else
|
|
return new ProcessTerminationMethod[]
|
|
{
|
|
ProcessTerminationMethod.Close,
|
|
ProcessTerminationMethod.Kill
|
|
};
|
|
}
|
|
}
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
Games = await GameService.Include(g => g.Media).GetAsync();
|
|
}
|
|
|
|
async Task ChangeDockerHost(ServerEngineConfiguration hostConfiguration)
|
|
{
|
|
Containers = await DockerServerEngine.GetContainersAsync(hostConfiguration.Id);
|
|
}
|
|
|
|
async Task ChangeRemoteHost(ServerEngineConfiguration hostConfiguration)
|
|
{
|
|
RemoteServers = await RemoteServerEngine.GetRemoteServersAsync(hostConfiguration.Id);
|
|
}
|
|
|
|
async Task Save(Server server)
|
|
{
|
|
try
|
|
{
|
|
if (server.Id != Guid.Empty)
|
|
{
|
|
server = await ServerService.UpdateAsync(server);
|
|
|
|
await MessageService.SuccessAsync("Server updated!");
|
|
}
|
|
else
|
|
{
|
|
server = await ServerService.AddAsync(server);
|
|
|
|
NavigationManager.LocationChanged += NotifyServerAdded;
|
|
|
|
NavigationManager.NavigateTo($"/Servers/{server.Id}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageService.Error("Could not save!");
|
|
Logger.LogError(ex, "Could not save!");
|
|
}
|
|
}
|
|
|
|
void NotifyServerAdded(object? sender, LocationChangedEventArgs e)
|
|
{
|
|
NavigationManager.LocationChanged -= NotifyServerAdded;
|
|
|
|
MessageService.Success("Server added!");
|
|
}
|
|
|
|
private async Task OpenExportDialog()
|
|
{
|
|
_openingExportDialog = true;
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
await Task.Yield();
|
|
|
|
var server = await ServerService.GetAsync(Id);
|
|
|
|
var modalOptions = new ModalOptions()
|
|
{
|
|
Title = $"Export {server.Name}",
|
|
Maximizable = false,
|
|
DefaultMaximized = false,
|
|
Closable = true,
|
|
OkText = "Add",
|
|
Footer = null,
|
|
};
|
|
|
|
var options = new ExportDialogOptions()
|
|
{
|
|
RecordId = Id,
|
|
RecordType = ImportExportRecordType.Server
|
|
};
|
|
|
|
var modalRef = await ModalService.CreateModalAsync<ExportDialog, ExportDialogOptions>(modalOptions, options);
|
|
|
|
_openingExportDialog = false;
|
|
|
|
await InvokeAsync(StateHasChanged);
|
|
await Task.Yield();
|
|
}
|
|
} |