slightly more of HandleSocketReceiveFromConnectedPlayer

This commit is contained in:
yugecin 2020-04-05 00:47:06 +02:00
parent a7aa10a637
commit 6f436ead4d
No known key found for this signature in database
GPG Key ID: BB3591E3D68964DE
5 changed files with 306 additions and 46 deletions

50
common.c Normal file
View File

@ -0,0 +1,50 @@
/* vim: set filetype=c ts=8 noexpandtab: */
#include "common.h"
__declspec(naked)
void __stdcall RangeList__ctor(struct CRangeList *this)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45F2D0
jmp eax
}
}
__declspec(naked)
void __stdcall RangeList__dtor(struct CRangeList *this)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45F300
jmp eax
}
}
__declspec(naked)
int __stdcall BPlusTree__IsEmpty(void *this)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45B570
jmp eax
}
}
int RaknetTimeNS_IsBigger(
struct CRaknetTimeNS isbigger,
struct CRaknetTimeNS than)
{
if (isbigger.hi32 > than.hi32) {
return 1;
}
return isbigger.hi32 == than.hi32 && isbigger.lo32 > than.lo32;
}

View File

@ -22,18 +22,24 @@ struct CList {
EXPECT_SIZE(struct CList, 0xC); EXPECT_SIZE(struct CList, 0xC);
struct COrdenedList { struct COrdenedList {
struct CList _parent; struct CList _;
}; };
EXPECT_SIZE(struct COrdenedList, 0xC); EXPECT_SIZE(struct COrdenedList, 0xC);
struct CRangeList { struct CRangeList {
struct COrdenedList _parent; struct COrdenedList _;
}; };
EXPECT_SIZE(struct CRangeList, 0xC); EXPECT_SIZE(struct CRangeList, 0xC);
struct CRangeNode_Short {
short minIndex;
short maxIndex;
};
EXPECT_SIZE(struct CRangeNode_Short, 0x4);
struct CRaknetTimeNS { struct CRaknetTimeNS {
int lo32; unsigned int lo32;
int hi32; unsigned int hi32;
}; };
EXPECT_SIZE(struct CRaknetTimeNS, 0x8); EXPECT_SIZE(struct CRaknetTimeNS, 0x8);
@ -78,7 +84,9 @@ struct CReliabilityLayer {
/*3C4*/ char _pad3C4[0x4]; /*3C4*/ char _pad3C4[0x4];
/*3C8*/ unsigned int statistics_bitsReceivedLo32; /*3C8*/ unsigned int statistics_bitsReceivedLo32;
/*3CC*/ unsigned int statistics_bitsReceivedHi32; /*3CC*/ unsigned int statistics_bitsReceivedHi32;
/*3D0*/ char _pad3D0[0x10]; /*3D0*/ char _pad3D0[0x8];
/*3D8*/ int statistics_acksReceived;
/*3DC*/ char _pad3DC[0x4];
/*3E0*/ int statistics_messagesReceived; /*3E0*/ int statistics_messagesReceived;
/*3E4*/ char _pad3E4[0x4]; /*3E4*/ char _pad3E4[0x4];
/*3E8*/ int statistics_duplicateMessagesReceived; /*3E8*/ int statistics_duplicateMessagesReceived;
@ -90,7 +98,7 @@ struct CReliabilityLayer {
/*436*/ char resetReceivedPackets; /*436*/ char resetReceivedPackets;
/*437*/ char _pad437[0x11]; /*437*/ char _pad437[0x11];
/*448*/ struct CRaknetTimeNS histogramStartTime; /*448*/ struct CRaknetTimeNS histogramStartTime;
/*450*/ int histogramReceiveMarker; /*450*/ unsigned int histogramReceiveMarker;
/*454*/ char _pad454[0x8]; /*454*/ char _pad454[0x8];
/*45C*/ int histogramAckCount; /*45C*/ int histogramAckCount;
/*460*/ char _pad460[0x24]; /*460*/ char _pad460[0x24];
@ -103,7 +111,29 @@ struct CReliabilityLayer {
/*728*/ void *internalPacketPool; /*728*/ void *internalPacketPool;
}; };
EXPECT_SIZE(struct CReliabilityLayer, 0x72C); EXPECT_SIZE(struct CReliabilityLayer, 0x72C);
struct CInternalPacket {
/*000*/ short messageNumber;
/*002*/ char _pad2[0x6];
/*008*/ int packetPriority;
/*00C*/ int packetReliability;
/*010*/ char orderingChannel;
/*011*/ char _pad11[0x1];
/*012*/ short orderingIndex;
/*014*/ short splitPacketId;
/*016*/ char _pad16[0x6];
/*01C*/ int splitPacketCount;
/*020*/ struct CRaknetTimeNS creationTime;
/*028*/ struct CRaknetTimeNS nextActionTime;
/*030*/ int numberOfBitsToSend;
/*034*/ char *pData;
};
EXPECT_SIZE(struct CInternalPacket, 0x38);
#pragma pack(pop) #pragma pack(pop)
void __stdcall __RangeList__ctor(struct CRangeList *this); void __stdcall RangeList__ctor(struct CRangeList *this);
void __stdcall __RangeList__dtor(struct CRangeList *this); void __stdcall RangeList__dtor(struct CRangeList *this);
int __stdcall BPlusTree__IsEmpty(void *this);
int RaknetTimeNS_IsBigger(
struct CRaknetTimeNS isbigger,
struct CRaknetTimeNS than);

View File

@ -1,28 +0,0 @@
/* vim: set filetype=c ts=8 noexpandtab: */
#include "common.h"
__declspec(naked)
void __stdcall __RangeList__ctor(struct CRangeList *this)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45F2D0
jmp eax
}
}
__declspec(naked)
void __stdcall __RangeList__dtor(struct CRangeList *this)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45F300
jmp eax
}
}

View File

@ -15,6 +15,201 @@
#include "reliability.h" #include "reliability.h"
#include <stdio.h> #include <stdio.h>
__declspec(naked)
static
void RangeList_Short__Insert(
void *this,
short value)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45E0C0
jmp eax
}
}
static
void SendAckForPacket(
struct CReliabilityLayer *this,
struct CInternalPacket *packet)
{
if (packet->packetReliability != RELIABLE_SEQUENCED ||
packet->packetReliability != RELIABLE_ORDENED ||
packet->packetReliability != RELIABLE)
{
return;
}
this->statistics_acknowlegementsSent++;
/*acknowlegements is probably an inlined struct*/
RangeList_Short__Insert(&this->acknowlegements, packet->messageNumber);
}
static
void HandlePacket(
struct CReliabilityLayer *this,
struct CInternalPacket *packet)
{
SendAckForPacket(this, packet);
// here lol @45FC87
}
__declspec(naked)
static
struct CInternalPacket *
__stdcall ReliabilityLayer__CreateInternalPacketFromBitStream(
struct CReliabilityLayer *this,
struct CBitStream *bitstream,
struct CRaknetTimeNS time)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45C000
jmp eax
}
}
static
__declspec(naked)
int __stdcall RangeList__Deserialize(
struct CRangeList *this,
struct CBitStream *bitStream)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45E2D0
jmp eax
}
}
/*ReliabilityLayer__RemovePacketFromResendListAndDeleteOlderReliableSequenced*/
__declspec(naked)
int __stdcall ReliabilityLayer__RemovePacketsConfirmedByAck(
struct CReliabilityLayer *this,
short ackMessageNumber,
struct CRaknetTimeNS time)
{
_asm {
pop eax
pop ecx
push eax
mov eax, 0x45EC40
jmp eax
}
}
static
void UpdateHistogramAckCount(
struct CReliabilityLayer *this,
struct CRaknetTimeNS timeNS,
unsigned int ackedCounter)
{
if (!RaknetTimeNS_IsBigger(this->histogramStartTime, timeNS)) {
return;
}
if (ackedCounter == (unsigned int) -1) {
return;
}
if (ackedCounter != this->histogramReceiveMarker) {
return;
}
this->histogramAckCount++;
}
static
void HandleAcksForMessageRange(
struct CReliabilityLayer *this,
short minMessageNumber,
short maxMessageNumber,
struct CRaknetTimeNS timeNS)
{
unsigned int ackedCounter;
short msgNum;
/*messageholelimit checked here?*/
for (msgNum = minMessageNumber; msgNum < maxMessageNumber; msgNum++) {
ackedCounter = ReliabilityLayer__RemovePacketsConfirmedByAck(
this,
msgNum,
timeNS);
UpdateHistogramAckCount(this, timeNS, ackedCounter);
/*resendList is not a pointer but
inlined struct that hasn't been defined yet*/
if (BPlusTree__IsEmpty(&this->resendList)) {
this->lastAckTime.lo32 = 0;
this->lastAckTime.hi32 = 0;
continue;
}
this->lastAckTime = timeNS;
}
}
/**
@return 0 if it did not contain valid acks
*/
static
int HandleAcks(
struct CReliabilityLayer *this,
struct CBitStream *bitStream,
struct CRaknetTimeNS timeNS)
{
struct CRangeList incomingAcksList;
struct CRangeNode_Short *ranges;
int amountOfAckRanges, ackRangeIdx;
int containedValidAcks;
short minMsg, maxMsg;
dprintf("reading ackslist, position is %d\n", bitStream->readOffset);
RangeList__ctor(&incomingAcksList);
if (!RangeList__Deserialize(&incomingAcksList, bitStream)) {
dprintf("could not deserialize ackslist\n");
RangeList__dtor(&incomingAcksList);
return 0;
}
dprintf("position after reading is %d\n", bitStream->readOffset);
amountOfAckRanges = incomingAcksList._._.list_size;
if (amountOfAckRanges == 0) {
dprintf("ackslist is empty\n");
RangeList__dtor(&incomingAcksList);
return 1;
}
containedValidAcks = 0;
ranges = (struct CRangeNode_Short*) incomingAcksList._._.values;
for (ackRangeIdx = 0; ackRangeIdx < amountOfAckRanges; ackRangeIdx++) {
minMsg = ranges[ackRangeIdx].minIndex;
maxMsg = ranges[ackRangeIdx].maxIndex;
if (minMsg > maxMsg) {
dprintf("invalid ack range %hd>%hd\n", minMsg, maxMsg);
continue;
}
containedValidAcks = 1;
HandleAcksForMessageRange(this, minMsg, maxMsg, timeNS);
/*ackslimit checked here*/
}
RangeList__dtor(&incomingAcksList);
return containedValidAcks;
}
/** /**
seems like a nop seems like a nop
*/ */
@ -47,10 +242,13 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
int MTUSize, int MTUSize,
int *ptrOutIsPacketFlood) int *ptrOutIsPacketFlood)
{ {
struct CInternalPacket *packet;
struct CBitStream bitStream; struct CBitStream bitStream;
struct CRaknetTimeNS time; struct CRaknetTimeNS timeNS;
struct CRangeList incomingAcks; char hasAcks, wereAcksHandled;
char hasAcks; int returnValue;
dprintf("HandleSocketReceiveFromConnectedPlayerStart\n");
if (length == 1 || buffer == NULL) { if (length == 1 || buffer == NULL) {
dprintf("ignoring length %d buffer %p\n", length, buffer); dprintf("ignoring length %d buffer %p\n", length, buffer);
@ -62,15 +260,25 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
AddBitsReceivedStatistic(this, length * 8); AddBitsReceivedStatistic(this, length * 8);
BitStream__ctor(&bitStream, buffer, length, 0); BitStream__ctor(&bitStream, buffer, length, 0);
RakNet__GetTimeNS(&time); RakNet__GetTimeNS(&timeNS);
__RangeList__ctor(&incomingAcks);
wereAcksHandled = 0;
BitStream__Read(&bitStream, &hasAcks); BitStream__Read(&bitStream, &hasAcks);
if (hasAcks) { if (hasAcks) {
dprintf("hasacks\n"); dprintf("has acks\n");
wereAcksHandled = HandleAcks(this, &bitStream, timeNS);
}
returnValue = wereAcksHandled;
while (packet = ReliabilityLayer__CreateInternalPacketFromBitStream(
this, &bitStream, timeNS))
{
returnValue = 1;
HandlePacket(this, packet);
} }
__RangeList__dtor(&incomingAcks); this->receivePacketCount++;
BitStream__dtor(&bitStream); BitStream__dtor(&bitStream);
return 0; dprintf("HandleSocketReceiveFromConnectedPlayerEnd\n");
return returnValue;
} }

View File

@ -102,11 +102,11 @@
> >
</File> </File>
<File <File
RelativePath=".\common.h" RelativePath=".\common.c"
> >
</File> </File>
<File <File
RelativePath=".\datastructures.c" RelativePath=".\common.h"
> >
</File> </File>
<File <File