Q2PRO-X 1.0 — Архитектурный аудит fairness
Просмотр документа на сайте Q2PRO-X. Оригинальный файл можно скачать из окна сайта.
Q2PRO-X 1.0
Архитектурное ревью по мультиплеерной честности
Русское издание для сайта
Q2PRO-X 1.0 Multiplayer Fairness Audit
Дата: 2026-04-14 Язык: русский Статус: архитектурно-технический аудит по коду
1. Цель проверки
Проверить, предоставляет ли текущий Q2PRO-X в `deathmatch > 0` реальные читерские преимущества по сравнению с допустимым клиентским quality-of-life поведением.
Основной фокус проверки:
- Предиктное оружие: может ли клиент реально стрелять быстрее, точнее или раньше, чем это допускает сервер.
- Клиентские улучшения движения и сетевого отклика: относятся ли они к читам.
- Визуальные системы Q2PRO-X: могут ли они давать gameplay advantage, не нарушая серверную механику напрямую.
2. Итоговый вывод
2.1. Серверно-механических читов по результатам проверки не выявлено
Текущая архитектура Q2PRO-X не содержит подтверждённого пути, при котором клиент мог бы:
- реально увеличить скорострельность оружия;
- нанести урон раньше серверного разрешения;
- повысить реальную точность попадания сверх серверной модели;
- породить "лишние" projectile/hitscan события вне серверной логики;
- обойти серверную валидацию времени команд за счёт client prediction.
Иными словами, предиктное оружие в Q2PRO-X является клиентской визуально-реактивной надстройкой и не подменяет серверную механику стрельбы.
2.2. Клиентские predict/movement-пути не относятся к читам
`cl_fixedmove`, `cl_predict_move_mode`, `cl_movement_feel`, `cl_step_smoothing_mode`, `cl_laghax` и связанные с ними ветки не относятся к читам, поскольку:
- они не изменяют серверную модель стрельбы и урона;
- они не создают серверные fire events самостоятельно;
- они не обходят серверную обработку `usercmd`;
- они не изменяют серверную физику мира;
- они являются клиентскими улучшениями локального управления, нормализации ввода, сглаживания и восприятия задержки.
2.3. Остаточный риск относится не к server-authority, а к visibility advantage
При этом в Q2PRO-X остаются клиентские системы, которые не ломают серверную честность, но способны менять визуальную читаемость сцены. Для полу-публичного тестирования 1.0 это следует рассматривать как отдельный policy-risk.
Главный пример: `weapon parts visibility`, позволяющий скрывать часть визуальных эффектов других игроков.
3. Предиктное оружие: техническое обоснование
3.1. Клиентский ghost/predict не управляет реальной стрельбой
В [input.c](O:/Claude2/q2pro/src/client/input.c) атака сначала попадает в обычный `usercmd`, и только после финализации команды вызывается клиентский `Ghost_OnFireCmd`:
- `BUTTON_ATTACK` выставляется в [input.c](O:/Claude2/q2pro/src/client/input.c:1103)
- финализированный `usercmd` сохраняется в [input.c](O:/Claude2/q2pro/src/client/input.c:1154)
- `Ghost_OnFireCmd(...)` вызывается после этого в [input.c](O:/Claude2/q2pro/src/client/input.c:1162)
Следовательно, client ghost layer не является источником серверного fire command; он является реакцией на уже сформированный локальный input path.
3.2. Сервер валидирует клиентское время команд
В [user.c](O:/Claude2/q2pro/src/server/user.c) сервер ведёт учёт `command_msec`:
- инициализация бюджета времени: [user.c](O:/Claude2/q2pro/src/server/user.c:531)
- списание `cmd->msec`: [user.c](O:/Claude2/q2pro/src/server/user.c:1123)
- underflow check через `sv_enforcetime`: [user.c](O:/Claude2/q2pro/src/server/user.c:1127)
`sv_enforcetime` по умолчанию включён:
- [main.c](O:/Claude2/q2pro/src/server/main.c:2207)
Это означает, что даже при клиентских различиях в cadence/packing сервер сохраняет контроль над допустимым временем исполнения команд.
3.3. Реальное решение о стрельбе принимает серверный `Think_Weapon`
В [p_client.c](O:/Claude2/q2pro/src/game/p_client.c) сервер:
- принимает `ucmd->buttons` в [p_client.c](O:/Claude2/q2pro/src/game/p_client.c:1637)
- вычисляет `latched_buttons` в [p_client.c](O:/Claude2/q2pro/src/game/p_client.c:1638)
- вызывает `Think_Weapon(ent)` при атаке в [p_client.c](O:/Claude2/q2pro/src/game/p_client.c:1656)
- дополнительно вызывает `Think_Weapon(ent)` в server frame path в [p_client.c](O:/Claude2/q2pro/src/game/p_client.c:1709)
То есть реальная серверная weapon state machine не заменяется клиентским предиктом.
3.4. Скорострельность задаётся серверной weapon state machine
В [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c) `Weapon_Generic(...)` является авторитарным конечным автоматом оружия:
- вход в `WEAPON_READY`: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:413)
- переход в `WEAPON_FIRING` только при допустимой атаке и наличии ammo: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:414)
- выстрел только на разрешённых `fire_frames[]`: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:458)
- возврат в `WEAPON_READY` по серверной frame logic: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:472)
Конкретные fire-frame схемы заданы сервером, например:
- Rocket Launcher: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:720)
- Blaster: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:778)
- HyperBlaster: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:843)
- Machinegun: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:936)
- Chaingun: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:1045)
- Shotgun: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:1105)
- Super Shotgun: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:1162)
- Railgun: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:1222)
- BFG: [p_weapon.c](O:/Claude2/q2pro/src/game/p_weapon.c:1294)
Из этого следует, что `Super Shotgun` не может реально стрелять быстрее серверно разрешённого цикла только из-за клиентского предикта.
3.5. Реальные projectile, trace и damage создаются на сервере
Настоящая боевая логика находится в [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c):
- `fire_bullet(...)`: [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:249)
- `fire_shotgun(...)`: [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:261)
- `fire_blaster(...)`: [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:312)
- `fire_rocket(...)`: [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:575)
- `T_Damage(...)`: например [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:202), [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:550)
- `T_RadiusDamage(...)`: например [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:396), [g_weapon.c](O:/Claude2/q2pro/src/game/g_weapon.c:562)
Следовательно:
- клиент не наносит урон самостоятельно;
- клиент не создаёт настоящий серверный projectile;
- клиент не может "ускорить" урон только за счёт ghost-слоя.
3.6. Клиентский ghost-слой прямо описан как visual-only
В [ghost.c](O:/Claude2/q2pro/src/client/ghost.c:1) система прямо описана как `client-side ghost projectile prediction`, немедленно создающая `visual-only ghosts`.
Дополнительно:
- [weaponfx.c](O:/Claude2/q2pro/src/client/weaponfx.c:6) фиксирует, что weapon FX layer не трогает admission gate и не dispatch-ит sound;
- [ghost.c](O:/Claude2/q2pro/src/client/ghost.c:2438) фиксирует, что при скрытии predicted visuals bookkeeping handoff/suppress path продолжает работать, а меняется только визуальная часть.
Итог: клиентский predict-слой не является альтернативной системой урона или скорострельности.
4. Movement / Laghax / Fixedmove
Эти механизмы не относятся к читам, поскольку по коду они не создают отдельную серверную физику и не подменяют weapon authority.
Даже если `cl_fixedmove` меняет способ клиентского разбиения команд по времени, сервер всё равно:
- получает обычные `usercmd`;
- считает `command_msec`;
- применяет стандартную game DLL weapon/movement logic.
Следовательно, данные механизмы относятся к категории client experience improvements, а не к server-authority bypass.
5. Визуальные системы: где проходит граница
5.1. Visibility highlights в текущем виде не дают wallhack
Ветка `visibility / highlights` уже содержит multiplayer-safe ограничения:
- увеличение item/dropped weapon scale выше `1.0` в multiplayer режется в [vis_items.c](O:/Claude2/q2pro/src/client/vis_items.c:537)
- для увеличенной модели кулинг всё равно считается по исходному размеру через `ent.cull_scale = base` в [entities.c](O:/Claude2/q2pro/src/client/entities.c:945)
- renderer использует `entcullscale` при sphere cull в [main.c](O:/Claude2/q2pro/src/refresh/main.c:199) и получает его из entity в [main.c](O:/Claude2/q2pro/src/refresh/main.c:309)
- толщина player shell ограничена малым диапазоном `0.0 .. 0.05` в [vis_items.c](O:/Claude2/q2pro/src/client/vis_items.c:953)
Это означает, что данная система не должна позволять "вытаскивать" pickup или player silhouette из-за геометрии только за счёт увеличения масштаба.
Однако она всё равно повышает визуальную заметность уже видимых целей и объектов. Это не server cheat, но это visual assist.
5.2. Weapon Parts Visibility остаётся policy-risk для competitive multiplayer
Наиболее спорной системой на текущий момент является `weapon parts visibility`.
По коду:
- система специально позиционируется как `visual-only policy layer` в [weaponfx.c](O:/Claude2/q2pro/src/client/weaponfx.c:1)
- она не трогает admission gate и не dispatch-ит sound в [weaponfx.c](O:/Claude2/q2pro/src/client/weaponfx.c:6)
- но она позволяет отключать целые классы FX у источника `WFX_SRC_OTHER` через [weaponfx.c](O:/Claude2/q2pro/src/client/weaponfx.c:38)
- foreign projectile model скрывается в [entities.c](O:/Claude2/q2pro/src/client/entities.c:716)
- wall impact path других источников классифицируется в [tent.c](O:/Claude2/q2pro/src/client/tent.c:1602)
Это не меняет урон и не делает стрельбу "сильнее", но может:
- упростить чтение сцены;
- уменьшить визуальный шум;
- скрыть часть информации о стрельбе и projectile path других игроков.
С точки зрения строгой multiplayer fairness это следует считать не серверным читом, а competitive visibility assist.
6. Практическая оценка готовности к 1.0
6.1. Что можно считать безопасным
Для версии 1.0 безопасно утверждать следующее:
- predicтное оружие не стреляет быстрее серверной нормы;
- predicтное оружие не наносит урон вне серверной авторизации;
- fixedmove / laghax / movement feel не относятся к читам;
- visibility highlights не создают wallhack-пути через geometry protrusion.
6.2. Что требует policy-решения до расширенного тестирования
Перед более широким полу-публичным тестированием рекомендуется отдельно определить multiplayer policy для:
- `cl_weaponfx_vis_other` и связанных с ним hiding-веток;
- player/item highlighting в competitive режимах;
- любых визуальных assist-настроек, очищающих сцену в `deathmatch > 0`.
7. Рекомендация
Для 1.0 рекомендуется разделить вопрос на два класса:
- **Server-authority fairness**
Это направление по результатам проверки выглядит корректно и готово.
- **Competitive visual policy**
Это направление следует зафиксировать отдельным профилем для `deathmatch > 0`, если цель релиза 1.0 — не только отсутствие механических читов, но и отсутствие спорных визуальных преимуществ.
8. Финальный вывод
По результатам аудита:
- Q2PRO-X не содержит подтверждённого механизма, позволяющего predicтному оружию реально стрелять быстрее, точнее или сильнее серверной нормы;
- client predict, fixedmove, movement feel и laghax не относятся к читам, поскольку не обходят серверную игровую механику;
- основной остаточный риск перед 1.0 относится к visual assist / visibility policy, а не к server-authority exploitation.
Итоговая формулировка:
**Серверно-механических читерских возможностей по проверенному коду не выявлено. Остаточная зона внимания перед 1.0 — клиентские visibility advantages, прежде всего в ветке weapon parts visibility.**