Профили серверов: несколько миров с раздельными настройками

Профиль — это отдельный сервер: свой мир, .ini, песочница, набор модов и
лимит памяти JVM. Project Zomboid различает их по -servername, поэтому
файлы профилей не пересекаются. Работает всегда один профиль: серверные
файлы, игровые порты и файл запуска JVM общие, так что переключение
разрешено только на остановленном сервере.

- config: список профилей вместо одиночных server_name/admin_password/
  java_memory; старые поля переносятся в первый профиль при загрузке;
- supervisor: запускает активный профиль и выставляет его -Xmx на каждом
  старте, потому что файл запуска общий;
- бэкапы: архив снимается с одного профиля (мир + его конфиги), имя
  профиля попадает в имя файла, ротация считается по профилям;
- API профилей: список, создание с копированием настроек из другого
  профиля, правка, удаление и переключение активного;
- панель: селектор профиля в шапке и вкладка со списком профилей.

Удаление профиля убирает его только из панели: мир и конфиги остаются на
диске, чтобы случайное нажатие не стоило сохранений.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 00:27:12 +03:00
co-authored by Claude Opus 5
parent c384d60416
commit 277ab7af4a
13 changed files with 1317 additions and 183 deletions
+49 -1
View File
@@ -46,6 +46,11 @@
<span id="status-text"></span>
</div>
<label class="profile-picker">
<span>Профиль</span>
<select id="profile-select" title="Профиль сервера: свой мир, конфиг и моды"></select>
</label>
<div class="controls">
<button class="btn btn-start" id="btn-start">Запустить</button>
<button class="btn btn-stop" id="btn-stop">Остановить</button>
@@ -70,6 +75,7 @@
<button class="tab" data-tab="sandbox">Песочница</button>
<button class="tab" data-tab="mods">Моды</button>
<button class="tab" data-tab="backups">Бэкапы</button>
<button class="tab" data-tab="profiles">Профили</button>
<button class="tab" data-tab="settings">Настройки</button>
</nav>
@@ -81,6 +87,7 @@
<div class="card">
<h3>Состояние</h3>
<div class="stat" id="ov-state"></div>
<div class="muted" id="ov-profile"></div>
<div class="muted" id="ov-uptime"></div>
<div class="muted" id="ov-pid"></div>
<div class="muted error" id="ov-lastexit"></div>
@@ -201,6 +208,7 @@
<div>
<h2>Резервные копии</h2>
<p class="muted small" id="backup-dir"></p>
<p class="muted small">Бэкап снимается с активного профиля: его мир и конфиги.</p>
</div>
<form id="backup-form">
<input type="text" id="backup-note" placeholder="Пометка (необязательно)" class="input-sm">
@@ -208,11 +216,51 @@
</form>
</div>
<table class="table">
<thead><tr><th>Архив</th><th>Размер</th><th>Создан</th><th></th></tr></thead>
<thead><tr><th>Архив</th><th>Профиль</th><th>Размер</th><th>Создан</th><th></th></tr></thead>
<tbody id="backup-rows"></tbody>
</table>
</section>
<!-- Профили -->
<section class="panel" data-panel="profiles">
<div class="panel-head">
<div>
<h2>Профили серверов</h2>
<p class="muted small">У каждого профиля свой мир, конфиг, песочница и набор модов.
Одновременно работает один — переключать можно на остановленном сервере.</p>
</div>
</div>
<div id="profile-cards" class="cards"></div>
<h3>Новый профиль</h3>
<form id="profile-add-form" class="fields">
<div class="cfg-field">
<label for="new-profile-id">Идентификатор</label>
<input type="text" id="new-profile-id" placeholder="modded" autocomplete="off">
<div class="hint">Латиница, цифры, дефис. Станет именем конфига и папки мира.</div>
</div>
<div class="cfg-field">
<label for="new-profile-title">Название</label>
<input type="text" id="new-profile-title" placeholder="Сборка с модами" autocomplete="off">
<div class="hint">Как профиль подписан в панели.</div>
</div>
<div class="cfg-field">
<label for="new-profile-memory">Память JVM</label>
<input type="text" id="new-profile-memory" placeholder="8g" autocomplete="off">
<div class="hint">Применяется при запуске этого профиля.</div>
</div>
<div class="cfg-field">
<label for="new-profile-copy">Скопировать настройки из</label>
<select id="new-profile-copy"></select>
<div class="hint">Копирует .ini и настройки песочницы. Мир останется новым.</div>
</div>
<div class="cfg-field">
<button class="btn btn-primary" type="submit">Создать профиль</button>
</div>
</form>
</section>
<!-- Настройки -->
<section class="panel" data-panel="settings">
<h2>Настройки менеджера</h2>