IS4Code / YSF

YSF Server Functions
Other
98 stars 34 forks source link

CHookRakServer::Send RebuildSyncData hook #20

Closed JernejL closed 8 years ago

JernejL commented 8 years ago

Would it be possible to - in a lightweight manner override bitstream data there and for ID_PLAYER_SYNC and ID_VEHICLE_SYNC override the synced keys?

I'd just need to seek specific amout of bytes to reach wKeys for the player and vehicle sync, write a zero for keys and pass the packet forward.

Any help to do this will be much appreciated.

JernejL commented 8 years ago

Here is my attempt for vehicle sync, this doesn't work tho.. any ideas how to do this?

void RebuildSyncData(RakNet::BitStream *bsSync, WORD toplayerid) { BYTE id; WORD playerid;

bsSync->Read(id);
bsSync->Read(playerid);

if(!IsPlayerConnectedEx(playerid) || !IsPlayerConnectedEx(toplayerid)) return;

//logprintf("RebuildSyncData %d - %d", id, playerid);
switch(id)
{
    case ID_VEHICLE_SYNC:
    {

        //if (blockKeySync[playerid]) {

        bsSync->IgnoreBits(16); // vehicleid

        bool k1;

        bsSync->Read(k1);

        if (k1)
            bsSync->IgnoreBits(16); // ignore word left right

        bsSync->Read(k1);

        if (k1)
            bsSync->IgnoreBits(16); // ignore word up down

        WORD wzero = 0;

        bsSync->Write(wzero);

        break;
    }
}

}

ghost commented 8 years ago

You need to do it in the same way how I did with player sync. Maybe I'll try to do it in weekend, but not tomorrow because I won't be home.

Anyway ID_PLAYER_SYNC are "decompiled" so now you can play with syncdata, until I reverse ID_VEHICLE_SYNC.

leaked shit, you know what i'm talking about, opensamp and Ida is a very big help :D

JernejL commented 8 years ago

Could this be done without rebuilding sync? I'd rather just seek to offset and override the keys, because i only need the keys overriden and would like this done in the least invasive and most future-compatible way.

ghost commented 8 years ago

A bit too late (i just give a fuck for samp around 4-5 monts in past since I had better things in my life to do), but DO NOT USE that fucking rebuildsyncdata function because I badly reverse engineered function which sends out onfoot data and there are problems about player movement when shooting. I didn't noticed it sadly, but the veteran players said that I fucked up something for 6 monts and I didn't belive it. Now I removed this shit and everything works, they said.

I have to create a new method how to manipulate bistream without recreating the complete.

JernejL commented 8 years ago

well i think you can seek to start of bitstream and skip to the particular parts to reach key input values and override them, that sounds like a valid approach..

oscar-broman commented 8 years ago

Can't you just modify the packets in GetPacketID? Like I do in SKY to block keys in onfoot sync. No need to send new packets if you modify the incoming ones.

JernejL commented 8 years ago

I've already explained that in a sky plugin's issue, the main problem became that if i override the keys in getpacketid hook, then the script will also never know when the key was depressed (to know when to stop overriding it).

For example, i have vehicle weapons disabled when vehicle is pointing at a spawn area. I want to disable the keys and potentially do other stuff to the player trying to attack and show a warning that should disappear once keys are depressed. If i override this in getpacketid hook i have no way of knowing when they stopped holding the key to remove textdraws, objects, warnings.

So basically, i want to override outgoing keys and keep the incoming keys state original fully availible to the script to choose when to actually override it, i don't want to always override it.

tl;dr:

Getpacketid hook will override the keys before i'd know when to override them.

I want to see if a player used firing key, do my zone checks then and then override key. You could say that i do those checks continously (they are in onplayerupdate), but doing complex polygon math point checks to see if player can shoot a hydra at a given point for 150 players at once is a performance-suicide, running this on a timer is not a option either (it will miss some keypresses), so the only good option is to do it when key firing is detected (key state changed to pressed).

oscar-broman commented 8 years ago

We could just solve this issue in a different manner. Add a new callback called OnPlayerFireVehicleWeapon(playerid, vehicleid, modelid). Return 0 to prevent syncing. This would have to be called from within the GetPacketID hook, and block key sync.

Oooor just rebuild the vehicle sync packets, send them in OnPlayerUpdate (if in hydra, pressing fire key) then return 0.

ghost commented 8 years ago

To rebuild packets you need to import all structures to ida, assign pPlayer pointer under BroadcastSyncData and done. I updated ysf classes to support this, i will Post them here when i will at home. But My problem is that ida assign 4 bytes for WORD sometimes, and my dick is out whit this because its crazy idea to work with offsets.

You can do this import c classes by pressing ctrl and f9 or 9.

Classes: http://pastebin.com/NirsnW2Q Ida 6.8 if you have older: https://mega.nz/#!h1tgBTLT!ZSuYSHWmoOsO0qILg_n0mi60Q4IEBOMxouxPYgO5Szo

Let's play with them :D

Maybe you'll need to remove bit fields and some shits which Ida won't like.

JernejL commented 8 years ago

oscar: it cannot be done that way, there is A LOT of logic in onplayerupdate in my and probably other people's scripts aswell.

This would be a totally counter-logical way of getting it work, for example your suggested OnPlayerFireVehicleWeapon - that would actually trigger BEFORE all getplayerpos, getplayerhealth etc.. internal data would be updated, making it not actually work on correct current data at all, but previous frame's data.

ghost commented 8 years ago

http://pastebin.com/wkWvfmhh

E: https://github.com/kurta999/YSF/commit/4c60265fd2462043c271a5face12980ac7d625c5

oscar-broman commented 8 years ago

Why can't you just modify the sync data in CPlayer during OnPlayerUpdate?

BTW, players will still be able to use Esc to glide into protected areas (while holding lmb) and fire bombs.

ghost commented 8 years ago

I think I can now close this issue, since main problem has been solved.

"I'd just need to seek specific amout of bytes to reach wKeys for the player and vehicle sync, write a zero for keys and pass the packet forward."

In future if I'll find a good way to do this, without rebuilding complete sync data, i'll do it.

JernejL commented 8 years ago

Kurta: i think the ignorebits() approach i attempted here: https://github.com/kurta999/YSF/issues/20#issuecomment-152488580 would be likely possible to make it work.