Commit Graph
8 Commits
Author SHA1 Message Date
cacto 20d63f0cee Фикс клавиатуры в бою, подсказка про WASD, зелёное дуло
Quintus слушает клавиатуру на самом канвасе, а не на document/window;
без autoFocus и явного focus() канвас не получал фокус (особенно после
переприкрепления к DOM на реванш) — WASD/стрелки/space никуда не долетали.
Клик по кнопке D-pad тоже уводил фокус — возвращаем его на канвас.

Дуло танка было почти того же цвета, что фон (#0a0e0c на чёрном) — не
видно. Сделал ярко-зелёным с тёмной обводкой, читается на любом корпусе.

Над блоком кнопок управления — подсказка, что WASD/стрелки тоже работают.
2026-08-06 18:50:20 +05:00
cacto 35041c7d48 Security-хардening: XSS в никах, non-root контейнер, rate-limiting, спавн-фикс
Клиент: ники других игроков рендерились через innerHTML без экранирования — XSS.
Добавлен escapeHtml() для nickname и в списке игроков комнаты.

Сервер:
- Санитайзинг ника и на бэкенде (обрезка длины, вырезание control/HTML
  символов) — защита не только для этого клиента, но и для любых будущих
  потребителей (логи, другие рендеры).
- onMessage обёрнут в try/catch: payload.value<T>() кидает json::type_error
  на несовпадении типа поля — одно кривое сообщение могло уронить процесс
  со всеми активными играми.
- Лимит на общее число комнат (200) — иначе клиент, спамящий
  lobby.create_room, разгонял rooms_ до исчерпания памяти.
- Fix: одна из раскладок coop-карты клала укрытие поверх стартовой позиции
  игрока — танк рождался внутри кирпича и не мог выехать. Тайл под каждым
  стартовым танком теперь расчищается после построения карты.

Docker: gameserver теперь работает от непривилегированного пользователя,
а не от root.

nginx: rate-limiting на /ws (5 подключений/с на IP, до 20 одновременных) —
защита от флуда соединениями/комнатами; CSP и security-заголовки
(X-Content-Type-Options, X-Frame-Options, Referrer-Policy).
2026-08-06 14:00:31 +05:00
cacto f2a5657740 Звук (Web Audio API) + несколько раскладок coop-карты
Клиент: audio.js синтезирует эффекты без внешних файлов (выстрел,
взрыв, разрушение кирпича, победа/поражение) — вписывается в
"чистый HTML/CSS/JS" стек. AudioContext разблокируется по клику
"готов" (браузеры блокируют автовоспроизведение без жеста).

Сервер: 3 варианта раскладки coop-карты (случайный выбор при старте
матча) вместо одной фиксированной.

Fix: сервер разрушал кирпичи в своей копии карты, но никогда не сообщал
об этом клиенту — стена оставалась видимой навсегда, хотя сквозь неё уже
можно было стрелять. Теперь game.state включает destroyed_tiles,
клиент убирает соответствующий спрайт стены.
2026-08-06 12:42:52 +05:00
cacto 84da9b49e2 Coop с AI/базой (соло-старт), реванш, чистые URL, доработки клиента
Сервер (Game.hpp/cpp):
- coop-режим: AI-противники (волна 8, до 3 одновременно), простое
  преследование базы с рандомизацией, база с укрытием из кирпича.
- Комната стартует соло (1 игрок), второй может подключиться позже.
- Fix: хитбокс пули по базе брал радиус танка вместо пули.
- Fix: AI при столкновении со стеной теперь сразу перерешает направление,
  а не долбит в одну точку до 3с — без этого база падала за секунды.

Клиент:
- Танк: гусеницы, башня, заметный ствол (было — незаметный нубик).
- Рендер базы (укрытие/флаг), AI-танки — отдельным оттенком зелёного.
- Экран победы/поражения — крупный glitch-текст на весь оверлей вместо
  строки текста; кнопки "играть ещё" (без reload) и "в лобби".
- Блок кнопок управления (D-pad + огонь) справа от игрового поля.
- Лобби: coop стартует по кнопке "готов" в одиночку.

nginx: try_files с fallback на .html — чистые URL (/projects, /game)
без расширения, старые /projects.html и т.п. продолжают работать.
2026-08-06 11:39:09 +05:00
cacto d47d50f467 Лобби: подсказка "жду второго игрока" вместо тихого бездействия
В pvp-комнате с одним игроком кнопка "готов" ничего не делала (сервер
не стартует матч без 2 игроков) без единого объяснения. Теперь кнопка
задизейблена и показывается статус, пока не зайдёт второй игрок.
2026-08-04 13:13:29 +05:00
cacto 2d0be9c287 Игровая логика PvP: сервер (C++) + клиент (Quintus.js)
Сервер: Game — authoritative-тик 20 Гц через uSockets timer, движение/коллизии
танков и пуль, разрушаемые кирпичные стены, respawn, победа/поражение/ничья,
технический проигрыш при дисконнекте. game.ready запускает матч, когда оба
игрока в pvp-комнате готовы.

Клиент: заведён Quintus.js (MIT, vendored) — Tank/Bullet/Wall спрайты,
рендер по снапшотам game.state, keyboard-инпут (WASD/стрелки/space),
экран результата матча.

Найден и исправлен use-after-free: колбэк onFinished_ синхронно удалял
Game изнутри его же метода — перенесено на uWS::Loop::defer.
2026-07-28 12:05:01 +05:00
cacto 864868de49 Лобби: комнаты на сервере (C++) и UI на клиенте
Сервер: Lobby/Room/Player — create/join/leave/list_rooms, broadcast обновлений,
проверка авторизации (hello) и состояния комнаты (waiting/full/in_progress).
Клиент: полноценный UI лобби (создание, список, вход в комнату, выход),
блокировка кнопок до установки WS-соединения.
nginx: no-cache для JS/CSS (нет хеширования имён файлов).
2026-07-26 21:22:20 +05:00
cacto a9d2a6b15c Каркас проекта: ТЗ, nginx+gameserver(uWebSockets) в Docker, /ws echo
Frontend — чистый HTML/CSS/JS без сборки (резюме, проекты, игра-заглушки).
Gameserver — C++ на uWebSockets (CMake FetchContent), протокол hello/lobby.list_rooms/error проверен end-to-end.
2026-07-26 19:31:44 +05:00