Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Урок Как отправлять данные Сервер << == >> Клиент

plakapenka

Специалист
Я не стану лить воду про то как устроен клиент, сетевое взаимодействие, контроль надежности, приоритеты и т.п. Разберетесь с этим сами, когда придет время. Мой урок будет в стиле манула, так что повторяйте за мной, и в процессе всё поймете. Обещаю :giggle:

Отправим hello world с сервера на клиент:

В SAMP уже есть пакеты.. По этому мы возьмем один из свободных ID. Он будет всегда неизменным
C++:
#define PACKET_CUSTOM 251
Т.к. 251 будет всегда неизменным, нужно завести еще один макрос на ID, что потом понять что именно мы отправляем.
Например:
C++:
#define RPC_HELLOWORLD 1
и дальше, отсылая новые данные будете добавлять новые идентификаторы и все... Зачем всё это, спросите Вы, если уже есть дефолт RPC? Я так захотел. Дефолт система RPC работает точно так же ( id пакета 20 ), так что какой-то особой разницы тут нет.

Все готово, отсылаем ( из мода. 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);
    }
Прием ( Сервер pwn ):
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.
Отправляешь результат на сервер, и сверяешь ответы.
Готово ( Только алгоритм посложнее придумай )


Просьба знатоков воздержаться от нравоучений. Урок написан на скорую руку, дабы у новичков было ХОТЬ ЧТО-ТО
 
Последнее редактирование:
Сверху Снизу