Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд CS 1.6 — Фикс симуляции игрока при спидхаке (анти-rubberbanding)

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
706
Реакции
18
Надоело смотреть на стагнацию в разделах по олдскульным шутерам, так что выкатываю немного технического мяса, которое валялось в закромах. Разберем фикс «резинок» (rubberbanding) при использовании спидхака в CS 1.6.

Суть проблемы проста: когда на сервере срабатывает SV_CheckCmdTimes и ваши команды начинают игнорироваться, движок перестает симулировать игрока на стороне сервера. При этом клиент по инерции продолжает предсказывать движение, что и вызывает дикие откаты назад.

Для начала нам нужно определить состояние «затыка». Это делается в CL_Move перед вызовом оригинала:

Код:
Expand Collapse Copy
game_i.is_stuck = local && c_game::is_alive(local) && game_i.client_state->frames[game_i.client_state->parsecountmod].clientbytes == 3;

Почему 3 байта?
В GoldSrc это размер дескрипторов дельты (фактически только заголовок). Если размер пакета равен 3 байтам, значит никаких изменений в состоянии игрока не произошло — сервер нас не симулирует.

Теперь сам фикс. Мы будем хукать CL_PredictMove, так как именно эта функция в GoldSrc отвечает за фактическую симуляцию игрока на клиенте.

Код:
Expand Collapse Copy
// Оффсет под актуальный Steam билд hw.dll
make_hook(void, __cdecl, get_module_base("hw.dll") + 0x1AB760, CL_PredictMove, bool predicting)
{
    // Если мы в стаке — скипаем симуляцию
    if (game_i.is_stuck)
    {
        return;
    }
    original.call(predicting);
}

Технические нюансы логики:
  1. Пайплайн вызовов выглядит так: CL_Move -> CL_PredictMove -> CL_ReadPackets.
  2. Мы определяем флаг is_stuck на основе данных последнего вызова CL_ReadPackets. Если сервер прислал пустую дельту, мы блокируем текущую симуляцию.
  3. Важно стопать именно CL_PredictMove, а не CL_RunUsercmd. Если заблокировать RunUsercmd, движок все равно будет копировать фреймы в список состояний клиента, что породит кучу неприятных визуальных багов.
  4. В итоге клиент всегда остается на 1 фрейм позади сервера, что полностью убирает эффект rubberbanding при агрессивном спидхаке. Привет из Source Engine, там похожая архитектурная особенность.

Метод старый как мир, но в большинстве паблик сурсов до сих пор реализован криво или не реализован вовсе. Юзайте, если пилите свой рейдж-мод для классики.

Интересно будет глянуть, у кого какие оффсеты на старых non-steam билдах, закидывайте в тред если есть наработки.
 
Назад
Сверху Снизу