mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2024-11-25 07:42:58 +01:00
Compare commits
3 Commits
599177409e
...
651a660cfc
Author | SHA1 | Date | |
---|---|---|---|
651a660cfc | |||
5e6cb91b64 | |||
80d6bcbcac |
@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Text;
|
||||||
using Phantom.Agent.Minecraft.Instance;
|
using Phantom.Agent.Minecraft.Instance;
|
||||||
using Phantom.Agent.Minecraft.Java;
|
using Phantom.Agent.Minecraft.Java;
|
||||||
using Phantom.Agent.Minecraft.Server;
|
using Phantom.Agent.Minecraft.Server;
|
||||||
@ -11,6 +12,7 @@ public abstract class BaseLauncher : IServerLauncher {
|
|||||||
private readonly InstanceProperties instanceProperties;
|
private readonly InstanceProperties instanceProperties;
|
||||||
|
|
||||||
protected string MinecraftVersion => instanceProperties.ServerVersion;
|
protected string MinecraftVersion => instanceProperties.ServerVersion;
|
||||||
|
protected string InstanceFolder => instanceProperties.InstanceFolder;
|
||||||
|
|
||||||
private protected BaseLauncher(InstanceProperties instanceProperties) {
|
private protected BaseLauncher(InstanceProperties instanceProperties) {
|
||||||
this.instanceProperties = instanceProperties;
|
this.instanceProperties = instanceProperties;
|
||||||
@ -51,16 +53,14 @@ public abstract class BaseLauncher : IServerLauncher {
|
|||||||
|
|
||||||
var processConfigurator = new ProcessConfigurator {
|
var processConfigurator = new ProcessConfigurator {
|
||||||
FileName = javaRuntimeExecutable.ExecutablePath,
|
FileName = javaRuntimeExecutable.ExecutablePath,
|
||||||
WorkingDirectory = instanceProperties.InstanceFolder,
|
WorkingDirectory = InstanceFolder,
|
||||||
RedirectInput = true,
|
RedirectInput = true,
|
||||||
UseShellExecute = false
|
UseShellExecute = false
|
||||||
};
|
};
|
||||||
|
|
||||||
var processArguments = processConfigurator.ArgumentList;
|
var processArguments = processConfigurator.ArgumentList;
|
||||||
PrepareJvmArguments(serverJar).Build(processArguments);
|
PrepareJvmArguments(serverJar).Build(processArguments);
|
||||||
processArguments.Add("-jar");
|
PrepareJavaProcessArguments(processArguments, serverJar.FilePath);
|
||||||
processArguments.Add(serverJar.FilePath);
|
|
||||||
processArguments.Add("nogui");
|
|
||||||
|
|
||||||
var process = processConfigurator.CreateProcess();
|
var process = processConfigurator.CreateProcess();
|
||||||
var instanceProcess = new InstanceProcess(instanceProperties, process);
|
var instanceProcess = new InstanceProcess(instanceProperties, process);
|
||||||
@ -99,6 +99,12 @@ public abstract class BaseLauncher : IServerLauncher {
|
|||||||
|
|
||||||
private protected virtual void CustomizeJvmArguments(JvmArgumentBuilder arguments) {}
|
private protected virtual void CustomizeJvmArguments(JvmArgumentBuilder arguments) {}
|
||||||
|
|
||||||
|
protected virtual void PrepareJavaProcessArguments(Collection<string> processArguments, string serverJarFilePath) {
|
||||||
|
processArguments.Add("-jar");
|
||||||
|
processArguments.Add(serverJarFilePath);
|
||||||
|
processArguments.Add("nogui");
|
||||||
|
}
|
||||||
|
|
||||||
private protected virtual Task<ServerJarInfo> PrepareServerJar(ILogger logger, string serverJarPath, CancellationToken cancellationToken) {
|
private protected virtual Task<ServerJarInfo> PrepareServerJar(ILogger logger, string serverJarPath, CancellationToken cancellationToken) {
|
||||||
return Task.FromResult(new ServerJarInfo(serverJarPath));
|
return Task.FromResult(new ServerJarInfo(serverJarPath));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Phantom.Agent.Minecraft.Instance;
|
||||||
|
using Phantom.Agent.Minecraft.Java;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
|
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
||||||
|
|
||||||
|
public sealed class ForgeLauncher : BaseLauncher {
|
||||||
|
public ForgeLauncher(InstanceProperties instanceProperties) : base(instanceProperties) {}
|
||||||
|
|
||||||
|
private protected override void CustomizeJvmArguments(JvmArgumentBuilder arguments) {
|
||||||
|
arguments.AddProperty("terminal.ansi", "true"); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PrepareJavaProcessArguments(Collection<string> processArguments, string serverJarFilePath) {
|
||||||
|
if (OperatingSystem.IsWindows()) {
|
||||||
|
processArguments.Add("@libraries/net/minecraftforge/forge/1.20.1-47.2.0/win_args.txt");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
processArguments.Add("@libraries/net/minecraftforge/forge/1.20.1-47.2.0/unix_args.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
processArguments.Add("nogui");
|
||||||
|
}
|
||||||
|
|
||||||
|
private protected override Task<ServerJarInfo> PrepareServerJar(ILogger logger, string serverJarPath, CancellationToken cancellationToken) {
|
||||||
|
return Task.FromResult(new ServerJarInfo(Path.Combine(InstanceFolder, "run.sh")));
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,11 @@ sealed class MinecraftServerExecutableDownloader {
|
|||||||
|
|
||||||
if (--listeners <= 0) {
|
if (--listeners <= 0) {
|
||||||
Logger.Debug("Unregistered last download listener, cancelling download.");
|
Logger.Debug("Unregistered last download listener, cancelling download.");
|
||||||
|
try {
|
||||||
cancellationTokenSource.Cancel();
|
cancellationTokenSource.Cancel();
|
||||||
|
} catch (ObjectDisposedException) {
|
||||||
|
// TODO THIS IS BAD
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Logger.Debug("Unregistered download listener, current listener count: {Listeners}", listeners);
|
Logger.Debug("Unregistered download listener, current listener count: {Listeners}", listeners);
|
||||||
|
@ -67,6 +67,10 @@ sealed class BackupManager : IDisposable {
|
|||||||
resultBuilder.Kind = BackupCreationResultKind.BackupCancelled;
|
resultBuilder.Kind = BackupCreationResultKind.BackupCancelled;
|
||||||
logger.Warning("Backup creation was cancelled.");
|
logger.Warning("Backup creation was cancelled.");
|
||||||
return null;
|
return null;
|
||||||
|
} catch (TimeoutException) {
|
||||||
|
resultBuilder.Kind = BackupCreationResultKind.BackupTimedOut;
|
||||||
|
logger.Warning("Backup creation timed out.");
|
||||||
|
return null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
resultBuilder.Kind = BackupCreationResultKind.UnknownError;
|
resultBuilder.Kind = BackupCreationResultKind.UnknownError;
|
||||||
logger.Error(e, "Caught exception while creating an instance backup.");
|
logger.Error(e, "Caught exception while creating an instance backup.");
|
||||||
@ -76,6 +80,8 @@ sealed class BackupManager : IDisposable {
|
|||||||
await dispatcher.EnableAutomaticSaving();
|
await dispatcher.EnableAutomaticSaving();
|
||||||
} catch (OperationCanceledException) {
|
} catch (OperationCanceledException) {
|
||||||
// Ignore.
|
// Ignore.
|
||||||
|
} catch (TimeoutException) {
|
||||||
|
logger.Warning("Timed out waiting for automatic saving to be re-enabled.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
resultBuilder.Warnings |= BackupCreationWarnings.CouldNotRestoreAutomaticSaving;
|
resultBuilder.Warnings |= BackupCreationWarnings.CouldNotRestoreAutomaticSaving;
|
||||||
logger.Error(e, "Caught exception while enabling automatic saving after creating an instance backup.");
|
logger.Error(e, "Caught exception while enabling automatic saving after creating an instance backup.");
|
||||||
@ -120,6 +126,7 @@ sealed class BackupManager : IDisposable {
|
|||||||
BackupCreationResultKind.Success => "Backup created successfully.",
|
BackupCreationResultKind.Success => "Backup created successfully.",
|
||||||
BackupCreationResultKind.InstanceNotRunning => "Instance is not running.",
|
BackupCreationResultKind.InstanceNotRunning => "Instance is not running.",
|
||||||
BackupCreationResultKind.BackupCancelled => "Backup cancelled.",
|
BackupCreationResultKind.BackupCancelled => "Backup cancelled.",
|
||||||
|
BackupCreationResultKind.BackupTimedOut => "Backup timed out.",
|
||||||
BackupCreationResultKind.BackupAlreadyRunning => "A backup is already being created.",
|
BackupCreationResultKind.BackupAlreadyRunning => "A backup is already being created.",
|
||||||
BackupCreationResultKind.BackupFileAlreadyExists => "Backup with the same name already exists.",
|
BackupCreationResultKind.BackupFileAlreadyExists => "Backup with the same name already exists.",
|
||||||
BackupCreationResultKind.CouldNotCreateBackupFolder => "Could not create backup folder.",
|
BackupCreationResultKind.CouldNotCreateBackupFolder => "Could not create backup folder.",
|
||||||
|
@ -7,7 +7,7 @@ using Serilog;
|
|||||||
namespace Phantom.Agent.Services.Backups;
|
namespace Phantom.Agent.Services.Backups;
|
||||||
|
|
||||||
sealed partial class BackupServerCommandDispatcher : IDisposable {
|
sealed partial class BackupServerCommandDispatcher : IDisposable {
|
||||||
[GeneratedRegex(@"^\[(?:.*?)\] \[Server thread/INFO\]: (.*?)$", RegexOptions.NonBacktracking)]
|
[GeneratedRegex(@"^\[(?:.*?)\] \[Server thread/INFO\](?:.*?): (.*?)$", RegexOptions.NonBacktracking)]
|
||||||
private static partial Regex ServerThreadInfoRegex();
|
private static partial Regex ServerThreadInfoRegex();
|
||||||
|
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
@ -32,18 +32,18 @@ sealed partial class BackupServerCommandDispatcher : IDisposable {
|
|||||||
|
|
||||||
public async Task DisableAutomaticSaving() {
|
public async Task DisableAutomaticSaving() {
|
||||||
await process.SendCommand(MinecraftCommand.SaveOff, cancellationToken);
|
await process.SendCommand(MinecraftCommand.SaveOff, cancellationToken);
|
||||||
await automaticSavingDisabled.Task.WaitAsync(cancellationToken);
|
await automaticSavingDisabled.Task.WaitAsync(TimeSpan.FromSeconds(30), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SaveAllChunks() {
|
public async Task SaveAllChunks() {
|
||||||
// TODO Try if not flushing and waiting a few seconds before flushing reduces lag.
|
// TODO Try if not flushing and waiting a few seconds before flushing reduces lag.
|
||||||
await process.SendCommand(MinecraftCommand.SaveAll(flush: true), cancellationToken);
|
await process.SendCommand(MinecraftCommand.SaveAll(flush: true), cancellationToken);
|
||||||
await savedTheGame.Task.WaitAsync(cancellationToken);
|
await savedTheGame.Task.WaitAsync(TimeSpan.FromMinutes(1), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EnableAutomaticSaving() {
|
public async Task EnableAutomaticSaving() {
|
||||||
await process.SendCommand(MinecraftCommand.SaveOn, cancellationToken);
|
await process.SendCommand(MinecraftCommand.SaveOn, cancellationToken);
|
||||||
await automaticSavingEnabled.Task.WaitAsync(cancellationToken);
|
await automaticSavingEnabled.Task.WaitAsync(TimeSpan.FromMinutes(1), cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnOutput(object? sender, string? line) {
|
private void OnOutput(object? sender, string? line) {
|
||||||
|
@ -102,6 +102,7 @@ sealed class InstanceManagerActor : ReceiveActor<InstanceManagerActor.ICommand>
|
|||||||
IServerLauncher launcher = configuration.MinecraftServerKind switch {
|
IServerLauncher launcher = configuration.MinecraftServerKind switch {
|
||||||
MinecraftServerKind.Vanilla => new VanillaLauncher(properties),
|
MinecraftServerKind.Vanilla => new VanillaLauncher(properties),
|
||||||
MinecraftServerKind.Fabric => new FabricLauncher(properties),
|
MinecraftServerKind.Fabric => new FabricLauncher(properties),
|
||||||
|
MinecraftServerKind.Forge => new ForgeLauncher(properties),
|
||||||
_ => InvalidLauncher.Instance
|
_ => InvalidLauncher.Instance
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
namespace Phantom.Common.Data.Backups;
|
namespace Phantom.Common.Data.Backups;
|
||||||
|
|
||||||
public enum BackupCreationResultKind : byte {
|
public enum BackupCreationResultKind : byte {
|
||||||
UnknownError,
|
UnknownError = 0,
|
||||||
Success,
|
Success = 1,
|
||||||
InstanceNotRunning,
|
InstanceNotRunning = 2,
|
||||||
BackupCancelled,
|
BackupTimedOut = 3,
|
||||||
BackupAlreadyRunning,
|
BackupCancelled = 4,
|
||||||
BackupFileAlreadyExists,
|
BackupAlreadyRunning = 5,
|
||||||
CouldNotCreateBackupFolder,
|
BackupFileAlreadyExists = 6,
|
||||||
CouldNotCopyWorldToTemporaryFolder,
|
CouldNotCreateBackupFolder = 7,
|
||||||
CouldNotCreateWorldArchive
|
CouldNotCopyWorldToTemporaryFolder = 8,
|
||||||
|
CouldNotCreateWorldArchive = 9
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BackupCreationResultSummaryExtensions {
|
public static class BackupCreationResultSummaryExtensions {
|
||||||
|
@ -2,5 +2,6 @@
|
|||||||
|
|
||||||
public enum MinecraftServerKind : ushort {
|
public enum MinecraftServerKind : ushort {
|
||||||
Vanilla = 1,
|
Vanilla = 1,
|
||||||
Fabric = 2
|
Fabric = 2,
|
||||||
|
Forge = 3
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user