Kruzya
Участник
- Сообщения
- 12,970
- Реакции
- 10,914
- Команда форума
- #1
Поднимаем сервер для апдейтов Геймдаты SourceMod
Введение, разбор принципа работы
Тема, на самом деле, довольно интересная. Нигде про это я не нашёл информации (даже в вики AlliedModders, что удивительно, ибо в конфигурации SourceMod (файл core.cfg) есть параметр, отвечающий за адрес сервера обновлений), а поднять сервер понадобилось по причине того, что на серверах так же используются некоторые геймдаты, которые по апдейтеру не приходят, но которые так же надо обновлять. И самый простой способ обновить гемйдату на всех серверах - поднять где-то у себя этот самый сервер обновлений, и обновлять геймдаты на нём.
ВНИМАНИЕ! Эта статья разделена на несколько отдельных. Так же, по возможности, кое-где будут проскакивать куски кода.
Полученный по итогам сервер обновлений будет выложен на всеобщее обозрение (ну, вдруг кому пригодится). Писаться он будет на ASP .NET Core, хотя можно обойтись и обычным PHP.
Все продолжения статьи будут поститься в этой же теме.
- Введение, разбор принципа работы (Вы здесь)
- Пишем простейший сервер обновлений, часть 1 (Скоро...)
- Пишем простейший сервер обновлений, часть ... (Скоро...)
- Пишем простейший сервер обновлений, часть Х (Скоро...)
Оффтоп(точное кол-во частей - неопределенно. однозначно сказать - сложно.) - Тестирование результата (Скоро...)
- Итоги (Скоро...)
Если вручную обратиться по ссылке, которая видна в конфиге, через браузер, то веб-сервер нам возвращает ошибку, что не указана необходимая версия.

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

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

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

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

Отправляем запрос. И тестовые файлы, которые мы указали, пропадают из ответа.

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