Текущее состояние (выводы исследования)
| Пункт | Текущее состояние |
|---|---|
| Сервер контента (протокол метаданных) | src/network/core/config.cpp NetworkContentServerConnectionString(): переменная окружения OTTD_CONTENT_SERVER_CS, по умолчанию content.openttd.org (TCP порт 3978) |
| Зеркала загрузки | NetworkContentMirrorUriString(): переменная окружения OTTD_CONTENT_MIRROR_URI, по умолчанию https://binaries.openttd.org/bananas |
| Способ загрузки | network_content.cpp DownloadSelectedContentHTTP(): один POST-запрос со всеми ID контента → зеркало возвращает список заголовков файлов (id,type,filesize,url на строку) → последовательная загрузка каждого файла (каждый через отдельное GET-соединение) → AfterDownload() gunzip + tar распаковка |
| Модель потоков | HTTP-слой (WinHttp) работает в фоновом потоке, но загрузка файлов последовательная; нет списка зеркал, нет внутриигровых настроек, нет параллельности |
Реализация данной функции
1. Новые настройки (network_settings.ini + settings_type.h)
network.content_server(SLE_STR, по умолчанию пусто = официальный сервер)network.content_mirrors(SLE_STR, несколько URI зеркал через запятую, по умолчанию пусто = официальное зеркало)
Приоритет: переменная окружения > настройки игры > официальные значения по умолчанию.
2. Разбор конфигурации (src/network/core/config.cpp/h)
NetworkContentServerConnectionString()читает настройки;- Новый
NetworkContentMirrorUris()разбирает список через запятую (удаление пробелов, пропуск пустых, запасной официальный источник); NetworkContentMirrorUriString()изменён для возврата первого элемента списка.
3. Параллельная загрузка (src/network/network_content.h/.cpp)
- Новый
ContentFileDownload(один файл для загрузки: id/type/filesize/url/filename); - Новый
ContentDownloadSession : HTTPCallback(независимый статус загрузки каждого файла и колбэк;IsCancelledвзаимодействует с handler); DownloadSelectedContentHTTP(): POST кmirrors[mirror_index]→ParseResponseHeaders()однократный разбор всех заголовков файлов →StartDownloadSessions()запускает до 4 параллельных сессий (CONTENT_DOWNLOAD_PARALLEL), каждая завершённая сессия автоматически берёт следующий файл для загрузки;- Цепочка повторов при сбое: сбой сессии/сбой запроса к зеркалу → повторный запрос к следующему зеркалу → все зеркала не удались → откат к старому протоколу TCP (
DownloadSelectedContentFallback); - Корректное завершение: при сбое/отмене устанавливается
download_cancelled, ожидание завершения всех текущих сессий (OnAllSessionsDone) перед повторной попыткой или откатом, чтобы избежать зависших колбэков; ResetMirrorIndex(): новая загрузка начинается с первого зеркала (вызывается при запуске из GUI).
Затронутые файлы
src/table/settings/network_settings.ini(добавлено 2 настройки)src/settings_type.h(NetworkSettingsдобавлено 2 поля)src/network/core/config.cpp/config.h(разбор списка зеркал)src/network/network_content.h/.cpp(параллельные сессии)src/network/network_content_gui.cpp(сброс индекса зеркала перед загрузкой)
Ключевые моменты проверки
- После заполнения
network.content_mirrorsнесколькими URI (через запятую) загрузка контента должна работать и загружать несколько файлов параллельно (наблюдать прогресс загрузки / несколько одновременных соединений); - При отсутствии сети/ошибочном зеркале должен автоматически пробоваться следующее зеркало, затем откат к старому протоколу;
- При отмене загрузки не должно оставаться незавершённых
.tar.gzфайлов; - Требуется проверка на реальном железе (в репозитории нет среды сборки, код не компилировался).
Известные ограничения
- Степень параллельности жёстко задана как 4 (
CONTENT_DOWNLOAD_PARALLEL), в будущем может быть сделана настраиваемой; - Протокол зеркал зависит от формата официального bananas API (POST со списком ID возвращает список заголовков файлов).