88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Mapping
|
|
|
|
from .models import ParsedConfig, Setting
|
|
|
|
|
|
def _to_ini_value(setting: Setting, new_value: object) -> str:
|
|
if setting.value_type == "bool":
|
|
return "true" if bool(new_value) else "false"
|
|
return str(new_value)
|
|
|
|
|
|
def _lua_quote(value: str) -> str:
|
|
# Minimal Lua string escaping for double-quoted strings.
|
|
value = (
|
|
value.replace("\\", "\\\\")
|
|
.replace('"', '\\"')
|
|
.replace("\r", "\\r")
|
|
.replace("\n", "\\n")
|
|
.replace("\t", "\\t")
|
|
)
|
|
return f'"{value}"'
|
|
|
|
|
|
def _to_lua_value(setting: Setting, new_value: object) -> str:
|
|
if setting.value_type == "bool":
|
|
return "true" if bool(new_value) else "false"
|
|
if setting.value_type == "int":
|
|
return str(int(new_value))
|
|
if setting.value_type == "float":
|
|
# Keep a plain, readable float representation.
|
|
return str(float(new_value))
|
|
return _lua_quote(str(new_value))
|
|
|
|
|
|
def write_server_ini(parsed: ParsedConfig, updates: Mapping[str, object]) -> str:
|
|
if parsed.source != "ini":
|
|
raise ValueError("write_server_ini expects ParsedConfig(source='ini')")
|
|
|
|
lines = list(parsed.lines)
|
|
key_re = re.compile(r"^([A-Za-z0-9_]+)=(.*)$")
|
|
for setting in parsed.settings:
|
|
if setting.path not in updates:
|
|
continue
|
|
new_value = _to_ini_value(setting, updates[setting.path])
|
|
original = lines[setting.line_index]
|
|
line_no_nl = original.rstrip("\r\n")
|
|
newline = original[len(line_no_nl) :]
|
|
m = key_re.match(line_no_nl)
|
|
if not m:
|
|
continue
|
|
key = m.group(1)
|
|
lines[setting.line_index] = f"{key}={new_value}{newline}"
|
|
return "".join(lines)
|
|
|
|
|
|
def write_sandboxvars_lua(parsed: ParsedConfig, updates: Mapping[str, object]) -> str:
|
|
if parsed.source != "lua":
|
|
raise ValueError("write_sandboxvars_lua expects ParsedConfig(source='lua')")
|
|
|
|
lines = list(parsed.lines)
|
|
for setting in parsed.settings:
|
|
if setting.path not in updates:
|
|
continue
|
|
new_value = _to_lua_value(setting, updates[setting.path])
|
|
|
|
original = lines[setting.line_index]
|
|
line_no_nl = original.rstrip("\r\n")
|
|
newline = original[len(line_no_nl) :]
|
|
|
|
# Replace between '=' and the final comma.
|
|
eq_index = line_no_nl.find("=")
|
|
comma_index = line_no_nl.rfind(",")
|
|
if eq_index == -1 or comma_index == -1 or comma_index <= eq_index:
|
|
continue
|
|
|
|
prefix = line_no_nl[: eq_index + 1]
|
|
# Preserve at least one space after '=' for readability.
|
|
prefix = prefix.rstrip() + " "
|
|
# Keep original indentation + key as-is.
|
|
suffix = line_no_nl[comma_index:] + newline
|
|
lines[setting.line_index] = f"{prefix}{new_value}{suffix}"
|
|
|
|
return "".join(lines)
|
|
|