Files
PzConfigStudio/pz_config/writers.py
2025-12-26 18:10:39 +08:00

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)