Skip to content

Latest commit

 

History

History
455 lines (346 loc) · 41.5 KB

File metadata and controls

455 lines (346 loc) · 41.5 KB

Sprint 18_20 — Theme 3_4 — Lesson 8_10 — Command Line


Тема

📌 Что изучается в задании command_line игрового сервера 📖 Подробное описание темы 🧠 Почему это важно для дальнейшего развития сервера ✅ Итог
И всё оживает В этом задании игровой сервер получает поддержку параметров командной строки и автоматическое обновление игрового времени Сервер можно запускать в тестовом режиме, реальном режиме, с ручным tick и с автоматическим tick Сервер становится управляемым через CLI

Задание

📌 Что нужно добавить в игровой сервер 📖 Подробное описание задачи 🧠 Что меняется в поведении сервера ✅ Итог
Поддержка параметров командной строки Нужно добавить разбор параметров запуска через Boost.ProgramOptions Сервер получает --help, --tick-period, --config-file, --www-root, --randomize-spawn-points CLI-параметры работают
Автоматическое обновление игрового времени Нужно добавить режим, в котором сервер сам вызывает Application::Tick с заданным периодом Игровое время может идти автоматически без ручного /api/v1/game/tick Автоматический tick работает

Полный путь проекта

📌 Где находится решение задания command_line 📖 Полный путь проекта 🧠 Для чего используется этот путь ✅ Итог
Solution-папка задания /home/almusha/cppbackend/sprint2/problems/command_line/solution В этой папке находится итоговое решение, README, исходный код, data, static и build после сборки Путь решения известен
/home/almusha/cppbackend/sprint2/problems/command_line/solution

Откуда взято решение

📌 Что было взято за основу 📖 Полный путь источника 🧠 Почему именно этот проект используется как база ✅ Итог
Свежий сервер из предыдущего задания /home/almusha/cppbackend/sprint2/problems/time_control/solution В предыдущем задании уже был сервер с управлением игровым временем, поэтому его удобно использовать как основу База взята из time_control
Актуальные данные текущего задания /home/almusha/cppbackend/sprint2/problems/command_line/precode/data В текущем задании свои актуальные игровые данные data обновлены
Актуальная статика текущего задания /home/almusha/cppbackend/sprint2/problems/command_line/precode/static В текущем задании свои актуальные статические файлы static обновлены
/home/almusha/cppbackend/sprint2/problems/time_control/solution
/home/almusha/cppbackend/sprint2/problems/command_line/precode/data
/home/almusha/cppbackend/sprint2/problems/command_line/precode/static

Подготовка проекта

📌 Шаг подготовки solution-папки 💻 Команда 📖 Что делает команда ✅ Итог
Перейти в solution cd /home/almusha/cppbackend/sprint2/problems/command_line/solution Открывает папку итогового решения Можно готовить проект
Очистить обычные файлы rm -rf ./* Удаляет обычные файлы и папки в solution Папка очищена
Очистить скрытые файлы rm -rf ./.??* Удаляет скрытые файлы и папки Скрытые остатки удалены
Скопировать основу cp -r /home/almusha/cppbackend/sprint2/problems/time_control/solution/* /home/almusha/cppbackend/sprint2/problems/command_line/solution/ Копирует свежее решение из time_control Основа перенесена
Удалить старый build rm -rf /home/almusha/cppbackend/sprint2/problems/command_line/solution/build Удаляет старую сборку Сборка будет чистой
Удалить старые data rm -rf /home/almusha/cppbackend/sprint2/problems/command_line/solution/data Удаляет старую папку данных Данные можно заменить
Удалить старую static rm -rf /home/almusha/cppbackend/sprint2/problems/command_line/solution/static Удаляет старую папку статических файлов Статика можно заменить
Скопировать новые data cp -r /home/almusha/cppbackend/sprint2/problems/command_line/precode/data /home/almusha/cppbackend/sprint2/problems/command_line/solution/data Копирует актуальные данные текущего задания Данные готовы
Скопировать новую static cp -r /home/almusha/cppbackend/sprint2/problems/command_line/precode/static /home/almusha/cppbackend/sprint2/problems/command_line/solution/static Копирует актуальные статические файлы текущего задания Static готова
cd /home/almusha/cppbackend/sprint2/problems/command_line/solution

rm -rf ./*
rm -rf ./.??*

cp -r /home/almusha/cppbackend/sprint2/problems/time_control/solution/* /home/almusha/cppbackend/sprint2/problems/command_line/solution/

rm -rf /home/almusha/cppbackend/sprint2/problems/command_line/solution/build

rm -rf /home/almusha/cppbackend/sprint2/problems/command_line/solution/data
rm -rf /home/almusha/cppbackend/sprint2/problems/command_line/solution/static

cp -r /home/almusha/cppbackend/sprint2/problems/command_line/precode/data /home/almusha/cppbackend/sprint2/problems/command_line/solution/data
cp -r /home/almusha/cppbackend/sprint2/problems/command_line/precode/static /home/almusha/cppbackend/sprint2/problems/command_line/solution/static

Проверка подготовки проекта

📌 Что проверить после подготовки проекта 💻 Команда 📖 Что должна показать команда ✅ Итог
Перейти в solution cd /home/almusha/cppbackend/sprint2/problems/command_line/solution Открывает итоговую папку решения Можно проверять структуру
Посмотреть дерево проекта tree -L 2 Показывает структуру проекта на глубину 2 уровня Видно, что data и static находятся на месте
cd /home/almusha/cppbackend/sprint2/problems/command_line/solution
tree -L 2

Фактическая структура solution после подготовки

📌 Что проверено командой tree -L 2 в solution-папке задания command_line 📖 Что реально находится в проекте после копирования основы из time_control и замены data / static 🧠 Почему эта проверка важна перед сборкой и запуском сервера ✅ Итог
Корневые файлы проекта В корне solution находятся CMakeLists.txt, Dockerfile, README.md, conanfile.txt, папки data, src, static Это подтверждает, что проект содержит сборочные файлы, Dockerfile, документацию, зависимости, данные, исходный код и статику Корень проекта готов
Папка data В data лежит config.json Этот файл передаётся серверу через параметр -c ../data/config.json или --config-file Конфиг на месте
Папка src В src находятся файлы сервера: main.cpp, http_server.cpp, request_handler.cpp, model.cpp, json_loader.cpp, logger.cpp, заголовки и вспомогательные файлы Это подтверждает, что исходный код игрового сервера перенесён из предыдущего решения и готов к доработке под CLI Исходники на месте
Папка static В static находятся HTML, favicon, manifest, изображения, JavaScript и другие статические файлы Эта папка передаётся серверу через параметр -w ../static или --www-root Статика на месте
Проверка глубины 2 Команда tree -L 2 показывает структуру на два уровня Этого достаточно, чтобы быстро убедиться, что основные файлы и каталоги находятся там, где нужно Структура проверена
almusha@compute-vm-2-2-20-ssd-1775824473365:~/cppbackend/sprint2/problems/command_line/solution$ tree -L 2
.
├── CMakeLists.txt
├── Dockerfile
├── README.md
├── conanfile.txt
├── data
│   └── config.json
├── src
│   ├── boost_json.cpp
│   ├── http_server.cpp
│   ├── http_server.h
│   ├── json_loader.cpp
│   ├── json_loader.h
│   ├── logger.cpp
│   ├── logger.h
│   ├── main.cpp
│   ├── model.cpp
│   ├── model.h
│   ├── player_tokens.h
│   ├── players.h
│   ├── request_handler.cpp
│   ├── request_handler.h
│   ├── sdk.h
│   ├── tagged.h
│   └── use_cases.h
└── static
    ├── abc..html
    ├── about.html
    ├── android-chrome-192x192.png
    ├── android-chrome-512x512.png
    ├── apple-touch-icon.png
    ├── assets
    ├── favicon-16x16.png
    ├── favicon-32x32.png
    ├── favicon.ico
    ├── file with spaces.html
    ├── game.html
    ├── game_old.html
    ├── images
    ├── index.html
    ├── js
    └── site.webmanifest

---

## Поддержанные параметры командной строки

| 📌 Параметр командной строки игрового сервера | 📖 Полная форма и короткая форма   | 🧠 Что задаёт параметр                                                    | ✅ Итог                             |
| --------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------- | ---------------------------------- |
| Help                                          | `-h`, `--help`                     | Показывает справку по доступным параметрам                                | Help работает                      |
| Tick period                                   | `-t`, `--tick-period milliseconds` | Задаёт период автоматического обновления игрового времени в миллисекундах | Автоматический tick настраивается  |
| Config file                                   | `-c`, `--config-file file`         | Задаёт путь к JSON-конфигу игрового сервера                               | Конфиг передаётся через CLI        |
| WWW root                                      | `-w`, `--www-root dir`             | Задаёт путь к папке статических файлов                                    | Static root передаётся через CLI   |
| Randomize spawn points                        | `--randomize-spawn-points`         | Включает случайные точки появления собак                                  | Random spawn включается параметром |

```text
-h, --help
-t, --tick-period milliseconds
-c, --config-file file
-w, --www-root dir
--randomize-spawn-points

Help

📌 Как проверить справку игрового сервера 💻 Команда 📖 Что должно быть в ожидаемом выводе ✅ Итог
Запуск help ./bin/game_server --help Сервер должен вывести список разрешённых параметров: help, tick-period, config-file, www-root, randomize-spawn-points Справка отображается
./bin/game_server --help

Ожидаемый вывод:

Allowed options:
  -h [ --help ]                     produce help message
  -t [ --tick-period ] milliseconds set tick period
  -c [ --config-file ] file         set config file path
  -w [ --www-root ] dir             set static files root
  --randomize-spawn-points          spawn dogs at random positions

Режимы работы

📌 Режим работы игрового сервера 💻 Команда запуска 📖 Особенности режима ✅ Итог
Тестовый режим ./bin/game_server -c ../data/config.json -w ../static Игровое время не идёт само, /api/v1/game/tick разрешён, тесты могут вручную двигать игровое время Подходит для тестов
Реальный режим ./bin/game_server -c ../data/config.json -w ../static -t 50 Игровое время обновляется автоматически, сервер вызывает Application::Tick каждые 50 миллисекунд, /api/v1/game/tick запрещён Подходит для реальной работы

Тестовый режим

📌 Что происходит в тестовом режиме 📖 Подробное описание поведения 🧠 Почему это нужно ✅ Итог
Игровое время не идёт само Сервер запущен без --tick-period Тесты полностью контролируют время Автоматический tick выключен
/api/v1/game/tick разрешён Endpoint работает как раньше Тесты могут вручную отправлять tick Ручной tick доступен
Тесты двигают игровое время Тестовый код вызывает endpoint tick Это делает поведение предсказуемым Тестирование удобно
./bin/game_server -c ../data/config.json -w ../static
игровое время не идёт само
/api/v1/game/tick разрешён
тесты могут вручную двигать игровое время

Реальный режим

📌 Что происходит в реальном режиме 📖 Подробное описание поведения 🧠 Почему это нужно ✅ Итог
Игровое время обновляется автоматически Сервер запущен с --tick-period, например -t 50 Игровой мир сам делает шаги времени Автоматический tick включён
Сервер вызывает Application::Tick Вызов происходит каждые 50 миллисекунд Модель обновляется регулярно Игровое время идёт
/api/v1/game/tick запрещён Ручной endpoint больше нельзя использовать Нельзя одновременно иметь ручное и автоматическое управление временем Endpoint защищён
./bin/game_server -c ../data/config.json -w ../static -t 50
игровое время обновляется автоматически
сервер вызывает Application::Tick каждые 50 миллисекунд
/api/v1/game/tick запрещён

Поведение /api/v1/game/tick

📌 Как запущен сервер 📖 Поведение endpoint /api/v1/game/tick 🧠 Почему так сделано ✅ Итог
Без --tick-period Endpoint работает как раньше Это тестовый режим, где время двигается вручную Tick разрешён
С --tick-period Endpoint должен вернуть ошибку 400 Bad request и JSON {"code": "badRequest", "message": "Invalid endpoint"} В автоматическом режиме нельзя вручную менять время через API Tick запрещён
HTTP/1.1 400 Bad request
Content-Type: application/json
Content-Length: <размер тела ответа>
Cache-Control: no-cache

{"code": "badRequest", "message": "Invalid endpoint"}

Случайные точки появления собак

📌 Как запущен сервер 💻 Команда 📖 Где появляется собака ✅ Итог
Без --randomize-spawn-points ./bin/game_server -c ../data/config.json -w ../static Собака появляется в начальной точке первой дороги карты Spawn фиксированный
С --randomize-spawn-points ./bin/game_server -c ../data/config.json -w ../static --randomize-spawn-points Собака появляется в случайной точке случайной дороги карты Spawn случайный
./bin/game_server -c ../data/config.json -w ../static
./bin/game_server -c ../data/config.json -w ../static --randomize-spawn-points

Boost.ProgramOptions

📌 Для чего используется Boost.ProgramOptions 📖 Что подключается в коде 🧠 Основная идея применения ✅ Итог
Разбор командной строки #include <boost/program_options.hpp> Нужно описать допустимые параметры, разобрать argc и argv, сохранить значения в структуру Args CLI разбирается через Boost.ProgramOptions
#include <boost/program_options.hpp>
описать допустимые параметры
разобрать argc и argv
сохранить значения в структуру Args

Пример структуры Args

📌 Поле структуры Args 📖 Тип поля 🧠 Что хранит поле ✅ Итог
config_file std::filesystem::path Путь к JSON-конфигу сервера Config path хранится
www_root std::filesystem::path Путь к папке статических файлов Static root хранится
tick_period std::optional<int> Период автоматического tick в миллисекундах, если он задан Tick period может отсутствовать
randomize_spawn_points bool Флаг случайного появления собак Random spawn хранится
struct Args {
    std::filesystem::path config_file;
    std::filesystem::path www_root;
    std::optional<int> tick_period;
    bool randomize_spawn_points = false;
};

Ticker

📌 Что такое Ticker 📖 Что делает класс Ticker 🧠 Почему он нужен ✅ Итог
Класс для автоматического обновления игрового времени Ticker создаёт Boost.Asio steady_timer, ждёт заданный период, вызывает Application::Tick(delta), после срабатывания снова ставит таймер и работает внутри strand Он нужен, чтобы игровой сервер мог сам обновлять состояние модели с заданным периодом Автоматический tick реализуется через Ticker
📌 Действие Ticker 📖 Подробное описание 🧠 Практический смысл ✅ Итог
Создаёт steady_timer Используется таймер Boost.Asio Таймер позволяет выполнять действие через заданный период Таймер создан
Ждёт заданный период Период берётся из --tick-period Например, 50 миллисекунд Интервал задан
Вызывает Application::Tick(delta) После ожидания вызывается обновление модели Игровой мир делает шаг времени Tick вызывается
Снова ставит таймер После срабатывания таймер планируется заново Обновление становится периодическим Tick повторяется
Работает внутри strand Все операции с моделью выполняются последовательно Это защищает состояние игры Потокобезопасность соблюдается
создаёт Boost.Asio steady_timer
ждёт заданный период
вызывает Application::Tick(delta)
после срабатывания снова ставит таймер
работает внутри strand

Почему используется strand

📌 Зачем нужен strand в игровом сервере 📖 Подробное объяснение проблемы 🧠 Что гарантирует strand ✅ Итог
Защита игрового состояния strand нужен, чтобы обращения к игровому состоянию выполнялись последовательно Если один поток обрабатывает API-запрос, а другой одновременно вызывает Tick, оба могут менять состояние игры strand предотвращает одновременное изменение модели
Возможная гонка данных Без strand один поток может обрабатывать API-запрос, а другой одновременно вызывать Tick Оба потока меняют состояние игры одновременно Возникает race condition
Последовательное выполнение strand гарантирует, что такие операции не выполнятся одновременно Операции с моделью идут одна за другой Модель защищена
один поток обрабатывает API-запрос
другой поток одновременно вызывает Tick
оба меняют состояние игры
strand гарантирует, что такие операции не выполнятся одновременно.

Сборка

📌 Шаг сборки решения command_line 💻 Команда 📖 Что делает команда ✅ Итог
Перейти в solution cd /home/almusha/cppbackend/sprint2/problems/command_line/solution Открывает папку решения Можно собирать
Удалить старую сборку rm -rf build Удаляет старый build Сборка будет чистой
Создать build mkdir build Создаёт папку сборки build создан
Перейти в build cd build Открывает папку build Можно запускать Conan и CMake
Активировать Conan source ~/conan-venv/bin/activate Включает Conan virtualenv Conan доступен
Установить зависимости conan install .. -s compiler.libcxx=libstdc++11 -s build_type=Release --build=missing Устанавливает зависимости для Release и ABI libstdc++11 Зависимости готовы
Запустить CMake cmake .. -DCMAKE_BUILD_TYPE=Release Генерирует файлы сборки CMake настроен
Собрать проект cmake --build . Компилирует сервер Сервер собран
cd /home/almusha/cppbackend/sprint2/problems/command_line/solution

rm -rf build
mkdir build
cd build

source ~/conan-venv/bin/activate

conan install .. -s compiler.libcxx=libstdc++11 -s build_type=Release --build=missing

cmake .. -DCMAKE_BUILD_TYPE=Release

cmake --build .

Проверка запуска

📌 Что проверяется 💻 Команда запуска 📖 Какой режим включается ✅ Итог
Тестовый режим ./bin/game_server -c ../data/config.json -w ../static Сервер работает без автоматического tick Тестовый режим запускается
Автоматический режим ./bin/game_server -c ../data/config.json -w ../static -t 50 Сервер вызывает Application::Tick каждые 50 миллисекунд Автоматический режим запускается
Автоматический режим со случайным spawn ./bin/game_server -c ../data/config.json -w ../static -t 50 --randomize-spawn-points Сервер автоматически обновляет время и размещает собак случайно Авто tick + random spawn работают
./bin/game_server -c ../data/config.json -w ../static
./bin/game_server -c ../data/config.json -w ../static -t 50
./bin/game_server -c ../data/config.json -w ../static -t 50 --randomize-spawn-points

Проверка endpoint tick

📌 В каком режиме проверяется endpoint 💻 Команда проверки 📖 Ожидаемый ответ ✅ Итог
Автоматический режим curl -i http://localhost:8080/api/v1/game/tick Ожидается JSON {"code": "badRequest", "message": "Invalid endpoint"} Ручной tick запрещён
curl -i http://localhost:8080/api/v1/game/tick

Ожидаемо:

{"code": "badRequest", "message": "Invalid endpoint"}

Итог

📌 Что реализовано в задании command_line 📖 Подробное описание результата 🧠 Почему это важно для игрового сервера ✅ Итог
Разбор командной строки через Boost.ProgramOptions Сервер умеет читать CLI-параметры запуска Настройки больше не нужно хардкодить CLI работает
Параметры --help, --tick-period, --config-file, --www-root Добавлены основные параметры запуска сервера Можно задавать конфиг, статику и период tick Основные параметры готовы
Параметр --randomize-spawn-points Добавлен флаг случайного появления собак Можно включать random spawn через CLI Random spawn работает
Два режима работы игрового времени Есть тестовый режим без --tick-period и реальный режим с --tick-period Сервер подходит и для тестов, и для реального запуска Режимы разделены
Автоматический Tick через Boost.Asio timer Реализован периодический вызов Application::Tick(delta) Игровое время может идти само Автоматический tick работает
Запрет ручного /api/v1/game/tick в автоматическом режиме Если сервер запущен с --tick-period, endpoint tick возвращает ошибку Нельзя одновременно управлять временем вручную и автоматически Поведение защищено
разбор командной строки через Boost.ProgramOptions
параметры --help, --tick-period, --config-file, --www-root
параметр --randomize-spawn-points
два режима работы игрового времени
автоматический Tick через Boost.Asio timer
запрет ручного /api/v1/game/tick в автоматическом режиме