• Из-за обновления GTA 5 (был добавлен новый патч) может временно не работать вход в RAGE Multiplayer.

    Ошибка: Ваша версия Grand Theft Auto V не поддерживается RAGE Multiplayer.
    ERROR: Your game version is not supported by RAGE Multiplayer.

    Данная ошибка говорит о том, что GTA V обновилась до новой версии (GTA Online тоже). Вам необходимо обновить саму игру в главном меню вашего приложения (Steam / Epic Games / Rockstar Games).
    Если после этого RAGE:MP все равно не работает - вам нужно дождаться выхода патча для самого мультиплеера (обычно это занимает от нескольких часов до нескольких дней).

    Новости и апдейты Rockstar Games - https://www.rockstargames.com/newswire/
    Статус всех служб для Rockstar Games Launcher и поддерживаемых игр: https://support.rockstargames.com/ru/servicestatus


    Grand Theft Auto 5 (+ GTA Online) последний раз были обновлены:

Читеры и доверие клиентской стороне

qweqweqwe123123123

Участник портала
24 Июн 2025
87
13
18
Привет, не сильно разбираюсь в читах, но знаю, что клиентской стороне доверять нельзя и все нужно перепроверять на серверной стороне.

Подскажите пожалуйста, кто шарит :)

Пример (Client-side):
Код:
mp.keys.bind(BTN_Y, true, () => {
    if (mp.players.local.getVariable("isDisabledBtnY")) return;

    mp.events.callRemote('accept-request');
});

1) Можно ли доверять этой проверке на клиентской стороне if (mp.players.local.getVariable("isDisableBtnY")) return;
Или все-таки надо на серверной стороне в ивенте 'accept-request' ставить еще раз проверку ?

Пример (Server-side):
Код:
mp.events.add('accept-request', (player) => {
    // надо ли повторять на серверной стороне проверку ?
    if (player.getVariable('isDisabledBtnY')) return;

    ...какой-то код....
});

2) Если все таки НАДО проверять и на серверной стороне это..., то может тогда стоит убрать проверку на клиентской стороне ?
Или это некий "трафик" будет гонять туда сюда и это типа плохо ?

3) Может ли читер на клиентской стороне вызывать событие на сервер ДРУГОГО player ?
(ps. как мы знаем, мы можем из client-side вызывать только самого себя на server-side)
 

Jerry (ChatGPT)

AI-powered language model
VIP
helper
17 Окт 2023
2,884
291
100
1) Проверке на клиентской стороне доверять нельзя, обязательно нужно повторять на сервере.
2) Лучше оставить проверку и там, и там: клиентская — для удобства пользователя, серверная — для безопасности. Дополнительный трафик незначителен.
3) Нет, с клиентской стороны можно вызвать серверный ивент только от имени своего персонажа, подделать другого игрока нельзя.
 

enotit

Высший разум
High developer
BackEnd developer
13 Ноя 2020
1,814
598
187
22
1) Можно ли доверять этой проверке на клиентской стороне if (mp.players.local.getVariable("isDisableBtnY")) return;
такие переменные задаются сервером. Доверять можно, но вызовы лучше перепроверять. Хотя насколько критично. Если "не проверка" никому не мешает, то ну и чёрт с ними?

Если отвечать на твой вопрос, если ты никаких обвязок на вызов клиент-сервер не делаешь, то вызов событий может подделан екзекьютерам. Потому насколько критично этот блок кода влияет на игру?


Если все таки НАДО проверять и на серверной стороне это..., то может тогда стоит убрать проверку на клиентской стороне ?
Или это некий "трафик" будет гонять туда сюда и это типа плохо ?
Старайся минимизировать триггеры сервера. Если можно что-то выполнить на клиенте - выполняй. Пример капча, с запросом клиент -> сервер именно клиент отправляет токен, задание которое он и выполнил. и уже сервер в последствии валидирует его.


Может ли читер на клиентской стороне вызывать событие на сервер ДРУГОГО player ?
Нет, если только:
1) другой клиент имеет какой-нибудь вирусный скрипт
2) кодер оставил бекдор (триггер через сервер без валидации)
 
Реакции: qweqweqwe123123123

qweqweqwe123123123

Участник портала
24 Июн 2025
87
13
18
такие переменные задаются сервером.
Это очень хорошо, что ты заметил. Тут речь шла именно про getVariable, а не про обычную локальную переменную на клиенте, например, mp.players.local.isQwe = true;
Если "не проверка" никому не мешает
Дублирование логики на клиенте и на сервере 1 в 1. Например, напишу это на клиенте if (mp.players.local.getVariable("isDisabledBtnY")) return; и на стороне сервера продублирую. А у меня таких getVariable может быть еще 3-4 штуки на одном ивенте, если не больше. Это не сильная проблема, но зачем это делать дважды(1 на клиенте,2ой раз на сервере), если читер через это не сможет пройти...
если ты никаких обвязок на вызов клиент-сервер не делаешь
Что ты имеешь ввиду под словом "обвязка" клиент-сервер ?

Пример капча, с запросом клиент -> сервер именно клиент отправляет токен, задание которое он и выполнил. и уже сервер в последствии валидирует его.
На client side создается токен, который отправляется на сервер ? Я бы создание токена сделал бы на сервере, положил бы в кэш, отправил бы на клиент/CEF. Или не так понимаю пример...
 

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
4,842
2,437
208
36
На client side создается токен, который отправляется на сервер ?
нет конечно
клиент общается с гуглом (например если говорить про рекапчу) - гугл отдает токен
клиент отправляет результат на сервак
сервак валидирует его через гугловское апи, естественно


Дублирование логики на клиенте и на сервере 1 в 1. Например, напишу это на клиенте if (mp.players.local.getVariable("isDisabledBtnY")) return; и на стороне сервера продублирую. А у меня таких getVariable может быть еще 3-4 штуки на одном ивенте, если не больше. Это не сильная проблема, но зачем это делать дважды(1 на клиенте,2ой раз на сервере), если читер через это не сможет пройти...
нет никакого смысла убирать клиентские проверки, потому что если он не сможет её пройти - ты не будешь лишний раз дёргать сервер
и уж точно нет никакого смысла убирать серверные проверки, потому что источник истины - всегда сервер
все что хранится на пк пользователя - он может разобрать, сломать и подменить

клиент может быть полностью скомпрометирован и ты должен быть к этому готов
 

enotit

Высший разум
High developer
BackEnd developer
13 Ноя 2020
1,814
598
187
22
Дублирование логики на клиенте и на сервере 1 в 1. Например, напишу это на клиенте if (mp.players.local.getVariable("isDisabledBtnY")) return; и на стороне сервера продублирую. А у меня таких getVariable может быть еще 3-4 штуки на одном ивенте, если не больше. Это не сильная проблема, но зачем это делать дважды(1 на клиенте,2ой раз на сервере), если читер через это не сможет пройти...
на сервере же не только злосчастные игроки, а есть ещё обычные. И 10 игроков нажмут Y и 10 раз бессмысленно затриггерят бек. Да, проверка небольшая, но какие-то мизерные ресурсы потратит сервак, а зачем? Задача сервера делать защиту на дурака, а задача клиента как можно лучше и более оптимизировано мучить сервер.

Что ты имеешь ввиду под словом "обвязка" клиент-сервер ?
Ну если очень кратко, клиент - сервер имеют одну точку входа, но пользак триггерит сервак с каким-нибудь зашифрованным-хитровыдуманным ключом, дабы минимизировать экзекьютеры. Сервак валидирует, ок - роутим, неок - бан и вызов легавых (маме игрока).

На client side создается токен, который отправляется на сервер ? Я бы создание токена сделал бы на сервере, положил бы в кэш, отправил бы на клиент/CEF. Или не так понимаю пример...
Это я тебе пример про капчу не к тому, что нужно на рейдж серваки их пихать, нет. То чтобы защитить сервис/сервисы сервиса от лишней нагрузки - на вход ставим капчу и валидируем каждый запрос.
 
Реакции: qweqweqwe123123123

qweqweqwe123123123

Участник портала
24 Июн 2025
87
13
18
на сервере же не только злосчастные игроки, а есть ещё обычные. И 10 игроков нажмут Y и 10 раз бессмысленно затриггерят бек. Да, проверка небольшая, но какие-то мизерные ресурсы потратит сервак, а зачем? Задача сервера делать защиту на дурака, а задача клиента как можно лучше и более оптимизировано мучить сервер.
Да, аргумент, лучше продублировать и не дергать сервер.

Ну если очень кратко, клиент - сервер имеют одну точку входа, но пользак триггерит сервак с каким-нибудь зашифрованным-хитровыдуманным ключом, дабы минимизировать экзекьютеры. Сервак валидирует, ок - роутим, неок - бан и вызов легавых (маме игрока).
Понял твою мысль, это как для веба JWT (access, refresh токен)... Тут логика какая ? На сервере создается JWT, в кэш player.JWT.access =... player.JWT.refresh... кладем токены, а access токен отправляем на клиент ? И когда события из клиента будут присылаться на сервер, я буду проверять acess токен?

нет конечно
клиент общается с гуглом (например если говорить про рекапчу) - гугл отдает токен
клиент отправляет результат на сервак
сервак валидирует его через гугловское апи, естественно
Теперь понял
 

MrJagger

Участник портала
19 Янв 2025
87
18
30
Да, аргумент, лучше продублировать и не дергать сервер.


Понял твою мысль, это как для веба JWT (access, refresh токен)... Тут логика какая ? На сервере создается JWT, в кэш player.JWT.access =... player.JWT.refresh... кладем токены, а access токен отправляем на клиент ? И когда события из клиента будут присылаться на сервер, я буду проверять acess токен?


Теперь понял
Глянь этот ролик, здесь чувак прям очень ясно объясняет про JWT
 

qweqweqwe123123123

Участник портала
24 Июн 2025
87
13
18
mr jagger, я знаю, что это такое)

чуть посидел подумал... тут(в ragemp) даже проще. Здесь не нужно создавать два токена (acсess и refresh), тут вообще даже либа не нужна для ренерации JWT.
access токен для веба используется, потому что можно зайти с разных устройств, и он обновляется условно каждые 15 минут
Но у нас игра и мы четко знаем, когда игрок зашел в игру и вышел.

Я бы сделал так... Я бы создал тупо uuiv() на сервере и все.... Кидаю его в кэш на сервер player.token = uuiv() и на клиент mp.player.local.token = uuiv()
Каждый раз, когда игрок заходит, каждый раз будет создаваться новый токен...

Енотик, попровь меня, если ошибаюсь
 

MrJagger

Участник портала
19 Янв 2025
87
18
30
mr jagger, я знаю, что это такое)

чуть посидел подумал... тут(в ragemp) даже проще. Здесь не нужно создавать два токена (acсess и refresh), тут вообще даже либа не нужна для ренерации JWT.
access токен для веба используется, потому что можно зайти с разных устройств, и он обновляется условно каждые 15 минут
Но у нас игра и мы четко знаем, когда игрок зашел в игру и вышел.

Я бы сделал так... Я бы создал тупо uuiv() на сервере и все.... Кидаю его в кэш на сервер player.token = uuiv() и на клиент mp.player.local.token = uuiv()
Каждый раз, когда игрок заходит, каждый раз будет создаваться новый токен...

Енотик, попровь меня, если ошибаюсь
Извини, не увавливаю суть.
Окей, игрок зашел, ты назначил ему токен передал на клиент
Игрок вышел и зашел заново и, что дальше?
player.token уничтожится автоматом после выхода игрока

Если ты хочешь автоход, то используй social club + hash + nickname social club игрока, шифруй это только каким-нибудь способом, заноси в базу и проверяй при входе игрока, совпадают ли они с тем, что есть в базе
Но стоит учесть, что это все тоже спуфается, и нужно как-то уберечь от взлома
 

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
4,842
2,437
208
36
mr jagger, я знаю, что это такое)

чуть посидел подумал... тут(в ragemp) даже проще. Здесь не нужно создавать два токена (acсess и refresh), тут вообще даже либа не нужна для ренерации JWT.
access токен для веба используется, потому что можно зайти с разных устройств, и он обновляется условно каждые 15 минут
Но у нас игра и мы четко знаем, когда игрок зашел в игру и вышел.

Я бы сделал так... Я бы создал тупо uuiv() на сервере и все.... Кидаю его в кэш на сервер player.token = uuiv() и на клиент mp.player.local.token = uuiv()
Каждый раз, когда игрок заходит, каждый раз будет создаваться новый токен...

Енотик, попровь меня, если ошибаюсь
в player который приходит тебе на сервер уже "зашит" аналог jwt
 
Реакции: qweqweqwe123123123

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
4,842
2,437
208
36
можно поподробнее, не понимаю... ты про какое свойство player говоришь ? :(
ремоут-евенты рейджа это своеобразный вебсокет, внутри которого уже есть токен игрока
ты не можешь и тебе не нужно его разбирать, сервер сам это делает

по крайней мере мне кажется что я когда-то супердавно читал что-то подобное от Гоши
 

qweqweqwe123123123

Участник портала
24 Июн 2025
87
13
18
Ну если очень кратко, клиент - сервер имеют одну точку входа, но пользак триггерит сервак с каким-нибудь зашифрованным-хитровыдуманным ключом, дабы минимизировать экзекьютеры. Сервак валидирует, ок - роутим, неок - бан и вызов легавых (маме игрока).
ну ждем тогда пояснений от Енотика :)
 

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
4,842
2,437
208
36
ну ждем тогда пояснений от Енотика :)
так а одно другому не мешает
никакой токен не мешает тебе вытащить его же из клиента по его же логике и подкинуть в экзек

поэтому например экзеком ты не можешь выполнить запрос от определённого игрока, и чит дергает например админ команду сразу "от всех админов"

античит по действиям это скорее ещё про логику обработки ремоутевентов и твоё доверие дальше, не только про токенизацию ещё какую то дополнительную
 
Последнее редактирование:

qweqweqwe123123123

Участник портала
24 Июн 2025
87
13
18
никакой токен не мешает тебе вытащить его же из клиента по его же логике и подкинуть в экзек
я просто не совсем понимаю , как работают экзекьютеры. К чему у них есть доступ, как они встраиваются ? Например, если я клиенту присвою токен: mp.players.local.token = uuiv()

Мне кажется, что читер, сможет получить эту переменную. Вопрос, где тогда тут защита то ?)
 

Inoi

/dev/null
Команда форума
Moderator
VIP
15 Окт 2020
4,842
2,437
208
36
я просто не совсем понимаю , как работают экзекьютеры. К чему у них есть доступ, как они встраиваются ? Например, если я клиенту присвою токен: mp.players.local.token = uuiv()

Мне кажется, что читер, сможет получить эту переменную. Вопрос, где тогда тут защита то ?)
сможет, да
это и не панацея, конечно
как и всё что ты хранишь на клиенте или оно туда попадает

экзек просто дёргает конкретный евент, подставляя плеера
например нас ебашили вызывая админевенты, в которые подставляются сразу все админы - админ евент выполняется
пока впадлу думать над токенезацией самый простой способ это обойти - валидация, т.е. в ответ плееру приходит запрос действительно ли он хочет выполнить эту команду
очевидно, что в экзек она прийти не может, так как приходит просто всем админам

если он дёргает евент например с каким-то получением денег, такой у нас тоже был я помню - там просто не было проверки на условие
ну условно ты списываешь с игрока например образную я не знаю руду и выдаёшь бабки
и ты проебал проверку - а ну, есть ли у него руда? такое ли её количество как надо?
если ты их проебал - экзек сработает
если нет - ну, на нет и суда нет

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

но ваще по уму должна быть какая-то валидация бизнес-состояния
ну
условно
сервер отправляет игроку "у тебя запрос, нажми ЕС чтобы принять"
и дайёт какой-то челленж=рандом
клиент жмёт И и шлёт ассепт-реквест на челлендж с реквест_айди
сервер проверяет, а есть ли вообще пендинг-реквест на этот реквест айди? совпадает ли челленж? время?
и если ок - тогда выполняет

если короче у тебя вообще можно вызывать какое то событие в любой момент и оно даст результат - значит ты забыл серверную проверку состояния какого-то.
любая вся эта токенизация это хуйня, такая же как шифровать клиентку
серверу вообще должно быть похуй на то что сказал клиент, он должен сам всегда знать, можно ли какое-то действие выполнить

а так можно до усрачки токенами обвешаться, тебя всё равно выебут
 
Реакции: qweqweqwe123123123