plakapenka
Специалист
Я не стану лить воду про то как устроен клиент, сетевое взаимодействие, контроль надежности, приоритеты и т.п. Разберетесь с этим сами, когда придет время. Мой урок будет в стиле манула, так что повторяйте за мной, и в процессе всё поймете. Обещаю 
Отправим hello world с сервера на клиент:
В SAMP уже есть пакеты.. По этому мы возьмем один из свободных ID. Он будет всегда неизменным
Т.к. 251 будет всегда неизменным, нужно завести еще один макрос на ID, что потом понять что именно мы отправляем.
Например:
и дальше, отсылая новые данные будете добавлять новые идентификаторы и все... Зачем всё это, спросите Вы, если уже есть дефолт RPC? Я так захотел. Дефолт система RPC работает точно так же ( id пакета 20 ), так что какой-то особой разницы тут нет.
Все готово, отсылаем ( из мода. pwn ):
Принимаем ( на клиенте. с++ ):
Теперь отправим с клиента на сервер:
Отправка (Клиент c++):
Прием ( Сервер pwn ):
Все остальное уже просто вариации данных. Вы можете управлять GUI, делать кастомные функции, ботов, проверки клиента и все что душе угодно.
Просьба знатоков воздержаться от нравоучений. Урок написан на скорую руку, дабы у новичков было ХОТЬ ЧТО-ТО
Отправим hello world с сервера на клиент:
В SAMP уже есть пакеты.. По этому мы возьмем один из свободных ID. Он будет всегда неизменным
C++:
#define PACKET_CUSTOM 251
Например:
C++:
#define RPC_HELLOWORLD 1
Все готово, отсылаем ( из мода. pwn ):
C++:
CMD:test(playerid) {
new BitStream:bitstream = BS_New();
BS_WriteValue(
bitstream,
PR_UINT8, PACKET_CUSTOM,
PR_UINT32, RPC_HELLOWORLD
);
PR_SendPacket(bitstream, playerid, PR_MEDIUM_PRIORITY, PR_RELIABLE);
BS_Delete(bitstream);
return 1;
}
у вас уже будет функция аля UpdateNetwork. так что я не буду заострять на этом внимание. Просто добавляем case
C++:
case ID_CUSTOM_RPC: {
RakNet::BitStream bs((unsigned char *) pkt->data, pkt->length, false);
uint8_t packetID;
uint32_t rpcID;
bs.Read(packetID);
bs.Read(rpcID);
if (rpcID == RPC_HELLOWORLD) {
// Приняли. Отправим сообщение в чат?
CChatWindow::AddDebugMessage("Hello from pwn");
return;
}
break;
}
Теперь отправим с клиента на сервер:
Отправка (Клиент c++):
C++:
if (strcmp(str, "/test") == 0) {
RakNet::BitStream bsSend;
bsSend.Write((uint8_t) ID_CUSTOM_RPC);
bsSend.Write((uint32_t) RPC_HELLOWORLD);
pNetGame->GetRakClient()->Send(&bsSend, MEDIUM_PRIORITY, RELIABLE, 0);
}
C++:
IPacket:PACKET_CUSTOM(playerid, BitStream:bs)
{
new header, rpcid;
BS_ReadValue(bs,
PR_UINT8, header,
PR_UINT32, rpcid
);
switch(rpcid)
{
case RPC_HELLOWORLD:
{
SendClientMessage(playerid, -1, "Hello from client");
return 1;
}
}
return 1;
}
Все остальное уже просто вариации данных. Вы можете управлять GUI, делать кастомные функции, ботов, проверки клиента и все что душе угодно.
Часто вижу про проверку клиента. КАК ЖЕ ПРОВЕРИТЬ КЛИЕНТ, БЛИН? Объясняю на пальцах:
Придумай алгоритм изменения данных. Посылай рандомные данные на клиент. С клиента изменяй данные и отправляй ответ. Сверяй результат:
Например:
Придумал алгоритм: увеличить число на 50 и уменьшить на 15.
Отсылаешь рандом число: 20
На клиенте делаешь (20 + 50) - 15.
Отправляешь результат на сервер, и сверяешь ответы.
Готово ( Только алгоритм посложнее придумай )
Придумай алгоритм изменения данных. Посылай рандомные данные на клиент. С клиента изменяй данные и отправляй ответ. Сверяй результат:
Например:
Придумал алгоритм: увеличить число на 50 и уменьшить на 15.
Отсылаешь рандом число: 20
На клиенте делаешь (20 + 50) - 15.
Отправляешь результат на сервер, и сверяешь ответы.
Готово ( Только алгоритм посложнее придумай )
Просьба знатоков воздержаться от нравоучений. Урок написан на скорую руку, дабы у новичков было ХОТЬ ЧТО-ТО
Последнее редактирование:
