Question

в чём может быть проблема? Передаю строку через PR_String, и получаю с клиента бред

CMD:TestData(playerid, params[]){

    new msg[] = "Code_Test";

	new BitStream:bs = BS_New();

    BS_WriteInt8(bs,30);
    BS_WriteFloat(bs,0.9);
    BS_WriteFloat(bs,23.4);
    BS_WriteString(bs, msg, sizeof msg);

	PR_SendRPC(bs, playerid, 179);

	BS_Delete(bs);
	return 1;
}

[05:57:27] RPC - Длина  30 | 0.900000 | 23.400000 | I*(!@dp
И всегда текст разный :S

Хотя принимаю всё нормально:

 

bool CALLBACK Hok_RPC_BYTE(stRakNetHookParams *params)
{
	if (params->packetId == 179) 
	{
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "Кастомный RPC работает!!!");
		byte nameLen;
		float test;
		float test1;
		char szPlayerName[100];
		params->bitStream->ResetReadPointer();
		params->bitStream->Read(nameLen); 
		params->bitStream->Read(test);
		params->bitStream->Read(test1);
        params->bitStream->Read(szPlayerName, 100);
		params->bitStream->ResetReadPointer(); 
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "RPC - Длина  %d | %f | %f | %s", nameLen, test , test1, szPlayerName);
	}
	return true;
};

 

Edited by .037

Share this post


Link to post

2 answers to this question

  • 0

Ну во первых используй strlen вместо sizeof. ( в данном случае )

strlen() используется для получения длины строки, хранящейся в массиве.

sizeof() используется для получения фактического размера.

Во вторых ты должен предварительно записать длину строки.

Твой код должен будет выглядеть так:

CMD:TestData(playerid, params[])
{
    new msg[] = "Code_Test";
	new BitStream:bs = BS_New();

    BS_WriteFloat(bs,0.9);
    BS_WriteFloat(bs,23.4);
    BS_WriteUint8(bs, strlen(msg));
    BS_WriteString(bs, msg);

	PR_SendRPC(bs, playerid, 179);
	BS_Delete(bs);
	return 1;
}

Клиентская сторона будет выглядеть так:

bool CALLBACK Hok_RPC_BYTE(stRakNetHookParams *params)
{
	if (params->packetId == 179) 
	{
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "Кастомный RPC работает!!!");
		float test, test1;
		std::string szPlayerName;
		uint8_t len;
		params->bitStream->ResetReadPointer();
		params->bitStream->Read(test);
		params->bitStream->Read(test1);
        params->bitStream->Read(len);
        text.reserve(len);
        params->bitStream->Read(const_cast<char*>(szPlayerName.data()), len);
		params->bitStream->ResetReadPointer(); 
		SF->getSAMP()->getChat()->AddChatMessage(D3DCOLOR_XRGB(0, 0xAA, 0), "RPC - Длина  %f | %f | %s | %d", test , test1, szPlayerName.c_str(), len);
	}
	return true;
};

В третьих, дефайн BS_WriteString принимает два аргумента ( line github pawn.raknet )

Edited by legendabrn

Share this post


Link to post
  • 0

Залогируйте еще какое значение возвращает функция Read для строки, оно должно быть true. 

Также попробуйте воспользоваться методом PrintHex(char*) для просмотра всего битстрима, который пришел. 

Чтобы лишние значения не мешали (30, 0,9 ...) можно их пока убрать. 

Share this post


Link to post
Guest
This topic is now closed to further replies.
Sign in to follow this  
Followers 0
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • Danny_Marcelo
      By Danny_Marcelo
      Всех приветствую. Сегодня я решил обновить систему мероприятий, т.к. на самом проекте Advance RP уже давно видоизменили систему, добавили нового функционала. Мы не должны стоять на месте и я решил тоже свою систему доработать. Вы можете использовать данную систему как аналог Advance RP или же доработать для своего проекта. Все в ваших руках как говорится.
       
      Что нового?
       
      Итак приступим:
      Находим свои переменные и вставляем:
       
      new settp = 0; // Флаг включения/выключения телепортации new Float:TeleportFloat[3]; // Координаты точки телепортации new TeleportInfo[2]; // Интерьер и виртуальный мир new Float:PlayerLastPos[MAX_PLAYERS][3]; // Последние координаты игрока new PlayerLastInt[MAX_PLAYERS]; // Последний интерьер игрока new PlayerLastVW[MAX_PLAYERS]; // Последний виртуальный мир игрока new PlayerWeapons[MAX_PLAYERS][13][2]; // Оружие игрока (слот и патроны) new PlayerUsedTP[MAX_PLAYERS]; // Флаг для отслеживания использования /tp  
      Далее идём в команды, мой случай на Pawn.CMD, но +/- везде одинаково, разве что меняется шапка
       
      CMD:settp(playerid, params[]) {     if (PlayerInfo[playerid][pAdmin] < 4) return 1;     new string[95];     if (settp == 0)     {         GetPlayerPos(playerid, TeleportFloat[0], TeleportFloat[1], TeleportFloat[2]);         TeleportInfo[0] = GetPlayerInterior(playerid);         TeleportInfo[1] = GetPlayerVirtualWorld(playerid);         settp = 1;         format(string, sizeof(string), "[A] %s[%d] установил точку телепорта для игроков. {00CC00}ТП включен.", PlayerInfo[playerid][pName], playerid);         SendAdminMessage(0x52B2B5FF, string);     }     else     {         format(string, sizeof(string), "[A] %s[%d] удалил точку телепорта для игроков. {FF6600}ТП отключен.", PlayerInfo[playerid][pName], playerid);         SendAdminMessage(0x52B2B5FF, string);         settp = 0;     }     return 1; } CMD:tp(playerid, params[]) {     if (settp == 0) return SendClientMessage(playerid, 0xCECECEFF, !"Функция отключена администратором.");     if (PlayerInfo[playerid][pJailed] >= 1) return SendClientMessage(playerid, 0xCECECEFF, !"Арестованным не разрешено покидать камеру.");     if (PlayerInfo[playerid][pRabota] != 0) return SendClientMessage(playerid, 0xCECECEFF, !"Необходимо завершить все начатые работы и активные действия.");     if (bolkam[playerid] == true) return SendClientMessage(playerid, 0xCECECEFF, !"Необходимо завершить все начатые работы и активные действия.");     GetPlayerPos(playerid, PlayerLastPos[playerid][0], PlayerLastPos[playerid][1], PlayerLastPos[playerid][2]);     PlayerLastInt[playerid] = GetPlayerInterior(playerid);     PlayerLastVW[playerid] = GetPlayerVirtualWorld(playerid);     for (new i = 0; i < 13; i++)     {         GetPlayerWeaponData(playerid, i, PlayerWeapons[playerid][i][0], PlayerWeapons[playerid][i][1]);     }     PlayerUsedTP[playerid] = 1;     ShowPlayerDialog(playerid, 22, DIALOG_STYLE_MSGBOX, !"{6699FF}Телепортация",         !"{FFFFFF}Вы уверены, что хотите попасть на место проведения мероприятия?\n{FFCD00}Ваше оружие будет изъято для хранения и возвращено позже.", !"Да", !"Нет");     return 1; }  
       
      CMD:back(playerid, params[]) {     if (!PlayerUsedTP[playerid])     {         return SendClientMessage(playerid, 0xCECECEFF, !"Эту функцию можно использовать после {FF9933}/tp, /go {CECECE}или по окончании {FF9933}мероприятий");     }     SetPlayerPos(playerid, PlayerLastPos[playerid][0], PlayerLastPos[playerid][1], PlayerLastPos[playerid][2]);     SetPlayerInterior(playerid, PlayerLastInt[playerid]);     SetPlayerVirtualWorld(playerid, PlayerLastVW[playerid]);     ResetPlayerWeapons(playerid);     for (new i = 0; i < 13; i++)     {         if (PlayerWeapons[playerid][i][0] != 0)         {             GivePlayerWeapon(playerid, PlayerWeapons[playerid][i][0], PlayerWeapons[playerid][i][1]);         }     }     PlayerUsedTP[playerid] = 0;     SendClientMessage(playerid, 0x3399FFFF, !"Вы вернулись туда, где были до телепортации");     return 1; } Ну и в OnDialogResponse:
      case 22: // Не забудьте проверить и при надобности изменить id диалога на вашу цифру или ID_NAME         {             if (response)             {                 SetPlayerPos(playerid, TeleportFloat[0], TeleportFloat[1], TeleportFloat[2]);                 SetPlayerInterior(playerid, TeleportInfo[0]);                 SetPlayerVirtualWorld(playerid, TeleportInfo[1]);                 ResetPlayerWeapons(playerid);                 SendClientMessage(playerid, 0x66CCFFFF, "Вы были доставлены на место проведения мероприятия");                 SendClientMessage(playerid, 0x66CCFFFF, "Чтобы вернуться обратно, введите {FF9900}/back");             }         } Скриншоты:
       
      Если игрок сидит в КПЗ и вводит /tp:

       
      При включенном /tp:

       
      При выключенном /tp:

       
      Сообщение администраторам:

       
      Если работаешь или лечишься в больнице:

       
      Текст после телепортации:

       
      При вводе /back 1 и более раз:

       
      P.S. Команду /tp на Advance можно нажимать бесконечно, по этому я не стал сюда пихать аналогичную проверку как в /back.
      Если что, не сложно будет добавить 1 строчку проверки. Просто имейте ввиду, что это не баг. Просто нужно же соответствовать названию темы "На 100% КОПИЯ"))
       
      Автор: Danny_Marcelo
      Размещая на другие порталы, обязательно указать автора
    • Wiggins
      By Wiggins
      Доброго времени суток, нуждаюсь в помощи. Если есть люди, которые шарят в pawno, нужна помощь. Короче, мод ART RP, там в донате есть строка "Уникальные аксессуары", когда на него нажмешь, открывается TextDraw менью, нужно переделать это на обычную менью (/mm например, там обычная менью), буду рад, если поможете, за ранее спасибо.

      Если не ошибаюсь, строка текстдрав аксессуаров начинается с 1416 до 1443.
      art4.pwn