Эмуляция RPC ApplyPlayerAnimation

Ya Zaregalsya

Известный
Автор темы
370
127
Пытаюсь задать персонажу анимку путём эмуляции входящего RPC в SAMPFUNCS. Далее код:
C++:
SF->getSAMP()->registerChatCommand("applyAnimation", [](std::string param)->void
                {
                    UINT16 wPlayerID = SF->getSAMP()->getPlayers()->sLocalPlayerID;
                    UINT8 AnimLibLength = 4;
                    char AnimLib[4] = "PED";
                    UINT8 AnimNameLength = 10;
                    char AnimName[10] = "IDLE_HBHB";
                    float fDelta = 3.000000;
                    bool loop = false;
                    bool lockx = true;
                    bool locky = true;
                    bool freeze = true;
                    UINT32 dTime = 0;

                    BitStream bs;
                    bs.Write(wPlayerID);
                    bs.Write(AnimLibLength);
                    bs.Write(AnimLib);
                    bs.Write(AnimNameLength);
                    bs.Write(AnimName);
                    bs.Write(fDelta);
                    bs.Write(loop);
                    bs.Write(lockx);
                    bs.Write(locky);
                    bs.Write(freeze);
                    bs.Write(dTime);

                    SF->getRakNet()->emulateRecvRPC(ScriptRPCEnumeration::RPC_ScrApplyAnimation, &bs);
                });

И на выходе он не делает абсолютно ничего. Все данные по пакету получил путём чтения входящих РПС. В чём может быть проблема?
 
Решение
Чтение:
struct ApplyPlayerAnimationData
{
    UINT16 wPlayerID;
    UINT8 AnimLibLength;
    std::string AnimLib;
    UINT8 AnimNameLength;
    std::string AnimName;
    float fDelta;
    bool loop;
    bool lockx;
    bool locky;
    bool freeze;
    UINT32 dTime;
};

bool CALLBACK incomingRPC(stRakNetHookParams* data)
{
    switch (data->packetId)
    {
        case ScriptRPCEnumeration::RPC_ScrApplyAnimation:
        {
            ApplyPlayerAnimationData applyPlayerAnimationData;
            data->bitStream->Read(applyPlayerAnimationData.wPlayerID);

            data->bitStream->Read(applyPlayerAnimationData.AnimLibLength);
            applyPlayerAnimationData.AnimLib.resize((size_t)applyPlayerAnimationData.AnimLibLength, '\0')...

Yayachana)

Известный
32
10
Пытаюсь задать персонажу анимку путём эмуляции входящего RPC в SAMPFUNCS. Далее код:
C++:
SF->getSAMP()->registerChatCommand("applyAnimation", [](std::string param)->void
                {
                    UINT16 wPlayerID = SF->getSAMP()->getPlayers()->sLocalPlayerID;
                    UINT8 AnimLibLength = 4;
                    char AnimLib[4] = "PED";
                    UINT8 AnimNameLength = 10;
                    char AnimName[10] = "IDLE_HBHB";
                    float fDelta = 3.000000;
                    bool loop = false;
                    bool lockx = true;
                    bool locky = true;
                    bool freeze = true;
                    UINT32 dTime = 0;

                    BitStream bs;
                    bs.Write(wPlayerID);
                    bs.Write(AnimLibLength);
                    bs.Write(AnimLib);
                    bs.Write(AnimNameLength);
                    bs.Write(AnimName);
                    bs.Write(fDelta);
                    bs.Write(loop);
                    bs.Write(lockx);
                    bs.Write(locky);
                    bs.Write(freeze);
                    bs.Write(dTime);

                    SF->getRakNet()->emulateRecvRPC(ScriptRPCEnumeration::RPC_ScrApplyAnimation, &bs);
                });

И на выходе он не делает абсолютно ничего. Все данные по пакету получил путём чтения входящих РПС. В чём может быть проблема?
Через RPC не пробовал эмулировать, но при помощи перехвата пакета, всё работает

123:
bool CALLBACK anim(stRakNetHookParams* params)
{
    if (params->packetId == PacketEnumeration::ID_PLAYER_SYNC)
    {
        char buf[128];
        stOnFootData data;
        memset(&data, 0, sizeof(stOnFootData));
        byte packet;

        params->bitStream->ResetReadPointer();
        params->bitStream->Read(packet);
        params->bitStream->Read((PCHAR)&data, sizeof(stOnFootData));
        params->bitStream->ResetReadPointer();

        data.byteSpecialAction = ;
        data.sCurrentAnimationID = ;
        data.sAnimFlags = ;

        //sprintf_s(buf, "SpecAction: %d || AnimID: %d || AnimFlags: %d", data.byteSpecialAction, data.sCurrentAnimationID, data.sAnimFlags);
        //SF->getSAMP()->getChat()->AddChatMessage(-1, buf);

        params->bitStream->ResetWritePointer();
        params->bitStream->Write(packet);
        params->bitStream->Write((PCHAR)&data, sizeof(stOnFootData));
    };

    return true;
};


В mainloop -> SF->getRakNet()->registerRakNetCallback(RakNetScriptHookType::RAKHOOK_TYPE_OUTCOMING_PACKET, anim);
 

Ya Zaregalsya

Известный
Автор темы
370
127
Через RPC не пробовал эмулировать, но при помощи перехвата пакета, всё работает

123:
bool CALLBACK anim(stRakNetHookParams* params)
{
    if (params->packetId == PacketEnumeration::ID_PLAYER_SYNC)
    {
        char buf[128];
        stOnFootData data;
        memset(&data, 0, sizeof(stOnFootData));
        byte packet;

        params->bitStream->ResetReadPointer();
        params->bitStream->Read(packet);
        params->bitStream->Read((PCHAR)&data, sizeof(stOnFootData));
        params->bitStream->ResetReadPointer();

        data.byteSpecialAction = ;
        data.sCurrentAnimationID = ;
        data.sAnimFlags = ;

        //sprintf_s(buf, "SpecAction: %d || AnimID: %d || AnimFlags: %d", data.byteSpecialAction, data.sCurrentAnimationID, data.sAnimFlags);
        //SF->getSAMP()->getChat()->AddChatMessage(-1, buf);

        params->bitStream->ResetWritePointer();
        params->bitStream->Write(packet);
        params->bitStream->Write((PCHAR)&data, sizeof(stOnFootData));
    };

    return true;
};


В mainloop -> SF->getRakNet()->registerRakNetCallback(RakNetScriptHookType::RAKHOOK_TYPE_OUTCOMING_PACKET, anim);
Задача состоит в том, чтобы применить анимацию к локальному игроку так, чтобы эту анимку было видно у пользователя. Ты предлагаешь просто отправить фэйк синхру, а её будут видеть только другие игроки.
 

Yayachana)

Известный
32
10
Задача состоит в том, чтобы применить анимацию к локальному игроку так, чтобы эту анимку было видно у пользователя. Ты предлагаешь просто отправить фэйк синхру, а её будут видеть только другие игроки.
Хорошо, а если ты просто RPC перехватишь, сделаешь условие, которое будет проверять твой айдишник и перезапишешь нужные параметры?
 

Ya Zaregalsya

Известный
Автор темы
370
127
Хорошо, а если ты просто RPC перехватишь, сделаешь условие, которое будет проверять твой айдишник и перезапишешь нужные параметры?
По идее будет то же самое. Скорее всего косяк в том, что я неправильно записываю строки.
 

Ya Zaregalsya

Известный
Автор темы
370
127
Чтение:
struct ApplyPlayerAnimationData
{
    UINT16 wPlayerID;
    UINT8 AnimLibLength;
    std::string AnimLib;
    UINT8 AnimNameLength;
    std::string AnimName;
    float fDelta;
    bool loop;
    bool lockx;
    bool locky;
    bool freeze;
    UINT32 dTime;
};

bool CALLBACK incomingRPC(stRakNetHookParams* data)
{
    switch (data->packetId)
    {
        case ScriptRPCEnumeration::RPC_ScrApplyAnimation:
        {
            ApplyPlayerAnimationData applyPlayerAnimationData;
            data->bitStream->Read(applyPlayerAnimationData.wPlayerID);

            data->bitStream->Read(applyPlayerAnimationData.AnimLibLength);
            applyPlayerAnimationData.AnimLib.resize((size_t)applyPlayerAnimationData.AnimLibLength, '\0');
            data->bitStream->Read((PCHAR)applyPlayerAnimationData.AnimLib.data(), (size_t)applyPlayerAnimationData.AnimLibLength);

            data->bitStream->Read(applyPlayerAnimationData.AnimNameLength);
            applyPlayerAnimationData.AnimName.resize((size_t)applyPlayerAnimationData.AnimNameLength, '\0');
            data->bitStream->Read((PCHAR)applyPlayerAnimationData.AnimName.data(), (size_t)applyPlayerAnimationData.AnimNameLength);

            data->bitStream->Read(applyPlayerAnimationData.fDelta);
            data->bitStream->Read(applyPlayerAnimationData.loop);
            data->bitStream->Read(applyPlayerAnimationData.lockx);
            data->bitStream->Read(applyPlayerAnimationData.locky);
            data->bitStream->Read(applyPlayerAnimationData.freeze);
            data->bitStream->Read(applyPlayerAnimationData.dTime);
            data->bitStream->ResetReadPointer();
                   
            SF->getSAMP()->getChat()->AddChatMessage(-1,
                "PlayerId: %d; AnimLib: %s; AnimName: %s; fDelta: %f; loop: %d; lockx: %d; locky: %d; freeze: %d; dTime: %d;",
                applyPlayerAnimationData.wPlayerID,
                applyPlayerAnimationData.AnimLib.c_str(), applyPlayerAnimationData.AnimName.c_str(),
                applyPlayerAnimationData.fDelta, applyPlayerAnimationData.loop,
                applyPlayerAnimationData.lockx, applyPlayerAnimationData.locky, applyPlayerAnimationData.freeze,
                applyPlayerAnimationData.dTime);
            SF->getSAMP()->getChat()->AddChatMessage(-1,
                "AnimLibLength: %d; AnimNameLength: %d;",
                applyPlayerAnimationData.AnimLibLength, applyPlayerAnimationData.AnimNameLength);
            break;
        }
    }
    return true;
}

Запись:
UINT16 wPlayerID = SF->getSAMP()->getPlayers()->sLocalPlayerID;
INT8 AnimLibLength = 3;
char AnimLib[4] = "PED";
INT8 AnimNameLength = 10;
char AnimName[11] = "WALK_DRUNK";
float fDelta = 4.100000;
bool loop = true;
bool lockx = true;
bool locky = true;
bool freeze = true;
INT32 dTime = 1;

BitStream bs;
bs.Write(wPlayerID);
bs.Write(AnimLibLength);
bs.Write(AnimLib, AnimLibLength);
bs.Write(AnimNameLength);
bs.Write(AnimName, AnimNameLength);
bs.Write(fDelta);
bs.Write(loop);
bs.Write(lockx);
bs.Write(locky);
bs.Write(freeze);
bs.Write(dTime);

SF->getRakNet()->emulateRecvRPC(ScriptRPCEnumeration::RPC_ScrApplyAnimation, &bs);