Настройки сервера и песочницы разложены по разделам
CI / test (push) Successful in 21s
Release / release (push) Successful in 26s

Полторы сотни параметров сплошным списком читать невозможно. Теперь они
разбиты на разделы — «Основное», «PVP и урон», «Убежища», «Античит» и так
далее, — свёрнутые по умолчанию, кроме первого. Поиск раскрывает разделы с
совпадениями и прячет остальные, а раскрытые разделы не схлопываются при
возврате на вкладку.

Категории составлены по настоящим конфигам Build 41 и 42: все 144 ключа
.ini и 270 параметров песочницы раскладываются без остатка. Нумерованные
и однотипные ключи (AntiCheatProtectionType1..24, *Loot, Animal*, Firearm*)
подхватываются по префиксу, а незнакомые попадают в «Прочее» — в новых
версиях игры ключи добавляют, и терять их со страницы нельзя.

Описания параметров панель больше не выдумывает, а берёт из самого
конфига: игра пишет их комментариями на языке сервера. Полный текст — во
всплывающей подсказке, начало — под полем; поиск ищет и по описанию, так
что параметр можно найти по-русски.

Заодно исправлено сохранение файлов с виндовыми переводами строк: панель
переписывала их в LF, и правка одного параметра меняла каждую строку
файла. Проверено на реальном SandboxVars.lua: правка одного значения
меняет ровно одну строку, размер файла не меняется.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-05 03:07:59 +03:00
co-authored by Claude Opus 5
parent 4a346c4ed9
commit 5d50b609f6
8 changed files with 503 additions and 20 deletions
+48 -4
View File
@@ -16,6 +16,10 @@ type iniLine struct {
Key string
Value string
Raw string
// Comment — описание параметра: строки комментария прямо перед ним.
// Project Zomboid пишет их на языке сервера, так что панели есть что
// показать человеку, не выдумывая своих формулировок.
Comment string
}
// INI — конфиг PZ в виде плоских key=value. Разбор сохраняет исходный порядок
@@ -23,22 +27,46 @@ type iniLine struct {
type INI struct {
lines []iniLine
index map[string]int
// crlf — файл был с виндовыми переводами строк. Сохраняем как было: иначе
// правка одного параметра переписывает весь файл целиком.
crlf bool
}
// ParseINI разбирает содержимое конфига.
func ParseINI(data []byte) *INI {
ini := &INI{index: make(map[string]int)}
text := strings.ReplaceAll(string(data), "\r\n", "\n")
raw := string(data)
ini.crlf = strings.Contains(raw, "\r\n")
text := strings.ReplaceAll(raw, "\r\n", "\n")
// Комментарии копим до ближайшего параметра: в конфигах PZ описание стоит
// строкой выше. Пустая строка обрывает связь — иначе описание прилипло бы
// к следующему блоку.
var comment []string
for _, raw := range strings.Split(text, "\n") {
trimmed := strings.TrimSpace(raw)
key, value, found := strings.Cut(raw, "=")
if !found || trimmed == "" || strings.HasPrefix(trimmed, "#") {
if strings.HasPrefix(trimmed, "#") {
comment = append(comment, strings.TrimSpace(strings.TrimPrefix(trimmed, "#")))
ini.lines = append(ini.lines, iniLine{Raw: raw})
continue
}
if !found || trimmed == "" {
comment = nil
ini.lines = append(ini.lines, iniLine{Raw: raw})
continue
}
key = strings.TrimSpace(key)
ini.index[key] = len(ini.lines)
ini.lines = append(ini.lines, iniLine{Key: key, Value: strings.TrimSpace(value)})
ini.lines = append(ini.lines, iniLine{
Key: key,
Value: strings.TrimSpace(value),
Comment: strings.Join(comment, " "),
})
comment = nil
}
return ini
}
@@ -90,6 +118,17 @@ func (i *INI) Keys() []string {
return out
}
// Comments возвращает описания параметров: ключ -> текст комментария.
func (i *INI) Comments() map[string]string {
out := make(map[string]string, len(i.index))
for _, l := range i.lines {
if l.Key != "" && l.Comment != "" {
out[l.Key] = l.Comment
}
}
return out
}
// Map отдаёт все параметры в виде словаря.
func (i *INI) Map() map[string]string {
out := make(map[string]string, len(i.index))
@@ -103,6 +142,11 @@ func (i *INI) Map() map[string]string {
// Render собирает файл обратно в текст.
func (i *INI) Render() []byte {
newline := "\n"
if i.crlf {
newline = "\r\n"
}
var buf bytes.Buffer
for n, l := range i.lines {
if l.Key == "" {
@@ -113,7 +157,7 @@ func (i *INI) Render() []byte {
buf.WriteString(l.Value)
}
if n < len(i.lines)-1 {
buf.WriteByte('\n')
buf.WriteString(newline)
}
}
return buf.Bytes()