HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ПРОГРАММИРОВАНИЕ > С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 19.07.2018, 21:13
F11GAR0.
Новичок
Регистрация: 08.06.2017
Сообщений: 0
С нами: 4700181

Репутация: 33
По умолчанию

RakNet. На версии SAMP 0.3.7

Кратко и понятно о движке и его использовании в собейте и сампфункц!

И так RakNet это сетевой движок для связи клиента с сервером и наоборот. Общаются они с помощью обычных пакетов и RPC.

Для понятности, представим себе посылку, которую мы будем отправлять.







Как и обычная посылка, пакет должен иметь свой ID. Например это будет ID_PLAYER_SYNC он равен 207. В нём будут такие параметры как позиция игрока, скорость и другие, вот полная структура:



Прежде чем отправить эту посылку нужно заполнить её вот этой структурой, запишем позицию скорость и здоровье, остальное оставим по нулям. Чтоб не записывать в каждое поле ноль можно просто написать после обьявления структуры ZeroMemory(&название вашей струкуты, sizeof(stOnFootData));



Вот мы обьявили структуру как data, обнулили все значения(*образно*) и записали в позицию координаты Groove Street а в скорость записали ускорение в сторону поворота игрока(небольшое чтоб было заметней нужно домножить на 10 и поднять педа, тоесть data.fPosition[2]+=1.5)

Так же есть fQuaternion, это такая вещь, что то типа замены матрицы, которая отвечает за поворот игрока.

Тут я не буду обьяснять как перевести матрицу поворота в кватернион, но возможно в скором будущем обьясню.

Ну вот мы подготовили груз к отправке теперь его нужно положить в коробку. Коробка это выражение образное ,на самом деле в RakNet это последовательность битов(байтов) так называемый BitStream.

Создаём битстрим строчкой

И так, как говорилось ранее сначало нужно записать ID нашего пакета, тоесть ID_PLAYER_SYNC, делается это просто

Записали в битстрим байт с идом пакета, затем записываем всю структуру, так называемый груз который мы подготавливали ранее. Выглядит это таким образом

Ну вот как говорится и рыбку сьели и на *** сели, теперь можно отправлять наш пакет на сервер, делается это так: Send(&bs);> (в случае собейта) а если у вас сф, то делается это так getRakNet()->SendPacket(&bsOnfootSync);>

И на выходе вы получите такую картину:



~Не обращайте на приставку LQ_ внимания, это обозначение битстрима в LiquidMod в который я это решил пихнуть, у вас же будет просто BitStream.~

Но что же произойдёт после того как мы отправили пакет? Ну начнём с того что отправим мы его один раз, а пакеты PLAYER_SYNC отправляются довольно часто самим самп клиентом, примерно каждую секунду когда вы стоите, и очень быстро когда двигаетесь. Но на выходе вы получите быстрый телепорт на грув с ускорением в сторону которую вы смотрите и телепорт обратно. (!Важная инфа) Синхра она на то и синхра что вы её не видите, увидят этот телепорт только остальные люди!

RakNet хуки!

Как вы уже знаете, пакеты не только исходят от нас но и приходят к нам, всё тот же PLAYER, BULLET, VEHICLE и т.д и мы их уже умеем отправлять НО!Что если мы хотим не отправлять пакеты сами,азаменять те которые уже исходят от нас? В этом нам помогут хуки!

Хук исходящей синхры.

~Для тех у кого сф пример будет потом, наберитесь терпения~

В собейте(mod_sa на 0.3.7 R1-R2 etc.) есть уже готовый хук исходящей синхры, он находится в файле cheat_samp.cpp и является функцией bool OnSendPacket(BitStream *parameters, PacketPriority priority, PacketReliability reliability, char orderingChannel){ … }

И так всякий раз когда мы отправляем пакет, в собейте вызывается функция OnSendPacket

Ловится битстрим, как мы говорили в прошлом примере коробка и выполняются некие действия с ними. Рассмотрим простой пример GhostMod, когда другие игроки смогут проходить сквозь нас. Принцип простой: Ловим пакет, заменяем параметр byteSpecialAction на 3. И так начнём.

Для начала узнаем какой пакет у нас отловился, для этого пишем ResetReadPointer();

parameters->Read(packetId);>

ResetReadPointer обозначает то что мы сдвинули указатель чтения пакета в 0, это можно сравнить с курсором в текстовом редакторе.



Теперь после обнуления перед курсором стоит ид пакета, после прочтения которого, «курсор»

сдвинется за него. Далее мы проверяем если ид пакета равен 207 (ID_PLAYER_SYNC) то начинаем редактировать.

Чтоб не читать всё подряд то нужного нам значения, мы поставим нужный нам сдвиг байтов, тоесть переместим его сами. Для этого есть функция SetReadOffset(int offset). Чтоб узнать на каком оффсете расположен byteSpecialAction нужно посчитать сколько было байт информации до него. Я этого делать не буду так как у меня есть сосчитаные оффсеты, которые я приложу к данному «гайду».

И так оффсет у нас равен 37, пишем parameters->SetReadOffset(37);

Отлично, мы сдвинули курсор в нужное нам место, теперь картина выглядит примерно вот так:



Можно прочитать byteSpecialAction в какую нибудь переменную например:

uint8_t sAction;

parameters->Read(sAction);

Но нам же нужно просто заменить?

Тогда делаем parameters->SetWriteOffset(37);

WriteOffset это уже курсор записи, а не чтения.

Запись выглядит так, будто был нажат Insert поэтому после записи какого то значения, остальное не сдвинется а заменится тем что вводили. И так поставили мы оффсет теперь parameters->Write((uint8_t)3);

Отлично! Мы заменили наше значение, теперь отпускам пакет на свободу return true;

Получилось примерно следущее:



А теперь главный вопрос: Как же быть с SF?

А всё очень просто, мы просто создадим такую же функу как в собейте.

Сначала регистрируем коллбэк функи в mainloop (там где вся инициализация)

SF->getRakNet()->registerRakNetCallback( RakNetScriptHookType::RAKHOOK_TYPE_OUTCOMING_PACKE T, OnSendPacket );

Затем создаём функу

bool CALLBACK outcomingData( stRakNetHookParams *params ){

}

Теперь у нас есть удобная структурка в отличии от собейта где мы сразу можем достать ид пакета, вот так: if(params->packetId == ID_PLAYER_SYNC){ … }

Битстрим идёт отдельно как params->bitStream НО!В нём по прежднему лежит пакет айди, не стоит думать что он отдельно! Дальше всё происходит так же только вместа parameters мы пишем params->bitStream

Хук входящей синхры.



Как я уже говорил, пакеты идут не только от нас, но и к нам! Поэтому логично тебе подумать что входящие пакеты тоже можно ловить. И да, это так! Можно стопануть например унок синхру(она нужна для синхронизации пустых машин, исходят когда ты толкаешь машину) и пояснить за позицию например.

Чтобы не ебаться лишний раз с оффсетами мы прочитаем всю структуру разом. Функа для хука входящих пакетов в собейте находится в файле cheat_samp.cpp и является функцией bool OnReceivePacket(Packet *p){...}

Для начала получим пакет айди, он находится в p->data[0] и проверяем

if(p->data[0] == ID_UNOCCUPIED_SYNC){ … }

Затем нам нужно из пакета получить битстрим, делаем это так: BitStream bsUnoData((unsigned char *)p->data, p->length, false);

Получили битстрим затем читаем его в структуру UnoData(назвать можно как угодно хоть huimorzha)

stUnoccupiedData UnoData;

bsUnoData.IgnoreBits(8);

bsUnoData.Read(playerId);

bsUnoData.Read((PCHAR)&UnoData, sizeof(stUnoccupiedData));

Теперь просим пакет пояснить за позицию которую он шлёт, делается это так

if(UnoData.fPosition[2] > 20000 || UnoData.fPosition[2] data[0] = 255; что в принципе даст одно и тоже.

Что же делать в SF? Ну тут опять же всё просто, регистрируем коллбэк в mainloop инициализации:

SF->getRakNet()->registerRakNetCallback( RakNetScriptHookType::RAKHOOK_TYPE_INCOMING_PACKET , OnRecivePacket );

И создаём функу приёма пакета.

bool CALLBACK OnRecivePacket( stRakNetHookParams *params ){

...

}

Далее всё делается ещё проще, битстрим лежит всё там же в params->bitStream и пакет айди тоже. Читаем как исходящий а чтоб не пустить его, так же как в исходящем пишем return false;

На этом по ракнету у меня всё, RPC лень писать, возможно мне припрёт и я напишу про них, удачного кодинга вашего собейта/сфплагина

с вами был zH.F11GAR0

Thanks to:

FYP – for SF and mod_sa source

MasterZero – for motivation to make cheats

GH0ST – for help with sobeit and c++

DR8GUN8V – for testing my shit

0pc0d3r – for good nastroenie and motivation to reverce injenering shit and (?)

Zeta-Hack team – for motivation to fuCK SAMP JAJAJA
 
Ответить с цитированием

  #2  
Старый 19.07.2018, 21:33
kawa operand
Постоянный
Регистрация: 15.04.2017
Сообщений: 602
С нами: 4778331

Репутация: 63


По умолчанию

лайк за рисунки вообще круто описал офигенно четко красава репспект

(однако сейчас придет дарккнайт тебя обсирать наверное будь готов)
 
Ответить с цитированием

  #3  
Старый 19.07.2018, 22:42
Dark_Knight
Флудер
Регистрация: 18.03.2013
Сообщений: 4,080
С нами: 6921957

Репутация: 183


По умолчанию

Цитата:
Сообщение от kewa opcode  

(однако сейчас придет дарккнайт тебя обсирать наверное будь готов)
Традициям изменять нельзя. Кеша, ты нубососяра.

По теме, красиво.
 
Ответить с цитированием

  #4  
Старый 19.07.2018, 21:43
Toopie
Новичок
Регистрация: 21.01.2018
Сообщений: 29
С нами: 4373792

Репутация: 0
По умолчанию

мене нравицо я 2 клас ставит))))
 
Ответить с цитированием

  #5  
Старый 19.07.2018, 21:51
ArtzEs
Новичок
Регистрация: 09.07.2017
Сообщений: 8
С нами: 4656361

Репутация: 3
По умолчанию

так себе тутор, для новичков надо расписывать все конкретно ,каждую частичку кода
 
Ответить с цитированием

  #6  
Старый 19.07.2018, 21:57
Musaigen
Познавший АНТИЧАТ
Регистрация: 01.04.2018
Сообщений: 1,710
С нами: 4272230

Репутация: 183


По умолчанию

[QUOTE="fiigaro"]

if(UnoData.fPosition[2] > 20000 || UnoData.fPosition[0]
 
Ответить с цитированием

  #7  
Старый 19.07.2018, 22:16
F11GAR0.
Новичок
Регистрация: 08.06.2017
Сообщений: 0
С нами: 4700181

Репутация: 33
По умолчанию

Цитата:
Сообщение от Musaigen  

Плохой пакет начинается в принципе уже с 10000.0, лимиты карты гта са это 2600 и -2600 кроме оси Z, дальше уже идут краши или попытки телепортировать в загрузку
WorldBounds 20000 являются пределами, за которыми хуярит лоад, 2600 и -2600 это только края карты, по Z стрим бесконечный однако при больших значениях тоже лоад, вообще пример тривиальный но от некоторых крашеров из ликвида спасёт)
 
Ответить с цитированием

  #8  
Старый 19.07.2018, 22:20
D3structoR
Познающий
Регистрация: 12.04.2013
Сообщений: 71
С нами: 6886020

Репутация: 68
По умолчанию

Цитата:
Сообщение от Musaigen  

Плохой пакет начинается в принципе уже с 10000.0, лимиты карты гта са это 2600 и -2600 кроме оси Z, дальше уже идут краши или попытки телепортировать в загрузку
лимит по кордам до 19999, дальше лоад
 
Ответить с цитированием

  #9  
Старый 20.07.2018, 07:42
uryukhai
Участник форума
Регистрация: 01.07.2017
Сообщений: 196
С нами: 4667719

Репутация: 28
По умолчанию

Цитата:
Сообщение от AlexDrift  

лимит по кордам до 19999, дальше лоад
где лоад?

 
Ответить с цитированием

  #10  
Старый 20.07.2018, 12:31
Azller Lollison
Познавший АНТИЧАТ
Регистрация: 20.07.2017
Сообщений: 1,292
С нами: 4639746

Репутация: 183


По умолчанию

Цитата:
Сообщение от uryukhai  

где лоад?
Мб потому что ты с собейтом?
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.

×

Создать сделку

Продавец: ник или ID

Название сделки:

Сумма USDT:

Срок сделки, дней:

Кто платит комиссию:

Условия сделки:

После создания сделки средства будут зарезервированы в холде до завершения сделки.

×

Мои сделки

Загрузка...
×

Сделка


Загрузка чата...
×

ESCROW ADMIN PANEL

Загрузка...
Загрузка...