Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e25294db16 | ||
|
|
a8d86e0c48 | ||
|
|
3da1135202 |
@@ -54,6 +54,11 @@ jobs:
|
||||
# если в настройках инстанса права такого токена урезаны.
|
||||
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
DEFAULT_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Команду установки из описания релиза копируют люди, поэтому в ней
|
||||
# нужен внешний адрес. GITHUB_SERVER_URL для этого не годится: внутри
|
||||
# Actions он указывает на адрес, по которому Gitea видна runner'у, а
|
||||
# это обычно внутренний IP. Переопределяется переменной репозитория.
|
||||
PUBLIC_URL: ${{ vars.PUBLIC_URL }}
|
||||
run: |
|
||||
set -eu
|
||||
apt-get update -qq && apt-get install -y -qq jq
|
||||
@@ -77,8 +82,9 @@ jobs:
|
||||
CHANGES="$(git log --no-merges --pretty=format:'- %s')"
|
||||
fi
|
||||
|
||||
NOTES="$(printf '## Установка\n\n```bash\ncurl -fsSL %s/%s/raw/branch/main/deploy/get.sh | sudo bash\n```\n\nОбновление — та же команда: конфиг, миры и учётные записи не трогаются.\n\n## Изменения\n\n%s\n' \
|
||||
"${GITHUB_SERVER_URL}" "${GITHUB_REPOSITORY}" "${CHANGES}")"
|
||||
PUBLIC="${PUBLIC_URL:-https://gitea.hsrv.site}"
|
||||
NOTES="$(printf '## Установка\n\n```bash\ncurl -fsSL %s/%s/raw/branch/main/deploy/get.sh | sudo bash\n```\n\nОбновление — та же команда или кнопка в панели: конфиг, миры и учётные записи не трогаются.\n\n## Изменения\n\n%s\n' \
|
||||
"${PUBLIC%/}" "${GITHUB_REPOSITORY}" "${CHANGES}")"
|
||||
|
||||
PAYLOAD="$(jq -n --arg tag "$TAG" --arg body "$NOTES" \
|
||||
'{tag_name: $tag, name: $tag, body: $body, draft: false, prerelease: false}')"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# PZ Manager
|
||||
|
||||
[](https://gitea.hsrv.site/mrleo1nid/pzmanager/releases/latest)
|
||||
[](LICENSE)
|
||||
[](https://go.dev/)
|
||||
[](https://ubuntu.com/)
|
||||
@@ -89,23 +90,25 @@ curl -fsSL https://gitea.hsrv.site/mrleo1nid/pzmanager/raw/branch/main/deploy/ge
|
||||
|
||||
Дальше:
|
||||
|
||||
1. Посмотрите код первичной настройки:
|
||||
|
||||
```bash
|
||||
journalctl -u pzmanager -n 30 --no-pager
|
||||
```
|
||||
|
||||
2. Откройте панель в браузере и создайте администратора, введя этот код.
|
||||
Если панель слушает localhost, пробросьте порт:
|
||||
1. Откройте панель в браузере и создайте администратора, введя код первичной
|
||||
настройки — установщик печатает его последним сообщением. Если панель
|
||||
слушает localhost, пробросьте порт:
|
||||
|
||||
```bash
|
||||
ssh -L 8080:127.0.0.1:8080 пользователь@сервер
|
||||
```
|
||||
|
||||
3. Во вкладке «Обзор» нажмите **Установить / обновить через SteamCMD** и
|
||||
Код одноразовый и перестаёт работать сразу после создания администратора.
|
||||
Если вывод установщика потерялся, код есть в журнале:
|
||||
|
||||
```bash
|
||||
journalctl -u pzmanager -n 30 --no-pager
|
||||
```
|
||||
|
||||
2. Во вкладке «Обзор» нажмите **Установить / обновить через SteamCMD** и
|
||||
дождитесь окончания — прогресс виден во вкладке «Консоль».
|
||||
|
||||
4. Запустите сервер. При первом запуске PZ создаст `Zomboid/Server/*.ini` —
|
||||
3. Запустите сервер. При первом запуске PZ создаст `Zomboid/Server/*.ini` —
|
||||
после этого станут доступны вкладки «Конфиг сервера», «Песочница» и «Моды».
|
||||
|
||||
Порты, которые нужно открыть:
|
||||
@@ -131,6 +134,32 @@ make build-linux
|
||||
sudo PZ_LISTEN=10.10.1.142:8080 ./deploy/install.sh
|
||||
```
|
||||
|
||||
### Удаление
|
||||
|
||||
Убрать панель, оставив миры и настройки:
|
||||
|
||||
```bash
|
||||
sudo /opt/pzmanager/install.sh --uninstall
|
||||
```
|
||||
|
||||
Удалить всё вместе с мирами, бэкапами и учётными записями:
|
||||
|
||||
```bash
|
||||
sudo /opt/pzmanager/install.sh --uninstall --purge
|
||||
```
|
||||
|
||||
`--purge` спрашивает подтверждение; в неинтерактивном запуске нужен ещё и
|
||||
`--yes`. Каталог сносится, только если похож на установку панели — иначе
|
||||
опечатка в `PZ_HOME` стоила бы чужих файлов.
|
||||
|
||||
Установщик кладёт свою копию в `/opt/pzmanager/install.sh`, так что для
|
||||
удаления ничего скачивать не нужно. Если копии нет, те же аргументы принимает
|
||||
и установочная команда:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://gitea.hsrv.site/mrleo1nid/pzmanager/raw/branch/main/deploy/get.sh | sudo bash -s -- --uninstall --purge
|
||||
```
|
||||
|
||||
## Моды
|
||||
|
||||
Project Zomboid хранит моды в двух строках конфига: `WorkshopItems` — что
|
||||
|
||||
+21
-11
@@ -131,24 +131,34 @@ func serve(cfg *config.Config, users *auth.Store, secureCookies bool) error {
|
||||
// Пока учёток нет, создать первого администратора можно только с этим
|
||||
// кодом — иначе панель захватит любой, кто откроет её первым.
|
||||
setupToken := ""
|
||||
setupTokenFile := filepath.Join(cfg.DataDir, "setup-token")
|
||||
if users.IsEmpty() {
|
||||
setupToken = randomToken()
|
||||
// Код кладём и в файл: установщик читает его оттуда и показывает сразу
|
||||
// после установки, не заставляя идти в журнал.
|
||||
if err := os.WriteFile(setupTokenFile, []byte(setupToken+"\n"), 0o600); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "не удалось записать %s: %v\n", setupTokenFile, err)
|
||||
}
|
||||
fmt.Printf("\n Панель ещё не настроена.\n"+
|
||||
" Откройте её в браузере и введите код первичной настройки:\n\n %s\n\n", setupToken)
|
||||
} else {
|
||||
// Панель уже настроена: файл мог остаться от прошлой установки.
|
||||
os.Remove(setupTokenFile)
|
||||
}
|
||||
|
||||
apiServer := api.New(api.Options{
|
||||
Version: version,
|
||||
Config: cfg,
|
||||
Users: users,
|
||||
Supervisor: supervisor,
|
||||
Jobs: jobs,
|
||||
Backups: backups,
|
||||
Steam: steam,
|
||||
Static: static,
|
||||
SecureCookies: secureCookies,
|
||||
SetupToken: setupToken,
|
||||
Repo: repoURL(),
|
||||
Version: version,
|
||||
Config: cfg,
|
||||
Users: users,
|
||||
Supervisor: supervisor,
|
||||
Jobs: jobs,
|
||||
Backups: backups,
|
||||
Steam: steam,
|
||||
Static: static,
|
||||
SecureCookies: secureCookies,
|
||||
SetupToken: setupToken,
|
||||
SetupTokenFile: setupTokenFile,
|
||||
Repo: repoURL(),
|
||||
})
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
+41
-9
@@ -7,6 +7,15 @@
|
||||
#
|
||||
# curl -fsSL .../get.sh | sudo PZ_LISTEN=10.10.1.142:8080 bash
|
||||
#
|
||||
# Удаление (аргументы уходят установщику как есть):
|
||||
#
|
||||
# curl -fsSL .../get.sh | sudo bash -s -- --uninstall
|
||||
# curl -fsSL .../get.sh | sudo bash -s -- --uninstall --purge
|
||||
#
|
||||
# Если панель уже установлена, то же самое умеет её локальная копия:
|
||||
#
|
||||
# sudo /opt/pzmanager/install.sh --uninstall --purge
|
||||
#
|
||||
# Переменные окружения:
|
||||
# PZ_VERSION какой тег ставить (по умолчанию последний релиз)
|
||||
# PZ_HOME куда ставить (по умолчанию /opt/pzmanager)
|
||||
@@ -29,6 +38,19 @@ die() { echo "Ошибка: $*" >&2; exit 1; }
|
||||
|
||||
[[ $EUID -eq 0 ]] || die "запустите с правами root (sudo)"
|
||||
|
||||
# Аргументы уходят установщику. Для удаления бинарник качать незачем — это
|
||||
# лишние восемь мегабайт ради скрипта, который его же и сотрёт.
|
||||
ARGS=("$@")
|
||||
NEED_BINARY=1
|
||||
# Идиома ${ARGS[@]+...} нужна из-за set -u: обычная "${ARGS[@]:-}" на пустом
|
||||
# массиве разворачивается в один пустой аргумент, и установщик спотыкается о
|
||||
# него при обычной установке.
|
||||
for arg in ${ARGS[@]+"${ARGS[@]}"}; do
|
||||
case "$arg" in
|
||||
--uninstall | --remove | --purge) NEED_BINARY=0 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
for tool in curl sha256sum; do
|
||||
command -v "$tool" >/dev/null 2>&1 || die "не найдена утилита $tool"
|
||||
done
|
||||
@@ -68,10 +90,13 @@ asset_url() {
|
||||
}
|
||||
|
||||
BIN_NAME="pzmanager-linux-${ARCH}"
|
||||
BIN_URL="$(asset_url "$BIN_NAME")"
|
||||
[[ -n "$BIN_URL" ]] || die "в релизе ${TAG} нет файла ${BIN_NAME}"
|
||||
|
||||
echo "==> Ставлю ${TAG} (${ARCH})"
|
||||
if [[ "$NEED_BINARY" == "1" ]]; then
|
||||
BIN_URL="$(asset_url "$BIN_NAME")"
|
||||
[[ -n "$BIN_URL" ]] || die "в релизе ${TAG} нет файла ${BIN_NAME}"
|
||||
echo "==> Ставлю ${TAG} (${ARCH})"
|
||||
else
|
||||
echo "==> Беру установщик из ${TAG} для удаления"
|
||||
fi
|
||||
|
||||
TMP="$(mktemp -d)"
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
@@ -91,13 +116,17 @@ download() {
|
||||
curl -fsSL -o "$name" "$url" || die "не удалось скачать ${name}"
|
||||
}
|
||||
|
||||
download "$BIN_NAME"
|
||||
download install.sh
|
||||
download pzmanager.service
|
||||
FILES=(install.sh pzmanager.service)
|
||||
|
||||
if [[ "$NEED_BINARY" == "1" ]]; then
|
||||
download "$BIN_NAME"
|
||||
FILES+=("$BIN_NAME")
|
||||
fi
|
||||
|
||||
# Скрипт привилегированных действий появился не сразу: со старым релизом
|
||||
# ставим без него, панель просто не покажет кнопку обновления.
|
||||
FILES=("$BIN_NAME" install.sh pzmanager.service)
|
||||
if download pzmanager-admin.sh optional; then
|
||||
FILES+=(pzmanager-admin.sh)
|
||||
fi
|
||||
@@ -120,8 +149,11 @@ mv install.sh pzmanager.service deploy/
|
||||
if [[ -f pzmanager-admin.sh ]]; then
|
||||
mv pzmanager-admin.sh deploy/
|
||||
fi
|
||||
mv "$BIN_NAME" pzmanager
|
||||
chmod +x pzmanager deploy/install.sh
|
||||
chmod +x deploy/install.sh
|
||||
if [[ "$NEED_BINARY" == "1" ]]; then
|
||||
mv "$BIN_NAME" pzmanager
|
||||
chmod +x pzmanager
|
||||
fi
|
||||
|
||||
echo "==> Запускаю установщик"
|
||||
BINARY="$TMP/pzmanager" bash deploy/install.sh
|
||||
BINARY="$TMP/pzmanager" bash deploy/install.sh ${ARGS[@]+"${ARGS[@]}"}
|
||||
|
||||
+125
-9
@@ -1,10 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
# Установка и обновление pzmanager на Ubuntu/Debian. Запускать от root:
|
||||
# Установка, обновление и удаление pzmanager на Ubuntu/Debian. От root:
|
||||
#
|
||||
# sudo ./deploy/install.sh
|
||||
# sudo ./deploy/install.sh установить или обновить
|
||||
# sudo ./deploy/install.sh --uninstall убрать панель, данные оставить
|
||||
# sudo ./deploy/install.sh --uninstall --purge убрать вместе с мирами
|
||||
#
|
||||
# Скрипт идемпотентен: на уже настроенной машине он обновляет бинарник и
|
||||
# юнит, не трогая конфиг, миры и учётные записи панели.
|
||||
# Установка идемпотентна: на уже настроенной машине обновляются бинарник и
|
||||
# юнит, а конфиг, миры и учётные записи панели остаются нетронутыми.
|
||||
#
|
||||
# Переменные окружения:
|
||||
# PZ_HOME куда ставить всё хозяйство (по умолчанию /opt/pzmanager)
|
||||
@@ -29,11 +31,94 @@ ADMIN_SRC="${SCRIPT_DIR}/pzmanager-admin.sh"
|
||||
TARGET_BINARY=/usr/local/bin/pzmanager
|
||||
ADMIN_BINARY=/usr/local/bin/pzmanager-admin
|
||||
|
||||
UNINSTALL=0
|
||||
PURGE=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--uninstall | --remove) UNINSTALL=1 ;;
|
||||
--purge) UNINSTALL=1; PURGE=1 ;;
|
||||
--yes | -y) PZ_ASSUME_YES=1 ;;
|
||||
-h | --help)
|
||||
sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Неизвестный аргумент: $arg" >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
echo "Запустите скрипт от root: sudo $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# uninstall снимает панель с машины. Данные (миры, бэкапы, учётки) удаляются
|
||||
# только по --purge: потерять сохранения из-за неудачно набранной команды
|
||||
# гораздо обиднее, чем лишний раз убрать каталог руками.
|
||||
uninstall() {
|
||||
echo "==> Удаляю pzmanager"
|
||||
|
||||
if systemctl list-unit-files pzmanager.service &>/dev/null &&
|
||||
systemctl is-active --quiet pzmanager; then
|
||||
echo "==> Останавливаю службу (игровой сервер завершится штатно, это небыстро)"
|
||||
systemctl stop pzmanager || true
|
||||
fi
|
||||
systemctl disable --quiet pzmanager 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/pzmanager.service
|
||||
systemctl daemon-reload
|
||||
systemctl reset-failed pzmanager 2>/dev/null || true
|
||||
|
||||
rm -f /usr/local/bin/pzmanager /usr/local/bin/pzmanager-admin /etc/sudoers.d/pzmanager
|
||||
echo "Служба, бинарники и правило sudo удалены."
|
||||
|
||||
if [[ "$PURGE" != "1" ]]; then
|
||||
echo
|
||||
echo "Данные остались в ${PZ_HOME} (миры, бэкапы, конфиг, учётные записи)."
|
||||
echo "Удалить и их: sudo $0 --uninstall --purge"
|
||||
return
|
||||
fi
|
||||
|
||||
# Защита от опечатки в PZ_HOME: сносим только то, что похоже на нашу
|
||||
# установку, и никогда — корень или домашние каталоги.
|
||||
local home_clean="${PZ_HOME%/}"
|
||||
if [[ -z "$home_clean" || "$home_clean" == "/" || "$home_clean" != /* ]]; then
|
||||
echo "!! PZ_HOME=${PZ_HOME} не похож на каталог установки — не трогаю" >&2
|
||||
return
|
||||
fi
|
||||
if [[ ! -e "$home_clean/config.yaml" && ! -d "$home_clean/data" ]]; then
|
||||
echo "!! В ${home_clean} нет ни config.yaml, ни data/ — не похоже на установку pzmanager," >&2
|
||||
echo " поэтому каталог оставлен нетронутым." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "${PZ_ASSUME_YES:-0}" != "1" ]]; then
|
||||
echo
|
||||
echo "Будет безвозвратно удалено: ${home_clean}"
|
||||
echo "Это миры, бэкапы, конфиг и учётные записи панели."
|
||||
if [[ -t 0 ]]; then
|
||||
read -r -p "Введите YES для подтверждения: " answer
|
||||
[[ "$answer" == "YES" ]] || { echo "Отменено."; return; }
|
||||
else
|
||||
echo "Запуск неинтерактивный — повторите с флагом --yes, если уверены." >&2
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf "$home_clean"
|
||||
if id "$PZ_USER" &>/dev/null; then
|
||||
deluser --system "$PZ_USER" &>/dev/null || userdel "$PZ_USER" &>/dev/null || true
|
||||
echo "Пользователь ${PZ_USER} удалён."
|
||||
fi
|
||||
echo "Удалено полностью: ${home_clean}"
|
||||
}
|
||||
|
||||
if [[ "$UNINSTALL" == "1" ]]; then
|
||||
uninstall
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ ! -f "$BINARY" ]]; then
|
||||
echo "Не найден бинарник $BINARY. Соберите его: make build-linux" >&2
|
||||
exit 1
|
||||
@@ -152,6 +237,14 @@ else
|
||||
echo "!! $ADMIN_SRC не найден или нет sudo — обновление из панели будет недоступно" >&2
|
||||
fi
|
||||
|
||||
# Кладём сам установщик рядом с данными: удалить или переустановить панель
|
||||
# можно будет одной локальной командой, без похода в репозиторий.
|
||||
install -m 0755 "$0" "$PZ_HOME/install.sh"
|
||||
if [[ -f "$ADMIN_SRC" ]]; then
|
||||
install -m 0755 "$ADMIN_SRC" "$PZ_HOME/pzmanager-admin.sh"
|
||||
fi
|
||||
install -m 0644 "$UNIT_SRC" "$PZ_HOME/pzmanager.service"
|
||||
|
||||
echo "==> Ставлю systemd-юнит"
|
||||
sed -e "s|/opt/pzmanager|${PZ_HOME}|g" \
|
||||
-e "s|User=pzserver|User=${PZ_USER}|" \
|
||||
@@ -178,8 +271,21 @@ if [[ "$MODE" == "update" ]]; then
|
||||
fi
|
||||
|
||||
systemctl start pzmanager
|
||||
# Дадим сервису секунду подняться, чтобы код настройки успел попасть в журнал.
|
||||
sleep 2
|
||||
|
||||
# Панель кладёт код первичной настройки в файл, как только поднимется. Ждём
|
||||
# его, чтобы показать код прямо здесь: иначе за ним пришлось бы идти в журнал.
|
||||
SETUP_TOKEN=""
|
||||
TOKEN_FILE="$PZ_HOME/data/setup-token"
|
||||
for _ in $(seq 1 20); do
|
||||
if [[ -s "$TOKEN_FILE" ]]; then
|
||||
SETUP_TOKEN="$(head -1 "$TOKEN_FILE")"
|
||||
break
|
||||
fi
|
||||
if ! systemctl is-active --quiet pzmanager; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Готово. Панель запущена и слушает ${PZ_LISTEN}."
|
||||
@@ -198,8 +304,18 @@ else
|
||||
echo " sudo ufw allow ${PORT}/tcp"
|
||||
echo
|
||||
fi
|
||||
echo "Код первичной настройки — в журнале:"
|
||||
echo
|
||||
echo " journalctl -u pzmanager -n 30 --no-pager"
|
||||
if [[ -n "$SETUP_TOKEN" ]]; then
|
||||
echo "Код первичной настройки (введите его в браузере):"
|
||||
echo
|
||||
echo " ${SETUP_TOKEN}"
|
||||
echo
|
||||
echo "Код одноразовый: после создания администратора он перестаёт работать."
|
||||
else
|
||||
echo "Код первичной настройки не удалось прочитать. Посмотрите журнал:"
|
||||
echo
|
||||
echo " journalctl -u pzmanager -n 30 --no-pager"
|
||||
fi
|
||||
echo
|
||||
echo "Игровые порты сервера: udp/16261 и udp/16262."
|
||||
echo
|
||||
echo "Удалить панель целиком: sudo ${PZ_HOME}/install.sh --uninstall --purge"
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/mrleo1nid/pzmanager/internal/auth"
|
||||
@@ -55,6 +56,10 @@ func (s *Server) handleSetup(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
// Администратор создан — код больше не нужен и не должен лежать на диске.
|
||||
if s.setupTokenFile != "" {
|
||||
os.Remove(s.setupTokenFile)
|
||||
}
|
||||
s.setSessionCookie(w, id, sessionTTL)
|
||||
writeJSON(w, http.StatusOK, map[string]any{"authenticated": true, "login": creds.Login})
|
||||
}
|
||||
|
||||
+20
-13
@@ -40,8 +40,11 @@ type Server struct {
|
||||
// secureCookies включает флаг Secure у cookie сессии (панель за HTTPS).
|
||||
secureCookies bool
|
||||
// setupToken защищает первичное создание администратора: менеджер печатает
|
||||
// его в журнал при старте, когда учёток ещё нет.
|
||||
// его при старте, когда учёток ещё нет.
|
||||
setupToken string
|
||||
// setupTokenFile — копия кода на диске, которую показывает установщик.
|
||||
// После создания администратора файл больше не нужен.
|
||||
setupTokenFile string
|
||||
}
|
||||
|
||||
// Options — то, что нужно собрать серверу API.
|
||||
@@ -57,6 +60,9 @@ type Options struct {
|
||||
Static fs.FS
|
||||
SecureCookies bool
|
||||
SetupToken string
|
||||
// SetupTokenFile — файл с кодом первичной настройки, удаляется после
|
||||
// создания администратора.
|
||||
SetupTokenFile string
|
||||
// Repo — репозиторий, из которого панель берёт обновления.
|
||||
Repo string
|
||||
}
|
||||
@@ -64,18 +70,19 @@ type Options struct {
|
||||
// New собирает HTTP-обработчик панели.
|
||||
func New(o Options) *Server {
|
||||
return &Server{
|
||||
version: o.Version,
|
||||
cfg: o.Config,
|
||||
users: o.Users,
|
||||
sup: o.Supervisor,
|
||||
jobs: o.Jobs,
|
||||
backups: o.Backups,
|
||||
steam: o.Steam,
|
||||
workshop: pzconfig.NewWorkshopClient(),
|
||||
updater: updater.New(o.Repo, o.Version),
|
||||
static: o.Static,
|
||||
secureCookies: o.SecureCookies,
|
||||
setupToken: o.SetupToken,
|
||||
version: o.Version,
|
||||
cfg: o.Config,
|
||||
users: o.Users,
|
||||
sup: o.Supervisor,
|
||||
jobs: o.Jobs,
|
||||
backups: o.Backups,
|
||||
steam: o.Steam,
|
||||
workshop: pzconfig.NewWorkshopClient(),
|
||||
updater: updater.New(o.Repo, o.Version),
|
||||
static: o.Static,
|
||||
secureCookies: o.SecureCookies,
|
||||
setupToken: o.SetupToken,
|
||||
setupTokenFile: o.SetupTokenFile,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user