Mr_panica
XenForo one 💖
- Сообщения
- 942
- Реакции
- 458
Способ проверен только частично, потому что уже не помню как точно делал, кто будет делать потом напишите если работает корректно.
Делайте на свой страх и риск, но на чистую VPS можно спокойно ставить.
Этот гайд скорее для того что бы понять сам принцип, после его написания я бы и сам бы не захотел ему следовать
Этот способ позволит экономить огромное количество места на вашем VDS.
По стандарту в Pterodactyl при создании нового сервера он качается полностью. Все 20-25 ГБ файлов и сделать итоговый вес около 5-10 МБ (чистый сервер)
В основном это звуки и текстуры.
Но ведь они одинаковы у всех серверов и меняются только при обновлении серверов.
В панели Pterodactyl есть способ создавать ссылки на файлы, то есть сервер будет видеть ссылку на файл, пойдёт по пути и будет использовать файл по ссылке.
Называется способ Mount (Using Mounts | Pterodactyl)
Я буду показывать на примере сервера для игры Team Fortress 2.
Имея скромную VDS на 100ГБ с этим способом она без проблем вмещает 8 игровых сервреров + Fast-DL + сайт с форумом + остаётся ещё 25-30ГБ свободного места для обновления сервера.
В этом способе обновляется только главный сервер.
По идеи вам никто не мешает сделать маунты SourceMod или карт, звуков, моделей, если они у вас одинаковые везде.
Возможно можно сделать FastDL (но без сжатия bz2)
Плюсы:
-Освобождение места на VDS.
-Быстрое обновление (обновляется только один сервер, а не все)
-Потенциальная автоматизация.
-Меньше нагрузки на VDS.
Минусы:
-Потенциальные проблемы (с TF2 вроде за +-полгода не было, но всё же)
-При обновлении сервера могут крашатсся (обновление занимает 5-10 мин)
-Несовершенство метода (делал сам так что на свой страх и риск)
*Возможно можно сделать чтобы mount был из контейнера в контейнер, но я не нашёл такого способа, хотя в интернете была информация что так можно сделать.
В данной реализации mount идёт из системы Linux VDS, а не контейнера от Pterodactyl.
Тут будет смешанное руководство через консоль SSH и графического SFTP клиента.
Использовал:
SFTP клиент: WinSCP
SSH клиент: Termius
OS: Ubuntu 24
1. Создание папки для целого сервера.
В директории /var/lib/pterodactyl создайте папку mounts (если её нет)
Тут будет находиться папка с сервером.
Создайте папку с любым названием, там будет полный сервер, у меня называется tf2_full, итоговый путь: /var/lib/pterodactyl/mounts/tf2_full
2. Установка SteamCMD (Если нет)
Гайд от ИИ (т.к уже у меня установлена)
Второй способ: Через пакетный менеджер:
*Тут SteamCMD должен установиться по пути /usr/games/steamcmd
AppID для dedicated-сервера Team Fortress 2 — 232250.
Пример команд в SteamCMD:
Заходим в SteamCMD:
Внутри SteamCMD:
В панели Pterodactyl нужно создать API Ключи для управления серверами:
Настройка находится по пути domen.ru/account/api или в панели в вашем профиле вкладка API Credentials.
Создаём новый ключ и записываем его.
Создание файла автообновления сервера:
Будем создавать скрипт по пути: /usr/local/bin
Например название: ptero_tf2_update.sh
Содержание:
Скрипт будет обновлять сервер если для него будет обновления, при начале и окончании обновления будет присылать сообщения в ДС.
*Обязательно редактируйте данные в скрипте на свои*
Теперь нужно сделать так чтобы скрипт периодически запускался и смотрел есть ли обновления, для этого сделаем крон:
Пишем в консоле VDS:
У вас откроется файлик, на последнюю пустую строчку пропишите: */3 * * * * /usr/local/bin/ptero_tf2_update.sh
Каждые 3 минуты будет запускаться скрипт для проверки есть ли обновления.
Потом нужно закрыть режим редактирования crontab, он предложит сохранить.
У меня это комбинации:
Ctrl + x - закрытие режима редактирования.
Затем он предложит сохранить - нажимаете y (именно английскую)
Затем нажимаете enter.
Должен написать:
crontab: installing new crontab
Можете повторно зайти в режим редактирования и убедиться что там есть новая запись.
И так, мы наконец-то добрались до основной темы гайда...
Создаём необходимые маунты тут: /admin/mounts
Эмпирическим путём (тыканием пальца) выяснил что как минимум эти маунты рабочие:
Везде Read Only: true, кроме base_steam, там false (но можете попробовать и true поставить)
Вики Pterodactyl говорит что нельзя в target писать часть пути home/container, но хз, без этого не работало.
При создании Mount указываете свою ноду и яйцо сервера.
Затем нужно разрешить директорию маунтов в кфг Pterodacty, файл: /etc/pterodactyl, внизу файла, должно получится как-то так:
Затем в установленном сервере в панели Pterodactyl маунтите все Mount (нажимаете на зелёные плюсики)
Изменения вступят в силу после перезагрузки.
Особенность Mount, файлы которые замаунчены видит только сам игровой сервер (контейнер), если мотреть через консоль VDS, то будет показывать что просто пустая папка.
Теперь нужно создать скрипт для автоудаления необходимых оригинальных файлов на игровом сервере:
Например у меня это скрипт /usr/local/bin/optimize_container.sh
Потом запускаем скрипт через SSH VDS:
/usr/local/bin/optimize_container.sh <ID сервера> (Именно ID, а не UID контейнера)
Смотреть ID тут:
Для данного примера: /usr/local/bin/optimize_container.sh 20
Далее самые спорные места, 100% можно сделать лучше:
*Сервер должен быть включён
Заходим в оболочку контейнера игрового сервера:
docker exec -it <UUID сервера> /bin/sh, пример:
Если всё ок:
Пропишите в консоль:
Необходимые ссылки создались.
В параметры запуска сервера можно прописать +sv_auto_update_enabled 0 для отключения автообновления, хотя в интернете разнится информация как отключать автообновление у серверов.
Перезагружаете сервер и надеетесь что всё работает)
Конечно лучше на пустом сервере проверять сначала или сделать бэкап...
Еб*нулся ли я? Наверное...
Делайте на свой страх и риск, но на чистую VPS можно спокойно ставить.
Этот гайд скорее для того что бы понять сам принцип, после его написания я бы и сам бы не захотел ему следовать
Этот способ позволит экономить огромное количество места на вашем VDS.
По стандарту в Pterodactyl при создании нового сервера он качается полностью. Все 20-25 ГБ файлов и сделать итоговый вес около 5-10 МБ (чистый сервер)
Но ведь они одинаковы у всех серверов и меняются только при обновлении серверов.
В панели Pterodactyl есть способ создавать ссылки на файлы, то есть сервер будет видеть ссылку на файл, пойдёт по пути и будет использовать файл по ссылке.
Называется способ Mount (Using Mounts | Pterodactyl)
Я буду показывать на примере сервера для игры Team Fortress 2.
Имея скромную VDS на 100ГБ с этим способом она без проблем вмещает 8 игровых сервреров + Fast-DL + сайт с форумом + остаётся ещё 25-30ГБ свободного места для обновления сервера.
В этом способе обновляется только главный сервер.
По идеи вам никто не мешает сделать маунты SourceMod или карт, звуков, моделей, если они у вас одинаковые везде.
Возможно можно сделать FastDL (но без сжатия bz2)
Плюсы:
-Освобождение места на VDS.
-Быстрое обновление (обновляется только один сервер, а не все)
-Потенциальная автоматизация.
-Меньше нагрузки на VDS.
Минусы:
-Потенциальные проблемы (с TF2 вроде за +-полгода не было, но всё же)
-При обновлении сервера могут крашатсся (обновление занимает 5-10 мин)
-Несовершенство метода (делал сам так что на свой страх и риск)
*Возможно можно сделать чтобы mount был из контейнера в контейнер, но я не нашёл такого способа, хотя в интернете была информация что так можно сделать.
В данной реализации mount идёт из системы Linux VDS, а не контейнера от Pterodactyl.
Тут будет смешанное руководство через консоль SSH и графического SFTP клиента.
Использовал:
SFTP клиент: WinSCP
SSH клиент: Termius
OS: Ubuntu 24
1. Создание папки для целого сервера.
В директории /var/lib/pterodactyl создайте папку mounts (если её нет)
Тут будет находиться папка с сервером.
Создайте папку с любым названием, там будет полный сервер, у меня называется tf2_full, итоговый путь: /var/lib/pterodactyl/mounts/tf2_full
2. Установка SteamCMD (Если нет)
Гайд от ИИ (т.к уже у меня установлена)
Рекомендуемый способ: Ручная установка (работает стабильно)
- Создайте отдельного пользователя для безопасности(не запускайте сервер от root):
Bash:sudo adduser --gecos "" steam sudo passwd steam # Установите пароль sudo usermod -aG sudo steam # Опционально, для удобства
- Перейдите в домашнюю директорию пользователя steam:
su - steam
- Создайте директорию для SteamCMD и перейдите в неё:
Bash:mkdir ~/steamcmd cd ~/steamcmd
- Скачайте и распакуйте SteamCMD:
Bash:wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz tar -xvzf steamcmd_linux.tar.gz
./steamcmd.shВторой способ: Через пакетный менеджер:
*Тут SteamCMD должен установиться по пути /usr/games/steamcmd
Bash:
sudo add-apt-repository multiverse
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install steamcmd
Установка и обновление сервера TF2
AppID для dedicated-сервера Team Fortress 2 — 232250.
Пример команд в SteamCMD:
Заходим в SteamCMD:
./steamcmd.shВнутри SteamCMD:
Код:
login anonymous # Анонимный логин для публичных серверов
force_install_dir /var/lib/pterodactyl/mounts/tf2_full # Укажите путь к директории сервера
app_update 232250 validate # Установка/обновление с проверкой файлов
quit
В панели Pterodactyl нужно создать API Ключи для управления серверами:
Настройка находится по пути domen.ru/account/api или в панели в вашем профиле вкладка API Credentials.
Создаём новый ключ и записываем его.
Создание файла автообновления сервера:
Будем создавать скрипт по пути: /usr/local/bin
Например название: ptero_tf2_update.sh
Содержание:
C-подобный:
#!/bin/bash
set -euo pipefail
# === Конфигурация ===
STEAMCMD="/usr/games/steamcmd" #Путь до SteamCMD
APP_ID=232250 #AppID сервера в Steam
MOUNT_PATH="/var/lib/pterodactyl/mounts/tf2_full" #Путь до полного сервера игры
LOCKFILE="/tmp/tf2full_update.lock" #Файл лока чтобы не дёргать часто
PANEL_API_KEY="ptlc_B1NddTOiQPxsaXYUr17x6AzdsPeDiT48lGCcZ" #API ключ клиента панели для взаимодействия с серверами (перезагрузки)
PANEL_HOST="https://sub.domain.ru" #Домен где установлена панель
# === Вебхуки ===
DISCORD_WEBHOOK_URL="https://discordapp.com/api/webhooks/1398526936280996935/M2HqbU231aon99Vp0-3M90sd2XmtQ5kh1G0xds40pWiwhLhc0JsdfJzDKwnKkGPblWd_e5dC" #WebHook для системных сообщений в дискорд канале об обновлениях (для вас)
SECOND_WEBHOOK_URL="https://discord.com/api/webhooks/14264049923404414854/2jWssdxehTmHUPrtoe4sdfNXhjDGIOiaUVdsfsdAdsf7P27CootWLCL5sdfDiENKlJyltY60" #WebHook для системных сообщений в дискорд канале об обновлениях (для всех)
# === Утилиты ===
send_embed() {
local title="$1" desc="$2" color="${3:-16776960}"
local payload=$(cat <<EOF
{"embeds":[{"title":"$title","description":"$desc","color":$color,"timestamp":"$(date -Iseconds)"}]}
EOF
)
curl -s -H "Content-Type: application/json" -X POST -d "$payload" "$DISCORD_WEBHOOK_URL" >/dev/null
}
send_plain_to_second() {
local content="$1"
local payload=$(cat <<EOF
{"content":"$content"}
EOF
)
curl -s -H "Content-Type: application/json" -X POST -d "$payload" "$SECOND_WEBHOOK_URL" >/dev/null
}
get_remote_buildid() {
"$STEAMCMD" +login anonymous +app_info_update 1 \
+app_info_print "$APP_ID" +quit 2>/dev/null \
| awk '/"buildid"/ { gsub(/"/,""); print $2; exit }'
}
get_local_buildid() {
local acf="$MOUNT_PATH/steamapps/appmanifest_${APP_ID}.acf"
[[ -f "$acf" ]] && awk -F'"' '/"buildid"/ { print $4; exit }' "$acf" || echo "0"
}
api_curl() {
curl -sk -H "Authorization: Bearer $PANEL_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/vnd.pterodactyl.v1+json" "$@"
}
# === Логика ===
exec 200>"$LOCKFILE"
flock -n 200 || { echo "🔒 Уже работает"; exit 1; }
local=$(get_local_buildid)
remote=$local;
remote=$(get_remote_buildid)
# ✅ ПРОВЕРКА: удалённый buildid должен быть непустым числом
if [[ -z "$remote" || ! "$remote" =~ ^[0-9]+$ ]]; then
echo "❌ Не удалось получить корректный удалённый buildid"
send_embed "❌ Ошибка обновления TF2" "Не удалось получить корректный удалённый buildid из SteamCMD." 16711680
exit 1
fi
if [[ "$remote" == "$local" ]]; then
echo "✔ Уже актуально ($local)"
exit 0
fi
# === Уведомление о наличии обновления ===
send_embed "⚙️ Обнаружено обновление TF2" "🔹 Текущая версия: **$local**\n🔹 Новая версия: **$remote**\nНачинаю обновление..." 16776960
send_plain_to_second "⚙️ Обнаружено обновление TF2\nТекущая: **$local** → Новая: **$remote**\nToday at $(date +"%H:%M")"
# === Обновление с проверкой и ретраями (до 3 попыток) ===
tmpf=$(mktemp)
cat >"$tmpf" <<EOF
@ShutdownOnFailedCommand 1
@NoPromptForPassword 1
force_install_dir "$MOUNT_PATH"
login anonymous
app_update $APP_ID
quit
EOF
attempt=1
max_attempts=3
updated_ok=0
while (( attempt <= max_attempts )); do
echo "⏬ Запуск app_update (попытка $attempt/$max_attempts)…"
"$STEAMCMD" +runscript "$tmpf" || true
new_local=$(get_local_buildid)
echo "🔎 Проверка: локальный buildid=$new_local, ожидаем $remote"
if [[ -n "$new_local" && "$new_local" != "0" && "$new_local" == "$remote" ]]; then
echo "✅ Обновление успешно на попытке $attempt"
updated_ok=1
break
fi
if (( attempt < max_attempts )); then
send_embed "🔁 Повтор обновления TF2" "После попытки $attempt buildid=$new_local, ожидали $remote. Пробую ещё раз." 16776960
sleep 5
fi
((attempt++))
done
rm -f "$tmpf"
if (( updated_ok == 0 )); then
echo "❌ Обновление не удалось после $max_attempts попыток (buildid=$new_local, ожидали $remote)."
send_embed "❌ Обновление не удалось" "После $max_attempts попыток: buildid=$new_local, ожидали $remote.\nРестарты отменены." 16711680
exit 1
fi
# === Очистка карт ===
find "$MOUNT_PATH/tf/maps" -type f -name "*.bsp" -delete || true
# === Перезапуск всех серверов ===
avail=$(api_curl "$PANEL_HOST/api/client")
mapfile -t uuids < <(jq -r '.data[].attributes.uuid' <<<"$avail")
inf_src="$MOUNT_PATH/tf/steam.inf"
for uuid in "${uuids[@]}"; do
vol="/var/lib/pterodactyl/volumes/$uuid"
inf_dest="$vol/tf/steam.inf"
[[ -f "$inf_src" ]] && cp "$inf_src" "$inf_dest" || continue
api_curl -X POST "$PANEL_HOST/api/client/servers/$uuid/power" \
-d '{"signal":"restart"}' >/dev/null || {
send_embed "⚠️ Ошибка" "Не удалось перезапустить сервер **$uuid**" 16711680
continue
}
send_embed "🔄 Сервер перезапущен" "$uuid обновлён до **$remote**" 3066993
done
# === Финальное уведомление ===
send_embed "✅ Обновление завершено" "🎉 Все сервера успешно перезапущены." 5814783
send_plain_to_second "✅ Обновление завершено\n🎉 Все сервера перезапущены.\nToday at $(date +"%H:%M")"
Скрипт будет обновлять сервер если для него будет обновления, при начале и окончании обновления будет присылать сообщения в ДС.
*Обязательно редактируйте данные в скрипте на свои*
Теперь нужно сделать так чтобы скрипт периодически запускался и смотрел есть ли обновления, для этого сделаем крон:
Пишем в консоле VDS:
crontab -eУ вас откроется файлик, на последнюю пустую строчку пропишите: */3 * * * * /usr/local/bin/ptero_tf2_update.sh
Каждые 3 минуты будет запускаться скрипт для проверки есть ли обновления.
Потом нужно закрыть режим редактирования crontab, он предложит сохранить.
У меня это комбинации:
Ctrl + x - закрытие режима редактирования.
Затем он предложит сохранить - нажимаете y (именно английскую)
Затем нажимаете enter.
Должен написать:
crontab: installing new crontab
Можете повторно зайти в режим редактирования и убедиться что там есть новая запись.
И так, мы наконец-то добрались до основной темы гайда...
Создаём необходимые маунты тут: /admin/mounts
Эмпирическим путём (тыканием пальца) выяснил что как минимум эти маунты рабочие:
Name: base_hl2
Source: /var/lib/pterodactyl/mounts/tf2_full/hl2
Target: /home/container/hl2
Name: base_platform
Source: /var/lib/pterodactyl/mounts/tf2_full/platform
Target: /home/container/platform
Name: base_bin
Source: /var/lib/pterodactyl/mounts/tf2_full/bin
Target: /home/container/bin
Name: tf_base_tf_files
Source: /var/lib/pterodactyl/mounts/tf2_full/tf
Target: /home/container/tf/base_tf_files
Name: tf_bin
Source: /var/lib/pterodactyl/mounts/tf2_full/tf/bin
Target: /home/container/tf/bin
Name: tf_resource
Source: /var/lib/pterodactyl/mounts/tf2_full/tf/resource
Target: /home/container/tf/resource
Name: tf_scripts
Source: /var/lib/pterodactyl/mounts/tf2_full/tf/scripts
Target: /home/container/tf/scripts
Name: base_steam
Source: /var/lib/pterodactyl/mounts/tf2_full/.steam
Target: /home/container/.steam
Name: base_steamcmd
Source: /var/lib/pterodactyl/mounts/tf2_full/steamcmd
Target: /home/container/steamcmd
Name: base_steamapps
Source: /var/lib/pterodactyl/mounts/tf2_full/steamapps
Target: /home/container/steamapps
Source: /var/lib/pterodactyl/mounts/tf2_full/hl2
Target: /home/container/hl2
Name: base_platform
Source: /var/lib/pterodactyl/mounts/tf2_full/platform
Target: /home/container/platform
Name: base_bin
Source: /var/lib/pterodactyl/mounts/tf2_full/bin
Target: /home/container/bin
Name: tf_base_tf_files
Source: /var/lib/pterodactyl/mounts/tf2_full/tf
Target: /home/container/tf/base_tf_files
Name: tf_bin
Source: /var/lib/pterodactyl/mounts/tf2_full/tf/bin
Target: /home/container/tf/bin
Name: tf_resource
Source: /var/lib/pterodactyl/mounts/tf2_full/tf/resource
Target: /home/container/tf/resource
Name: tf_scripts
Source: /var/lib/pterodactyl/mounts/tf2_full/tf/scripts
Target: /home/container/tf/scripts
Name: base_steam
Source: /var/lib/pterodactyl/mounts/tf2_full/.steam
Target: /home/container/.steam
Name: base_steamcmd
Source: /var/lib/pterodactyl/mounts/tf2_full/steamcmd
Target: /home/container/steamcmd
Name: base_steamapps
Source: /var/lib/pterodactyl/mounts/tf2_full/steamapps
Target: /home/container/steamapps
Вики Pterodactyl говорит что нельзя в target писать часть пути home/container, но хз, без этого не работало.
При создании Mount указываете свою ноду и яйцо сервера.
Затем нужно разрешить директорию маунтов в кфг Pterodacty, файл: /etc/pterodactyl, внизу файла, должно получится как-то так:
YAML:
allowed_mounts:
- /var/lib/pterodactyl/mounts
allowed_origins: []
Затем в установленном сервере в панели Pterodactyl маунтите все Mount (нажимаете на зелёные плюсики)
Изменения вступят в силу после перезагрузки.
Особенность Mount, файлы которые замаунчены видит только сам игровой сервер (контейнер), если мотреть через консоль VDS, то будет показывать что просто пустая папка.
Теперь нужно создать скрипт для автоудаления необходимых оригинальных файлов на игровом сервере:
Например у меня это скрипт /usr/local/bin/optimize_container.sh
Код:
#!/bin/bash
set -euo pipefail
PANEL_API_KEY="ptlc_B1NddTOiQPxsaXYUr17x6AzdsPeDiT48lGCcZ" #API ключ клиента панели для взаимодействия с серверами (перезагрузки)
PANEL_HOST="https://sub.domain.ru" #Домен где установлена панель
VOLUMES_PATH="/var/lib/pterodactyl/volumes"
if [ $# -ne 1 ]; then
echo "Использование: $0 <SERVER_ID>"
exit 1
fi
SERVER_ID="$1"
echo "[*] Получаю данные сервера ID $SERVER_ID..."
SERVER_DATA=$(curl -s -H "Authorization: Bearer $PANEL_API_KEY" \
-H "Accept: application/vnd.pterodactyl.v1+json" \
"$PANEL_HOST/api/application/servers/$SERVER_ID")
UUID=$(echo "$SERVER_DATA" | jq -r '.attributes.uuid')
CONTAINER_PATH="$VOLUMES_PATH/$UUID"
if [[ -z "$UUID" || "$UUID" == "null" || ! -d "$CONTAINER_PATH" ]]; then
echo "❌ Сервер или контейнер не найден."
exit 1
fi
echo "[+] UUID: $UUID"
echo "[+] Путь к контейнеру: $CONTAINER_PATH"
echo "[*] Удаление старых файлов и директорий..."
rm -rf \
"$CONTAINER_PATH/.steam" \
"$CONTAINER_PATH/bin" \
"$CONTAINER_PATH/hl2" \
"$CONTAINER_PATH/platform" \
"$CONTAINER_PATH/steamapps" \
"$CONTAINER_PATH/steamcmd" \
"$CONTAINER_PATH/tf/bin" \
"$CONTAINER_PATH/tf/platform" \
"$CONTAINER_PATH/tf/resource" \
"$CONTAINER_PATH/tf/scripts" \
"$CONTAINER_PATH/tf/tf2_misc_"*.vpk \
"$CONTAINER_PATH/tf/tf2_misc_dir.vpk" \
"$CONTAINER_PATH/tf/tf2_sound_misc.vpk.sound.cache" \
"$CONTAINER_PATH/tf/tf2_sound_misc_dir.vpk" \
"$CONTAINER_PATH/tf/tf2_sound_vo_english.vpk.sound.cache" \
"$CONTAINER_PATH/tf/tf2_sound_vo_english_dir.vpk" \
"$CONTAINER_PATH/tf/tf2_textures_"*.vpk \
"$CONTAINER_PATH/tf/tf2_textures_dir.vpk"
echo "[+] Удаление завершено."
Потом запускаем скрипт через SSH VDS:
/usr/local/bin/optimize_container.sh <ID сервера> (Именно ID, а не UID контейнера)
Смотреть ID тут:
Для данного примера: /usr/local/bin/optimize_container.sh 20
Далее самые спорные места, 100% можно сделать лучше:
*Сервер должен быть включён
Заходим в оболочку контейнера игрового сервера:
docker exec -it <UUID сервера> /bin/sh, пример:
docker exec -it d10cb34f-3f5c-4e99-ad8a-cf68b4088deb /bin/shЕсли всё ок:
Пропишите в консоль:
Bash:
link_base_tf_files() {
LINK_SRC="tf/base_tf_files"
LINK_DST="tf"
echo "📎 [LINKER] Начинаю связывание файлов..."
echo "📂 Исходник: $LINK_SRC"
echo "📂 Цель: $LINK_DST"
if [ ! -d "$LINK_SRC" ]; then
echo "❌ Каталог не найден: $LINK_SRC"
return
fi
count=0
for file in "$LINK_SRC"/*.vpk "$LINK_SRC"/*.cache "$LINK_SRC"/*.manifest; do
[ -e "$file" ] || continue
basefile=$(basename "$file")
target="$LINK_DST/$basefile"
[ -L "$target" ] && [ "$(readlink "$target")" = "../$file" ] && continue
[ -e "$target" ] && echo "⚠️ Удаляю: $basefile" && rm -f "$target"
ln -s "../$file" "$target"
echo "🔗 Связано: $basefile"
count=$((count+1))
done
echo "✅ [LINKER] Всего создано ссылок: $count"
}
link_base_tf_files
Необходимые ссылки создались.
В параметры запуска сервера можно прописать +sv_auto_update_enabled 0 для отключения автообновления, хотя в интернете разнится информация как отключать автообновление у серверов.
Перезагружаете сервер и надеетесь что всё работает)
Конечно лучше на пустом сервере проверять сначала или сделать бэкап...
Еб*нулся ли я? Наверное...
Вложения
Последнее редактирование: