s1lentq / reapi

AMX Mod X module, using API regamedll & rehlds
GNU General Public License v3.0
161 stars 103 forks source link

Issue with Hooking PM_AirMove for changing user air-acceleration. #171

Open MaNaReaver opened 4 years ago

MaNaReaver commented 4 years ago

Hi s1lentq!

I've been facing issues with hooking PM_AirMove on ReHLDS, as there are clashes occuring with client's and the server's air-acceleration, which seem to cause client misprediction and therefore high amounts of chokes, even with high rate values.

This is the plugin I've been using, that uses this feature: https://forums.alliedmods.net/showpost.php?p=2540925&postcount=76

I've discussed the issue in fair amount on this thread: https://forums.alliedmods.net/showthread.php?t=326075

Thanks for assisting me out!

Best regards, MaNaReaver.

MaNaReaver commented 4 years ago

Hi again!

I wanted to update on this issue, as this also occurs when any variable in the MoveVars array is changed to a value that goes against the set server value using a hook chain.

An example to the issue, which was rectified after commenting out set_movevar(mv_gravity): https://dev-cs.ru/threads/5426/

This issue doesn't occur with Orpheu+HLDS: https://forums.alliedmods.net/showpost.php?p=1555428&postcount=24 , which deals with this issue using another but similar logic, however it uses a module for hooking/unhooking and orpheu signatures that involve changing binary information, which wouldn't work with ReHLDS.

I'd like to hear more about this from you or any other contributors on this project, as it's been around two months since this post, and I think a proper discussion could help you understand the issue more closely to fix it sooner.

Thanks and best regards, MaNaReaver.

etojuice commented 4 years ago

This issue doesn't occur with Orpheu+HLDS: https://forums.alliedmods.net/showpost.php?p=1555428&postcount=24

The issue doesn't occur because the plugin sends SVC_NEWMOVEVARS

MaNaReaver commented 4 years ago

Could you work on integrating this into ReAPI so that set_movevar is functional?

MaNaReaver commented 4 years ago

@etojuice @s1lentq Wanted to get back on this issue, I tried integrating the features from Arkshine's plugin into ReAPI, but as expected, it doesn't work. Sending SVC_NEWMOVEVARS with another movevars enum doesn't do anything either. Registering and Unregistering the HookChain didn't work as well. The issue seems to be how ReAPI is dealing with set_movevar, which is causing the massive amounts of chokes. Let me know what you think about this.

khanghugo commented 4 months ago

I got linked to this issue. As long as you write the message correctly, it should work. Check romanian-jumpers.com servers where they have working AA toggles (100AA for individual player while sv_airaccelerate 10 is the server cvar).

I have a working implementation but only for ReGameDLL_CS (C++). Feel free to adapt to AmxModX or whatever.

    // 44 is SvcNewMovevars
    MESSAGE_BEGIN(MSG_ONE, 44, nullptr, pevToucher);
        Message_WriteFloat(m_fGravity); // gravity
        Message_WriteFloat(100.f); // stop_speed
        Message_WriteFloat(320.f); // max_speed
        Message_WriteFloat(500.f); // spectator max speed
        Message_WriteFloat(m_fAccelerate);; // accelerate
        Message_WriteFloat(m_fAirAccelerate); // airaccelerate
        Message_WriteFloat(m_fWaterAccelerate); // water accelerate
        Message_WriteFloat(m_fFriction); // friction
        Message_WriteFloat(m_fEdgeFriction); // edge friction
        Message_WriteFloat(1.f); // water friction
        Message_WriteFloat(1.f); // ent_gravity
        Message_WriteFloat(1.f); // bounce
        Message_WriteFloat(18.f); // step size
        Message_WriteFloat(2000.f); // max velocity
        Message_WriteFloat(7000.f); // z max
        Message_WriteFloat(0.f); // wave height
        WRITE_BYTE(1); // foot step
        Message_WriteFloat(0.f); // roll angle
        Message_WriteFloat(0.f); // roll speed
        Message_WriteFloat(0.f); // skycolor r 
        Message_WriteFloat(0.f); // skycolor g 
        Message_WriteFloat(0.f); // skycolor b 
        Message_WriteFloat(0.f); // skyvec r 
        Message_WriteFloat(0.f); // skyvec g 
        Message_WriteFloat(0.f); // skyvec b 
        WRITE_STRING(m_szSkyName); // skyname
    MESSAGE_END();

...

void Message_WriteFloat(float f)
{
    // Union hack
    // https://stackoverflow.com/questions/24420246/c-function-to-convert-float-to-byte-array
    union
    {
        float a;
        unsigned char bytes[4];
    } thing;

    thing.a = f;

    for (int i = 0; i < 4; ++i)
        WRITE_BYTE(thing.bytes[i]);
}

Note that some of these values are wrong, and also you shouldn't use MSG_ONE because you might overflow reliable channel if things go wrong. I implemented this specifically for single player mode.

Here are the correct values as I rip them from a typical KZ demo.

MoveVars { gravity: 800.0, stopspeed: 75.0, maxspeed: 320.0, spectatormaxspeed: 500.0, accelerate: 5.0, airaccelerate: 10.0, wateraccelerate: 10.0, friction: 4.0, edgefriction: 2.0, waterfriction: 1.0, entgravity: 1.0, bounce: 1.0, stepsize: 18.0, maxvelocity: 2000.0, zmax: 4096.0, wave_height: 0.0, footsteps: 1, sky_name: [100, 101, 115, 101, 114, 116, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], rollangle: 0.0, rollspeed: 0.0, skycolor_r: 0.0, skycolor_g: 0.0, skycolor_b: 0.0, skyvec_x: 1.0, skyvec_y: 0.0, skyvec_z: 0.0 }