1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2026-03-01 05:07:53 +01:00

3 Commits

Author SHA1 Message Date
da206aacb2 wip status protocol 2026-02-23 04:05:44 +01:00
4ad9534d27 Merge Phantom.Agent.Minecraft project into Phantom.Agent.Services 2026-02-23 01:14:46 +01:00
2c63c1d7e0 Introduce instance launch recipes 2026-02-23 01:14:46 +01:00
3 changed files with 14 additions and 24 deletions

View File

@@ -13,7 +13,7 @@ static class MinecraftServerStatusProtocol {
await tcpClient.ConnectAsync(IPAddress.Loopback, serverPort, cancellationToken); await tcpClient.ConnectAsync(IPAddress.Loopback, serverPort, cancellationToken);
var tcpStream = tcpClient.GetStream(); var tcpStream = tcpClient.GetStream();
// https://wiki.vg/Server_List_Ping // https://minecraft.wiki/w/Java_Edition_protocol/Server_List_Ping
tcpStream.WriteByte(0xFE); tcpStream.WriteByte(0xFE);
await tcpStream.FlushAsync(cancellationToken); await tcpStream.FlushAsync(cancellationToken);

View File

@@ -26,7 +26,18 @@ sealed class InstanceLauncher(
} }
var stepExecutor = new StepExecutor(logger, downloadManager, pathResolver, reportStatus, cancellationToken); var stepExecutor = new StepExecutor(logger, downloadManager, pathResolver, reportStatus, cancellationToken);
if (!await RunPreparationSteps(logger, stepExecutor)) { var steps = launchRecipe.Preparation;
for (int stepIndex = 0; stepIndex < steps.Length; stepIndex++) {
var step = steps[stepIndex];
try {
if (await step.Run(stepExecutor)) {
continue;
}
} catch (Exception e) {
logger.Error(e, "Failed preparation step {StepIndex} out of {StepCount}: {StepName}", stepIndex, steps.Length, step.GetType().Name);
}
return new InstanceLaunchResult.CouldNotPrepareServerInstance(); return new InstanceLaunchResult.CouldNotPrepareServerInstance();
} }
@@ -69,27 +80,6 @@ sealed class InstanceLauncher(
return new InstanceLaunchResult.Success(instanceProcess); return new InstanceLaunchResult.Success(instanceProcess);
} }
private async Task<bool> RunPreparationSteps(ILogger logger, StepExecutor stepExecutor) {
var steps = launchRecipe.Preparation;
for (int stepIndex = 0; stepIndex < steps.Length; stepIndex++) {
var step = steps[stepIndex];
try {
if (await step.Run(stepExecutor)) {
continue;
}
} catch (OperationCanceledException) {
throw;
} catch (Exception e) {
logger.Error(e, "Failed preparation step {StepIndex} out of {StepCount}: {StepName}", stepIndex, steps.Length, step.GetType().Name);
}
return false;
}
return true;
}
private sealed class StepExecutor(ILogger logger, FileDownloadManager downloadManager, IInstancePathResolver pathResolver, Action<IInstanceStatus?> reportStatus, CancellationToken cancellationToken) : IInstanceLaunchStepExecutor<bool> { private sealed class StepExecutor(ILogger logger, FileDownloadManager downloadManager, IInstancePathResolver pathResolver, Action<IInstanceStatus?> reportStatus, CancellationToken cancellationToken) : IInstanceLaunchStepExecutor<bool> {
public async Task<bool> DownloadFile(FileDownloadInfo downloadInfo, IInstancePath path) { public async Task<bool> DownloadFile(FileDownloadInfo downloadInfo, IInstancePath path) {
string? filePath = path.Resolve(pathResolver); string? filePath = path.Resolve(pathResolver);

View File

@@ -61,7 +61,7 @@ sealed class InstancePlayerCountTracker : CancellableBackgroundTask {
try { try {
return await MinecraftServerStatusProtocol.GetPlayerCounts(serverPort, CancellationToken); return await MinecraftServerStatusProtocol.GetPlayerCounts(serverPort, CancellationToken);
} catch (MinecraftServerStatusProtocol.ProtocolException e) { } catch (MinecraftServerStatusProtocol.ProtocolException e) {
Logger.Error("{Message}", e.Message); Logger.Error("Could not check online player count due to protocol error: {Message}", e.Message);
return null; return null;
} catch (SocketException e) { } catch (SocketException e) {
bool waitingForServerStart = e.SocketErrorCode == SocketError.ConnectionRefused && WaitingForFirstDetection; bool waitingForServerStart = e.SocketErrorCode == SocketError.ConnectionRefused && WaitingForFirstDetection;