mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2024-11-24 22:42:53 +01:00
123 lines
4.5 KiB
C#
123 lines
4.5 KiB
C#
using System.Collections.ObjectModel;
|
|
using System.Text;
|
|
using Phantom.Agent.Minecraft.Instance;
|
|
using Phantom.Agent.Minecraft.Java;
|
|
using Phantom.Agent.Minecraft.Server;
|
|
using Phantom.Utils.Processes;
|
|
using Serilog;
|
|
|
|
namespace Phantom.Agent.Minecraft.Launcher;
|
|
|
|
public abstract class BaseLauncher : IServerLauncher {
|
|
private readonly InstanceProperties instanceProperties;
|
|
|
|
protected string MinecraftVersion => instanceProperties.ServerVersion;
|
|
protected string InstanceFolder => instanceProperties.InstanceFolder;
|
|
|
|
private protected BaseLauncher(InstanceProperties instanceProperties) {
|
|
this.instanceProperties = instanceProperties;
|
|
}
|
|
|
|
public async Task<LaunchResult> Launch(ILogger logger, LaunchServices services, EventHandler<DownloadProgressEventArgs> downloadProgressEventHandler, CancellationToken cancellationToken) {
|
|
if (!services.JavaRuntimeRepository.TryGetByGuid(instanceProperties.JavaRuntimeGuid, out var javaRuntimeExecutable)) {
|
|
return new LaunchResult.InvalidJavaRuntime();
|
|
}
|
|
|
|
var vanillaServerJarPath = await services.ServerExecutables.DownloadAndGetPath(instanceProperties.LaunchProperties.ServerDownloadInfo, MinecraftVersion, downloadProgressEventHandler, cancellationToken);
|
|
if (vanillaServerJarPath == null) {
|
|
return new LaunchResult.CouldNotDownloadMinecraftServer();
|
|
}
|
|
|
|
ServerJarInfo? serverJar;
|
|
try {
|
|
serverJar = await PrepareServerJar(logger, vanillaServerJarPath, cancellationToken);
|
|
} catch (OperationCanceledException) {
|
|
throw;
|
|
} catch (Exception e) {
|
|
logger.Error(e, "Caught exception while preparing the server jar.");
|
|
return new LaunchResult.CouldNotPrepareMinecraftServerLauncher();
|
|
}
|
|
|
|
if (!File.Exists(serverJar.FilePath)) {
|
|
logger.Error("Missing prepared server or launcher jar: {FilePath}", serverJar.FilePath);
|
|
return new LaunchResult.CouldNotPrepareMinecraftServerLauncher();
|
|
}
|
|
|
|
try {
|
|
await AcceptEula(instanceProperties);
|
|
await UpdateServerProperties(instanceProperties);
|
|
} catch (Exception e) {
|
|
logger.Error(e, "Caught exception while configuring the server.");
|
|
return new LaunchResult.CouldNotConfigureMinecraftServer();
|
|
}
|
|
|
|
var processConfigurator = new ProcessConfigurator {
|
|
FileName = javaRuntimeExecutable.ExecutablePath,
|
|
WorkingDirectory = InstanceFolder,
|
|
RedirectInput = true,
|
|
UseShellExecute = false
|
|
};
|
|
|
|
var processArguments = processConfigurator.ArgumentList;
|
|
PrepareJvmArguments(serverJar).Build(processArguments);
|
|
PrepareJavaProcessArguments(processArguments, serverJar.FilePath);
|
|
|
|
var process = processConfigurator.CreateProcess();
|
|
var instanceProcess = new InstanceProcess(instanceProperties, process);
|
|
|
|
try {
|
|
process.Start();
|
|
} catch (Exception launchException) {
|
|
logger.Error(launchException, "Caught exception launching the server process.");
|
|
|
|
try {
|
|
process.Kill();
|
|
} catch (Exception killException) {
|
|
logger.Error(killException, "Caught exception trying to kill the server process after a failed launch.");
|
|
}
|
|
|
|
return new LaunchResult.CouldNotStartMinecraftServer();
|
|
}
|
|
|
|
return new LaunchResult.Success(instanceProcess);
|
|
}
|
|
|
|
private JvmArgumentBuilder PrepareJvmArguments(ServerJarInfo serverJar) {
|
|
var builder = new JvmArgumentBuilder(instanceProperties.JvmProperties);
|
|
|
|
foreach (string argument in instanceProperties.JvmArguments) {
|
|
builder.Add(argument);
|
|
}
|
|
|
|
foreach (var argument in serverJar.ExtraArgs) {
|
|
builder.Add(argument);
|
|
}
|
|
|
|
CustomizeJvmArguments(builder);
|
|
return builder;
|
|
}
|
|
|
|
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) {
|
|
return Task.FromResult(new ServerJarInfo(serverJarPath));
|
|
}
|
|
|
|
private static async Task AcceptEula(InstanceProperties instanceProperties) {
|
|
var eulaFilePath = Path.Combine(instanceProperties.InstanceFolder, "eula.txt");
|
|
await File.WriteAllLinesAsync(eulaFilePath, new [] { "# EULA", "eula=true" }, Encoding.UTF8);
|
|
}
|
|
|
|
private static async Task UpdateServerProperties(InstanceProperties instanceProperties) {
|
|
var serverPropertiesEditor = new JavaPropertiesFileEditor();
|
|
instanceProperties.ServerProperties.SetTo(serverPropertiesEditor);
|
|
await serverPropertiesEditor.EditOrCreate(Path.Combine(instanceProperties.InstanceFolder, "server.properties"));
|
|
}
|
|
}
|