mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2025-05-29 01:34:04 +02:00
Make writing server.properties file asynchronous
This commit is contained in:
parent
9d9734d1fd
commit
3f976295bd
Agent/Phantom.Agent.Minecraft
Java
Launcher
Properties
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using Kajabity.Tools.Java;
|
|
||||||
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;
|
||||||
@ -108,21 +107,8 @@ public abstract class BaseLauncher : IServerLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static async Task UpdateServerProperties(InstanceProperties instanceProperties) {
|
private static async Task UpdateServerProperties(InstanceProperties instanceProperties) {
|
||||||
var serverPropertiesFilePath = Path.Combine(instanceProperties.InstanceFolder, "server.properties");
|
var serverPropertiesEditor = new JavaPropertiesFileEditor();
|
||||||
var serverPropertiesData = new JavaProperties();
|
instanceProperties.ServerProperties.SetTo(serverPropertiesEditor);
|
||||||
|
await serverPropertiesEditor.EditOrCreate(Path.Combine(instanceProperties.InstanceFolder, "server.properties"));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Kajabity.Tools.Java;
|
using Phantom.Agent.Minecraft.Java;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Properties;
|
namespace Phantom.Agent.Minecraft.Properties;
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ abstract class MinecraftServerProperty<T> {
|
|||||||
protected abstract T Read(string value);
|
protected abstract T Read(string value);
|
||||||
protected abstract string Write(T value);
|
protected abstract string Write(T value);
|
||||||
|
|
||||||
public void Set(JavaProperties properties, T value) {
|
public void Set(JavaPropertiesFileEditor properties, T value) {
|
||||||
properties.SetProperty(key, Write(value));
|
properties.Set(key, Write(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using Kajabity.Tools.Java;
|
using Phantom.Agent.Minecraft.Java;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Properties;
|
namespace Phantom.Agent.Minecraft.Properties;
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ public sealed record ServerProperties(
|
|||||||
ushort RconPort,
|
ushort RconPort,
|
||||||
bool EnableRcon = true
|
bool EnableRcon = true
|
||||||
) {
|
) {
|
||||||
internal void SetTo(JavaProperties properties) {
|
internal void SetTo(JavaPropertiesFileEditor properties) {
|
||||||
MinecraftServerProperties.ServerPort.Set(properties, ServerPort);
|
MinecraftServerProperties.ServerPort.Set(properties, ServerPort);
|
||||||
MinecraftServerProperties.RconPort.Set(properties, RconPort);
|
MinecraftServerProperties.RconPort.Set(properties, RconPort);
|
||||||
MinecraftServerProperties.EnableRcon.Set(properties, EnableRcon);
|
MinecraftServerProperties.EnableRcon.Set(properties, EnableRcon);
|
||||||
|
Loading…
Reference in New Issue
Block a user