1
0
mirror of https://github.com/chylex/Minecraft-Phantom-Panel.git synced 2025-05-07 18:34:03 +02:00

Make writing server.properties file asynchronous

This commit is contained in:
chylex 2023-03-05 13:30:18 +01:00
parent 9d9734d1fd
commit 3f976295bd
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
4 changed files with 100 additions and 22 deletions

View File

@ -0,0 +1,92 @@
using System.Text;
using Kajabity.Tools.Java;
namespace Phantom.Agent.Minecraft.Java;
sealed class JavaPropertiesFileEditor {
private static readonly Encoding Encoding = Encoding.GetEncoding("ISO-8859-1");
private readonly Dictionary<string, string> overriddenProperties = new ();
public void Set(string key, string value) {
overriddenProperties[key] = value;
}
public async Task EditOrCreate(string filePath) {
if (File.Exists(filePath)) {
string tmpFilePath = filePath + ".tmp";
File.Copy(filePath, tmpFilePath, overwrite: true);
await EditFromCopyOrCreate(filePath, tmpFilePath);
File.Move(tmpFilePath, filePath, overwrite: true);
}
else {
await EditFromCopyOrCreate(null, filePath);
}
}
private async Task EditFromCopyOrCreate(string? sourceFilePath, string targetFilePath) {
var properties = new JavaProperties();
if (sourceFilePath != null) {
// TODO replace with custom async parser
await using var sourceStream = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
properties.Load(sourceStream, Encoding);
}
foreach (var (key, value) in overriddenProperties) {
properties[key] = value;
}
await using var targetStream = new FileStream(targetFilePath, FileMode.Create, FileAccess.Write, FileShare.Read);
await using var targetWriter = new StreamWriter(targetStream, Encoding);
await targetWriter.WriteLineAsync("# Properties");
foreach (var (key, value) in properties) {
await WriteProperty(targetWriter, key, value);
}
}
private static async Task WriteProperty(StreamWriter writer, string key, string value) {
await WritePropertyComponent(writer, key, escapeSpaces: true);
await writer.WriteAsync('=');
await WritePropertyComponent(writer, value, escapeSpaces: false);
await writer.WriteLineAsync();
}
private static async Task WritePropertyComponent(TextWriter writer, string component, bool escapeSpaces) {
for (int index = 0; index < component.Length; index++) {
var c = component[index];
switch (c) {
case '\\':
case '#':
case '!':
case '=':
case ':':
case ' ' when escapeSpaces || index == 0:
await writer.WriteAsync('\\');
await writer.WriteAsync(c);
break;
case var _ when c > 31 && c < 127:
await writer.WriteAsync(c);
break;
case '\t':
await writer.WriteAsync("\\t");
break;
case '\n':
await writer.WriteAsync("\\n");
break;
case '\r':
await writer.WriteAsync("\\r");
break;
case '\f':
await writer.WriteAsync("\\f");
break;
default:
await writer.WriteAsync("\\u");
await writer.WriteAsync(((int) c).ToString("X4"));
break;
}
}
}
}

View File

@ -1,5 +1,4 @@
using System.Text;
using Kajabity.Tools.Java;
using Phantom.Agent.Minecraft.Instance;
using Phantom.Agent.Minecraft.Java;
using Phantom.Agent.Minecraft.Server;
@ -108,21 +107,8 @@ public abstract class BaseLauncher : IServerLauncher {
}
private static async Task UpdateServerProperties(InstanceProperties instanceProperties) {
var serverPropertiesFilePath = Path.Combine(instanceProperties.InstanceFolder, "server.properties");
var serverPropertiesData = new JavaProperties();
await using var fileStream = new FileStream(serverPropertiesFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
try {
serverPropertiesData.Load(fileStream);
} catch (ParseException e) {
throw new Exception("Could not parse server.properties file: " + serverPropertiesFilePath, e);
}
instanceProperties.ServerProperties.SetTo(serverPropertiesData);
fileStream.Seek(0L, SeekOrigin.Begin);
fileStream.SetLength(0L);
serverPropertiesData.Store(fileStream, true);
var serverPropertiesEditor = new JavaPropertiesFileEditor();
instanceProperties.ServerProperties.SetTo(serverPropertiesEditor);
await serverPropertiesEditor.EditOrCreate(Path.Combine(instanceProperties.InstanceFolder, "server.properties"));
}
}

View File

@ -1,4 +1,4 @@
using Kajabity.Tools.Java;
using Phantom.Agent.Minecraft.Java;
namespace Phantom.Agent.Minecraft.Properties;
@ -12,7 +12,7 @@ abstract class MinecraftServerProperty<T> {
protected abstract T Read(string value);
protected abstract string Write(T value);
public void Set(JavaProperties properties, T value) {
properties.SetProperty(key, Write(value));
public void Set(JavaPropertiesFileEditor properties, T value) {
properties.Set(key, Write(value));
}
}

View File

@ -1,4 +1,4 @@
using Kajabity.Tools.Java;
using Phantom.Agent.Minecraft.Java;
namespace Phantom.Agent.Minecraft.Properties;
@ -7,7 +7,7 @@ public sealed record ServerProperties(
ushort RconPort,
bool EnableRcon = true
) {
internal void SetTo(JavaProperties properties) {
internal void SetTo(JavaPropertiesFileEditor properties) {
MinecraftServerProperties.ServerPort.Set(properties, ServerPort);
MinecraftServerProperties.RconPort.Set(properties, RconPort);
MinecraftServerProperties.EnableRcon.Set(properties, EnableRcon);