complete HandleSocketReceiveFromConnectedPlayer

It doesn't fully work though. Player gets connected, but can't get to
class selection. GameModeText (from Grand Larceny) does appear. Maybe
an ack issue?
This commit is contained in:
yugecin 2020-04-05 21:10:03 +02:00
parent a4a19a8614
commit 495fa7d745
No known key found for this signature in database
GPG Key ID: BB3591E3D68964DE
4 changed files with 136 additions and 10 deletions

View File

@ -3,6 +3,15 @@
#include "common.h" #include "common.h"
__declspec(naked)
void j__free(void *ptr)
{
_asm {
mov eax, 0x49AAA8
jmp eax
}
}
__declspec(naked) __declspec(naked)
void * __stdcall Queue_AtPosition_QWORD(struct CQueue *queue, int position) void * __stdcall Queue_AtPosition_QWORD(struct CQueue *queue, int position)
{ {

View File

@ -7,6 +7,7 @@
#define EXPECT_SIZE(S,SIZE) STATIC_ASSERT(sizeof(S)==(SIZE)) #define EXPECT_SIZE(S,SIZE) STATIC_ASSERT(sizeof(S)==(SIZE))
#define DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE 0x200 #define DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE 0x200
#define NUMBER_OF_ORDERED_STREAMS 0x20
#pragma pack(push, 1) #pragma pack(push, 1)
struct PlayerID { struct PlayerID {
@ -39,6 +40,20 @@ struct CRangeNode_Short {
}; };
EXPECT_SIZE(struct CRangeNode_Short, 0x4); EXPECT_SIZE(struct CRangeNode_Short, 0x4);
struct CListNode_DWORD {
void *value;
struct CListNode_DWORD *prev;
struct CListNode_DWORD *next;
};
EXPECT_SIZE(struct CListNode_DWORD, 0xC);
struct CCircularLinkedList {
unsigned int list_size;
void *root;
void *position;
};
EXPECT_SIZE(struct CCircularLinkedList, 0xC);
struct CRaknetTimeNS { struct CRaknetTimeNS {
unsigned int lo32; unsigned int lo32;
unsigned int hi32; unsigned int hi32;
@ -154,6 +169,7 @@ EXPECT_SIZE(struct CInternalPacket, 0x38);
#define QUEUE_POP_IGNOREVALUE(X) \ #define QUEUE_POP_IGNOREVALUE(X) \
(X.head = (X.head+1 == X.allocationSize) ? 0 : (X.head+1)) (X.head = (X.head+1 == X.allocationSize) ? 0 : (X.head+1))
void j__free(void *ptr);
void * __stdcall Queue_AtPosition_QWORD(struct CQueue *queue, int position); void * __stdcall Queue_AtPosition_QWORD(struct CQueue *queue, int position);
void __stdcall Queue_Push_QWORD(struct CQueue *queue, void *value); void __stdcall Queue_Push_QWORD(struct CQueue *queue, void *value);
void __stdcall Queue_Push_DWORD(struct CQueue *queue, void *value); void __stdcall Queue_Push_DWORD(struct CQueue *queue, void *value);

View File

@ -84,6 +84,8 @@ int HandlePacketHole(
return 1; return 1;
} }
dprintf("packet hole is %d\n", holeSize);
if (holeSize > 0x8000) { if (holeSize > 0x8000) {
/*? underflow apparently*/ /*? underflow apparently*/
this->statistics_duplicateMessagesReceived++; this->statistics_duplicateMessagesReceived++;
@ -153,27 +155,123 @@ void CompressMessageHoleQueue(struct CReliabilityLayer *this)
thiscall0((void*) 0x45B6C0, &this->hasReceivedPacketQueue); thiscall0((void*) 0x45B6C0, &this->hasReceivedPacketQueue);
} }
static
void DiscardPacket(
struct CReliabilityLayer *this,
struct CInternalPacket *packet)
{
j__free(packet->pData);
thiscall1((void*) 0x44EBF0, &this->internalPacketPool, (int) packet);
}
static static
int HandleSequencedPacket( int HandleSequencedPacket(
struct CReliabilityLayer *this, struct CReliabilityLayer *this,
struct CInternalPacket *packet) struct CInternalPacket *packet)
{ {
char channel;
short waitingIndex;
short newIndex;
if (packet->packetReliability != RELIABLE_SEQUENCED || if (packet->packetReliability != RELIABLE_SEQUENCED ||
packet->packetReliability != UNRELIABLE_SEQUENCED) packet->packetReliability != UNRELIABLE_SEQUENCED)
{ {
return 0; return 0;
} }
channel = packet->orderingChannel;
if (channel >= NUMBER_OF_ORDERED_STREAMS) {
DiscardPacket(this, packet);
return 1; return 1;
} }
waitingIndex = this->waitingForSequencedPacketReadIndex[channel];
newIndex = packet->orderingIndex;
/*isOlderSequencedPacked*/
if (thiscall2((void*) 0x45B3D0, this, newIndex, waitingIndex)) {
this->statistics_sequencedMessagesOutOfOrder++;
DiscardPacket(this, packet);
return 1;
}
this->statistics_sequencedMessagesInOrder++;
/*ignoring split packet code @0x460098*/
this->waitingForSequencedPacketReadIndex[channel] = newIndex + 1;
Queue_Push_DWORD(&this->outputQueue, &packet);
return 1;
}
static
void OutputNowInOrderPackets(
struct CReliabilityLayer *this,
struct CCircularLinkedList *orderingList,
short *waitingForIndex)
{
struct CInternalPacket *packet;
struct CListNode_DWORD *node, *root;
int wasAtLeastOneRemoved;
wasAtLeastOneRemoved = 1;
while (wasAtLeastOneRemoved && orderingList->list_size) {
wasAtLeastOneRemoved = 0;
root = node = orderingList->position = orderingList->root;
do {
packet = node->value;
if (packet->orderingIndex == *waitingForIndex) {
dprintf("popped out of order packet\n");
Queue_Push_DWORD(&this->outputQueue, &packet);
/*CCircularLinkedList::PopCurrent_DWORD*/
thiscall0((void*) 0x44E750, orderingList);
*waitingForIndex++;
wasAtLeastOneRemoved = 1;
break;
}
node = node->next;
} while (node != root);
}
}
static static
int HandleOrdenedPacket( int HandleOrdenedPacket(
struct CReliabilityLayer *this, struct CReliabilityLayer *this,
struct CInternalPacket *packet) struct CInternalPacket *packet)
{ {
char channel;
short newIndex;
short *waitingForIndex;
struct CCircularLinkedList *orderingList;
if (packet->packetReliability != RELIABLE_ORDENED) { if (packet->packetReliability != RELIABLE_ORDENED) {
return 0; return 0;
} }
channel = packet->orderingChannel;
if (channel >= NUMBER_OF_ORDERED_STREAMS) {
DiscardPacket(this, packet);
return 1;
}
newIndex = packet->orderingIndex;
waitingForIndex = &this->waitingForOrderedPacketReadIndex[channel];
if (newIndex != *waitingForIndex) {
/*not yet time to handle this one*/
dprintf("out of order packet\n");
/*do outOfOrderLimit here*/
this->statistics_orderedMessagesOutOfOrder++;
/*ReliabilityLayer__AddToOrderingList*/
thiscall1((void*) 0x45DEE0, this, (int) packet);
return 1;
}
this->statistics_orderedMessagesInOrder++;
Queue_Push_DWORD(&this->outputQueue, &packet);
orderingList = thiscall1((void*) 0x45C4C0, this, channel);
if (orderingList == NULL) {
return 1;
}
OutputNowInOrderPackets(this, orderingList, waitingForIndex);
return 1; return 1;
} }
@ -308,17 +406,17 @@ int HandleAcks(
struct CRangeList incomingAcksList; struct CRangeList incomingAcksList;
struct CRangeNode_Short *ranges; struct CRangeNode_Short *ranges;
int amountOfAckRanges, ackRangeIdx; int amountOfAckRanges, ackRangeIdx;
int containedValidAcks; int numAcks, pos;
short minMsg, maxMsg; short minMsg, maxMsg;
dprintf("reading ackslist, position is %d\n", bitStream->readOffset); pos = bitStream->readOffset;
RangeList__ctor(&incomingAcksList); RangeList__ctor(&incomingAcksList);
if (!RangeList__Deserialize(&incomingAcksList, bitStream)) { if (!RangeList__Deserialize(&incomingAcksList, bitStream)) {
dprintf("could not deserialize ackslist\n"); dprintf("could not deserialize ackslist\n");
RangeList__dtor(&incomingAcksList); RangeList__dtor(&incomingAcksList);
return 0; return 0;
} }
dprintf("position after reading is %d\n", bitStream->readOffset); dprintf("read acks from %d to %d\n", pos, bitStream->readOffset);
amountOfAckRanges = incomingAcksList._._.list_size; amountOfAckRanges = incomingAcksList._._.list_size;
if (amountOfAckRanges == 0) { if (amountOfAckRanges == 0) {
@ -327,7 +425,7 @@ int HandleAcks(
return 1; return 1;
} }
containedValidAcks = 0; numAcks = 0;
ranges = (struct CRangeNode_Short*) incomingAcksList._._.values; ranges = (struct CRangeNode_Short*) incomingAcksList._._.values;
for (ackRangeIdx = 0; ackRangeIdx < amountOfAckRanges; ackRangeIdx++) { for (ackRangeIdx = 0; ackRangeIdx < amountOfAckRanges; ackRangeIdx++) {
minMsg = ranges[ackRangeIdx].minIndex; minMsg = ranges[ackRangeIdx].minIndex;
@ -338,14 +436,14 @@ int HandleAcks(
continue; continue;
} }
containedValidAcks = 1; numAcks += maxMsg - minMsg + 1;
HandleAcksForMessageRange(this, minMsg, maxMsg, timeNS); HandleAcksForMessageRange(this, minMsg, maxMsg, timeNS);
/*ackslimit checked here*/ /*ackslimit checked here*/
} }
RangeList__dtor(&incomingAcksList); RangeList__dtor(&incomingAcksList);
return containedValidAcks; return numAcks > 0;
} }
/** /**
@ -397,6 +495,7 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
struct CRaknetTimeNS timeNS; struct CRaknetTimeNS timeNS;
char hasAcks, wereAcksHandled; char hasAcks, wereAcksHandled;
int returnValue; int returnValue;
int packetCount;
dprintf("HandleSocketReceiveFromConnectedPlayerStart\n"); dprintf("HandleSocketReceiveFromConnectedPlayerStart\n");
@ -415,21 +514,23 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
wereAcksHandled = 0; wereAcksHandled = 0;
BitStream__Read(&bitStream, &hasAcks); BitStream__Read(&bitStream, &hasAcks);
if (hasAcks) { if (hasAcks) {
dprintf("has acks\n");
wereAcksHandled = HandleAcks(this, &bitStream, timeNS); wereAcksHandled = HandleAcks(this, &bitStream, timeNS);
} }
returnValue = wereAcksHandled; returnValue = wereAcksHandled;
packetCount = 0;
while (packet = ReliabilityLayer__CreateInternalPacketFromBitStream( while (packet = ReliabilityLayer__CreateInternalPacketFromBitStream(
this, &bitStream, timeNS)) this, &bitStream, timeNS))
{ {
returnValue = 1; returnValue |= 0x10000000;
packetCount++;
HandlePacket(this, packet, timeNS); HandlePacket(this, packet, timeNS);
} }
this->receivePacketCount++; this->receivePacketCount++;
BitStream__dtor(&bitStream); BitStream__dtor(&bitStream);
dprintf("HandleSocketReceiveFromConnectedPlayerEnd\n"); dprintf("HandleSocketReceiveFromConnectedPlayerEnd acks=%d packets=%d\n",
returnValue & 0xFFFFFFF, packetCount);
return returnValue; return returnValue;
#endif #endif
} }

View File

@ -1,7 +1,7 @@
/* vim: set filetype=c ts=8 noexpandtab: */ /* vim: set filetype=c ts=8 noexpandtab: */
#define COMPRESS_PRINT //#define COMPRESS_PRINT
#include "common.h" #include "common.h"
#include "uncompress.h" #include "uncompress.h"