From 3a3b4ab7e2bd963ca9c730d513db0b77ccc3ba5f Mon Sep 17 00:00:00 2001 From: yugecin Date: Sat, 4 Apr 2020 05:10:14 +0200 Subject: [PATCH] replace ProcessNetworkPacket --- nethandler.c | 2 + packet.c | 15 +++++ packet.h | 15 +++++ processnetworkpacket.c | 132 +++++++++++++++++++++++++++++++++++++++++ processnetworkpacket.h | 11 ++++ rakpeer.c | 64 +++++++++++++++++++- rakpeer.h | 35 +++++++++-- reliability.c | 25 ++++++++ reliability.h | 11 ++++ samp-re.vcproj | 32 ++++++++++ socketlayer.c | 18 ++++++ socketlayer.h | 9 +++ 12 files changed, 362 insertions(+), 7 deletions(-) create mode 100644 packet.c create mode 100644 packet.h create mode 100644 processnetworkpacket.c create mode 100644 processnetworkpacket.h create mode 100644 reliability.c create mode 100644 reliability.h create mode 100644 socketlayer.c create mode 100644 socketlayer.h diff --git a/nethandler.c b/nethandler.c index aa41b9f..ccac8cb 100644 --- a/nethandler.c +++ b/nethandler.c @@ -3,6 +3,7 @@ #include "common.h" #include "rakpeer.h" +#include "processnetworkpacket.h" #include "uncompress.h" #include #include @@ -20,6 +21,7 @@ void simple_redir_call(void *address, void *newtarget) void nethandler_init() { simple_redir_call(UNCOMPRESS_TARGET, uncompress_main); + simple_redir_call(RP_PARSE_NETWORK_PACKET, ProcessNetworkPacket); simple_redir_call(RP_PARSE_CONNECTION_REQ, RakPeer__ParseConnectionRequestPacket); } diff --git a/packet.c b/packet.c new file mode 100644 index 0000000..b56d927 --- /dev/null +++ b/packet.c @@ -0,0 +1,15 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#include "common.h" +#include "rakpeer.h" +#include "packet.h" + +__declspec(naked) +struct CPacket* __cdecl Packet__AllocPacket(int bitSize) +{ + _asm { + mov eax, 0x44FDE0 + jmp eax + } +} diff --git a/packet.h b/packet.h new file mode 100644 index 0000000..156eac0 --- /dev/null +++ b/packet.h @@ -0,0 +1,15 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#pragma pack(push,1) +struct CPacket { + short playerIndex; + struct PlayerID playerId; + char _pad[2]; + int bitSize; + char *ptrData; + char deleteData; +}; +#pragma pack(pop) + +struct CPacket* __cdecl Packet__AllocPacket(int bitSize); diff --git a/processnetworkpacket.c b/processnetworkpacket.c new file mode 100644 index 0000000..0da30f4 --- /dev/null +++ b/processnetworkpacket.c @@ -0,0 +1,132 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#define PROCESSNETWORKPACKET_PRINT + +#ifdef PROCESSNETWORKPACKET_PRINT +#define dprintf(X,...) printf(X,__VA_ARGS__) +#else +#define dprintf(X,...) +#endif + +#include "common.h" +#include "rakpeer.h" +#include "processnetworkpacket.h" +#include "socketlayer.h" +#include "packet.h" +#include "reliability.h" +#include +#include +#include + +static +void ShortResponse(struct CRakPeer *rp, int host, int port, char id) +{ + char buf[2]; + + buf[0] = id; + buf[1] = 0; /*padding cuz 1 byte packet may not get sent*/ + SocketLayer__SendTo(rp->socket, buf, 2, host, port); +} + +static +void HandleConnectedPlayerTryingToConnect( + struct CRakPeer *rp, + struct CRemoteSystem *remoteSystem, + int host, + int port) +{ + if (remoteSystem->connectMode != CONNECTED && + remoteSystem->connectMode != DISCONNECT_ASAP && + remoteSystem->connectMode != DISCONNECT_ASAP_SILENTLY) + { + dprintf("is from connected player, ignore\n"); + return; + } + + dprintf("is from disconnected player, send that it failed\n"); + ShortResponse(rp, host, port, ID_CONNECTION_ATTEMPT_FAILED); +} + +static +void HandleConnectingPlayer( + struct CRakPeer *rp, + struct CRemoteSystem *rs, + int host, + short port, + char *data, + int length) +{ +#define assignRemoteSystem RakPeer__AssignPlayerIDToRemoteSystemList + + struct CPacket *packet; + struct PlayerID playerId; + short playerIndex; + + /*connection cookies, but we don't do that*/ + + if (rs != NULL) { + dprintf("connection request is from already connected playa\n"); + HandleConnectedPlayerTryingToConnect(rp, rs, host, port); + return; + } + + dprintf("it's a new player\n"); + playerId.binaryAddress = host; + playerId.port = port; + + if (!assignRemoteSystem(rp, playerId, UNVERIFIED_SENDER)) { + dprintf("server is full\n"); + ShortResponse(rp, host, port, ID_NO_FREE_INCOMING_CONNECTIONS); + return; + } + + playerIndex = RakPeer__GetIndexFromPlayerID(rp, playerId, 1); + dprintf("assigned index %hd\n", playerIndex); + + packet = Packet__AllocPacket(1); + packet->playerId = playerId; + packet->bitSize = 8; + packet->playerIndex = playerIndex; + packet->ptrData[0] = ID_OPEN_CONNECTION_REQUEST; + RakPeer__AddPacketToProducer(rp, packet); + + ShortResponse(rp, host, port, ID_OPEN_CONNECTION_REPLY); +} + +void __stdcall ProcessNetworkPacket( + int host, + short port, + char *data, + int length, + struct CRakPeer *rp) +{ + struct CRemoteSystem *rs; + struct PlayerID playerId; + int isPacketFlood; + + playerId.binaryAddress = host; + playerId.port = port; + + if (data[0] == ID_OPEN_CONNECTION_REQUEST && length == 3) { + dprintf("got connection request\n"); + rs = RakPeer__GetRemoteSystemFromPlayerID(rp, playerId, 1, 1); + HandleConnectingPlayer(rp, rs, host, port, data, length); + return; + } + + rs = RakPeer__GetRemoteSystemFromPlayerID(rp, playerId, 1, 1); + if (!rs) { + dprintf("incoming from UNCONNECTED, ignoring\n"); + return; + } + + ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( + (void*) &rs->reliabilityLayer, + data, + length, + playerId, + &rp->messageHandlerList, + rp->MTUSize, + &isPacketFlood); +} diff --git a/processnetworkpacket.h b/processnetworkpacket.h new file mode 100644 index 0000000..e894d01 --- /dev/null +++ b/processnetworkpacket.h @@ -0,0 +1,11 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#define RP_PARSE_NETWORK_PACKET ((void*) 0x462C21) + +void __stdcall ProcessNetworkPacket( + int binaryAddress, + short port, + char *data, + int length, + struct CRakPeer *rakPeer); diff --git a/rakpeer.c b/rakpeer.c index a1d43d9..7cc21f5 100644 --- a/rakpeer.c +++ b/rakpeer.c @@ -9,10 +9,70 @@ #include #include +__declspec(naked) +int __stdcall RakPeer__GetIndexFromPlayerID( + struct CRakPeer *this, + struct PlayerID playerId, + char calledFromNetworkThread) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x453A40 + jmp eax + } +} + +__declspec(naked) +int __stdcall RakPeer__AddPacketToProducer( + struct CRakPeer *this, + struct CPacket *packet) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x4523D0 + jmp eax + } +} + +__declspec(naked) +int __stdcall RakPeer__AssignPlayerIDToRemoteSystemList( + struct CRakPeer *this, + struct PlayerID playerId, + int connectionMode) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x455E00 + jmp eax + } +} + +__declspec(naked) +struct CRemoteSystem* __stdcall RakPeer__GetRemoteSystemFromPlayerID( + struct CRakPeer *this, + struct PlayerID playerId, + char calledFromNetworkThread, + char onlyActive) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x453AF0 + jmp eax + } +} + static int __declspec(naked) RakPeer__OnConnectionRequest( struct CRakPeer *this, - struct CRakPeer__RemoteSystemStruct *remoteSystem, + struct CRemoteSystem *remoteSystem, char *AESKey, char setAESkey) { @@ -88,7 +148,7 @@ short __declspec(naked) RakPeer__AllowIncomingConnectionsInternal( static void RakPeer__ParseConnectionRequestPacketInternal( struct CRakPeer *this, - struct CRakPeer__RemoteSystemStruct *remoteSystem, + struct CRemoteSystem *remoteSystem, struct PlayerID playerId, char *data, char byteSize) diff --git a/rakpeer.h b/rakpeer.h index f991899..56f3dd7 100644 --- a/rakpeer.h +++ b/rakpeer.h @@ -16,11 +16,12 @@ #define ID_CONNECTION_REQUEST 0x0B #define ID_OPEN_CONNECTION_REQUEST 0x18 #define ID_OPEN_CONNECTION_REPLY 0x19 -#define ID_CONNECTION_ATTEMPT_FAILED 0x1D +#define ID_CONNECTION_ATTEMPT_FAILED 0x1D /*results in server did not respond*/ #define ID_NEW_INCOMING_CONNECTION 0x1E #define ID_NO_FREE_INCOMING_CONNECTIONS 0x1F #define ID_CONNECTION_BANNED 0x24 #define ID_INVALID_PASSWORD 0x25 +#define ID_MODIFIED_PACKET 0x26 #define SYSTEM_PRIORITY 0 #define HIGH_PRIORITY 1 @@ -40,9 +41,9 @@ struct PlayerID { }; EXPECT_SIZE(struct PlayerID, 0x8); -struct CRakPeer__RemoteSystemStruct { +struct CRemoteSystem { char _pad0[0x10-0x0]; - void *reliabilityLayer; + int reliabilityLayer; char _pad14[0x778-0x14]; int lowestPing; int nextPingTime; @@ -70,17 +71,41 @@ struct CRakPeer { unsigned char incomingPasswordLength; char _pad33B[0x33C-0x33B]; struct CRakPeer__RemoteSystemStruct *remoteSystemList; - char _pad340[0x7DC-0x340]; + char _pad340[0x3B8-0x340]; + int messageHandlerList; + char _pad3BC[0x7DC-0x3BC]; void *inputTree; /*HuffmanEncodingTree**/ void *outputTree; /*HuffmanEncodingTree**/ char _pad7E4[0xC0C-0x7E4]; int MTUSize; - char _padC10[0xD95-0xC10]; + char _padC18[0xC18-0xC10]; + void *socket; + char _padC1C[0xD95-0xC1C]; char usingSecurity; /*incomplete*/ }; #pragma pack(pop) +int __stdcall RakPeer__GetIndexFromPlayerID( + struct CRakPeer *this, + struct PlayerID playerId, + char calledFromNetworkThread); + +int __stdcall RakPeer__AddPacketToProducer( + struct CRakPeer *this, + struct CPacket *packet); + +int __stdcall RakPeer__AssignPlayerIDToRemoteSystemList( + struct CRakPeer *this, + struct PlayerID playerId, + int connectionMode); + +struct CRemoteSystem* __stdcall RakPeer__GetRemoteSystemFromPlayerID( + struct CRakPeer *this, + struct PlayerID playerId, + char calledFromNetworkThread, + char onlyActive); + /** int __thiscall RakPeer__ParseConnectionRequestPacket( CRakPeer *this, diff --git a/reliability.c b/reliability.c new file mode 100644 index 0000000..7c4d991 --- /dev/null +++ b/reliability.c @@ -0,0 +1,25 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#include "common.h" +#include "rakpeer.h" +#include "reliability.h" + +__declspec(naked) +int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( + struct CReliabilityLayer *this, + char *buffer, + int length, + struct PlayerID playerId, + void *messageHandlerList, + int MTUSize, + int *ptrOutIsPacketFlood) +{ + _asm { + pop eax + pop ecx + push eax + mov eax, 0x45F7E0 + jmp eax + } +} diff --git a/reliability.h b/reliability.h new file mode 100644 index 0000000..bc595b0 --- /dev/null +++ b/reliability.h @@ -0,0 +1,11 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer( + struct CReliabilityLayer *this, + char *buffer, + int length, + struct PlayerID playerId, + void *messageHandlerList, + int MTUSize, + int *ptrOutIsPacketFlood); diff --git a/samp-re.vcproj b/samp-re.vcproj index 3808e7b..96b9ae0 100644 --- a/samp-re.vcproj +++ b/samp-re.vcproj @@ -101,10 +101,26 @@ RelativePath=".\nethandler.c" > + + + + + + + + @@ -113,6 +129,22 @@ RelativePath=".\rakpeer.h" > + + + + + + + + diff --git a/socketlayer.c b/socketlayer.c new file mode 100644 index 0000000..4c20c26 --- /dev/null +++ b/socketlayer.c @@ -0,0 +1,18 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +#include "socketlayer.h" + +__declspec(naked) +int __stdcall SocketLayer__SendTo( + void *socket, + char *buf, + int len, + int host, + short port) +{ + _asm { + mov eax, 0x462C50 + jmp eax + } +} diff --git a/socketlayer.h b/socketlayer.h new file mode 100644 index 0000000..1f3be7c --- /dev/null +++ b/socketlayer.h @@ -0,0 +1,9 @@ + +/* vim: set filetype=c ts=8 noexpandtab: */ + +int __stdcall SocketLayer__SendTo( + void *socket, + char *buf, + int len, + int host, + short port);