Поднимаем сервер для апдейтов Геймдаты SourceMod

Интересна ли Вам данная тема?

  • Да

    Голосов: 7 100.0%
  • Нет

    Голосов: 0 0.0%

  • Всего проголосовало
    7

Kruzya

Участник
Сообщения
12,970
Реакции
10,914
  • Команда форума
  • #1
Поднимаем сервер для апдейтов Геймдаты SourceMod

Введение, разбор принципа работы
Тема, на самом деле, довольно интересная. Нигде про это я не нашёл информации (даже в вики AlliedModders, что удивительно, ибо в конфигурации SourceMod (файл core.cfg) есть параметр, отвечающий за адрес сервера обновлений), а поднять сервер понадобилось по причине того, что на серверах так же используются некоторые геймдаты, которые по апдейтеру не приходят, но которые так же надо обновлять. И самый простой способ обновить гемйдату на всех серверах - поднять где-то у себя этот самый сервер обновлений, и обновлять геймдаты на нём.

ВНИМАНИЕ! Эта статья разделена на несколько отдельных. Так же, по возможности, кое-где будут проскакивать куски кода.
Полученный по итогам сервер обновлений будет выложен на всеобщее обозрение (ну, вдруг кому пригодится). Писаться он будет на ASP .NET Core, хотя можно обойтись и обычным PHP.
Все продолжения статьи будут поститься в этой же теме.
  1. Введение, разбор принципа работы (Вы здесь)
  2. Пишем простейший сервер обновлений, часть 1 (Скоро...)
  3. Пишем простейший сервер обновлений, часть ... (Скоро...)
  4. Пишем простейший сервер обновлений, часть Х (Скоро...)
    Оффтоп
  5. Тестирование результата (Скоро...)
  6. Итоги (Скоро...)

Если вручную обратиться по ссылке, которая видна в конфиге, через браузер, то веб-сервер нам возвращает ошибку, что не указана необходимая версия.
MVDDvZ1.png

Первое, что в голову лезет при получении такой ошибки - посмотреть, как собирает запрос расширение, и попытаться повторить его через любой удобный софт. Мне предпочтительнее Postman. Скачать его можно здесь.
И так, открываем на Гитхабе исходники Сурсмода, открываем папку с расширениями, и следуем в директорию расширения апдейтера. Нужный нам код располагается в файле Updater.cpp и начинается со строки 347.
Первое, что попадается на глаза - в каком параметре передаётся версия SourceMod.
PHP:
form->AddString("version", SOURCEMOD_VERSION);
В GET-параметры прописать не вышло. Открываем Postman, превращаем запрос в POST, добавляем поле "version" со значением версии SourceMod.
На заметку: Поэкспериментировав с этим полем, выяснилось, что версию надо писать полностью, но можно без билда: На 1.8 он вернёт ошибку, что версия не поддерживается, а вот с 1.8.0 он уже готов работать. Так же можно передать версию с билдом (через пробел, точку, или букву - значения не имеет). А ещё официальный сервер поддерживает минимум версию 1.6.0. На 1.5.0 уже возвращает ошибку о том, что необходимо обновиться.
Теперь сервер вернёт нам новую ошибку, что не передано кол-во файлов.
BuhxTQE.png

Продолжаем смотреть исходник, и видим вызов функции add_folders(), на которую передаётся:
  • Инстанс класса веб-формы с параметрами для запроса к серверу;
  • Имя корневой папки (фиксированная константа gamedata);
  • Ссылка на переменную типа unsigned int.
В самой функции идёт чтение содержимого папки. Формируются полные пути к полученному объекту, и дальше в зависимости от типа объекта выполняются действия. Если это файл, то вызывается ф-ия add_file() с аргументами:
  • Инстанс класса веб-формы с параметрами для запроса к серверу;
  • Имя файла;
  • Ссылка на переменную типа unsigned int.
Если папка, то всё та же функция add_folders().
С add_folders() разобрались. Посмотрим теперь под капот add_file(). А там всё проще.
  1. Генерируется полный путь к файлу относительно папки Сурсмода.
  2. Вычисляется хэш-сумма файла MD5.
  3. Если не удалось, возвращается false.
  4. В форму добавляются поля file_%d_name и file_%d_md5, где
    • %d - значение третьей переменной num_files;
    • Первое поле - путь к файлу относительно папки Сурсмода (gamedata/gamedata/sm-cstrike.games/game.css.txt);
    • Второе поле - MD5 хэш-сумма файла (cd671d538573abf2e8e61cb1c84f7f6e).
  5. Значение третьего аргумента инкрементится (увеличивается на 1).
  6. Возвращается true.

После первого вызова add_folders(), добавляется поле files со значением аргумента, ссылка на который передавалась третьим аргументом (т.е., num_files). И запрос уходит с последующим парсингом.
Следующая часть нам пока что не интересна. Попробуем добавить поле files со значением 0. Чисто для эксперимента.
LwQ8IxX.png

И получаем ответ от сервера с изменившимися файлами (в нашем случае - с файлами, которых у нас "нет").
JosRYMT.png

А теперь, на основе информации, которую мы выдрали из исходника апдейтера, попробуем добавить два файла в запрос, будто они у нас есть. Я для теста возьму первые два файла из ответа. Не забываем редактировать значение поля files.
jA8wtkw.png

Отправляем запрос. И тестовые файлы, которые мы указали, пропадают из ответа.
NDJlWlG.png
Теперь у нас есть примерные представления о том, как работает апдейтер геймдаты.
  • Создаётся POST-форма.
  • В неё автоматически добавляется версия SourceMod.
  • Автоматически идёт проход по содержимому папки gamedata. Каждому файлу, которые доступны для чтения, вычисляются MD5, и вместе с путём к ним, добавляется в форму.
  • Так же добавляется поле с кол-вом добавленных в форму файлов.
  • Созданная и заполненная POST-форма отправляется.
  • Сервер возвращает KeyValues структуру, главная секция которой может называться как Errors, так и Changed. Оффтоп
  • Клиент (т.е., расширение) обрабатывает его, выполняя запросы загрузки файлов, если необходимо.
 
Сверху Снизу