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"
__declspec(naked)
void j__free(void *ptr)
{
_asm {
mov eax, 0x49AAA8
jmp eax
}
}
__declspec(naked)
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 DEFAULT_HAS_RECEIVED_PACKET_QUEUE_SIZE 0x200
#define NUMBER_OF_ORDERED_STREAMS 0x20
#pragma pack(push, 1)
struct PlayerID {
@ -39,6 +40,20 @@ struct CRangeNode_Short {
};
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 {
unsigned int lo32;
unsigned int hi32;
@ -154,6 +169,7 @@ EXPECT_SIZE(struct CInternalPacket, 0x38);
#define QUEUE_POP_IGNOREVALUE(X) \
(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_Push_QWORD(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;
}
dprintf("packet hole is %d\n", holeSize);
if (holeSize > 0x8000) {
/*? underflow apparently*/
this->statistics_duplicateMessagesReceived++;
@ -153,17 +155,82 @@ void CompressMessageHoleQueue(struct CReliabilityLayer *this)
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
int HandleSequencedPacket(
struct CReliabilityLayer *this,
struct CInternalPacket *packet)
{
char channel;
short waitingIndex;
short newIndex;
if (packet->packetReliability != RELIABLE_SEQUENCED ||
packet->packetReliability != UNRELIABLE_SEQUENCED)
{
return 0;
}
channel = packet->orderingChannel;
if (channel >= NUMBER_OF_ORDERED_STREAMS) {
DiscardPacket(this, packet);
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
@ -171,9 +238,40 @@ int HandleOrdenedPacket(
struct CReliabilityLayer *this,
struct CInternalPacket *packet)
{
char channel;
short newIndex;
short *waitingForIndex;
struct CCircularLinkedList *orderingList;
if (packet->packetReliability != RELIABLE_ORDENED) {
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;
}
@ -308,17 +406,17 @@ int HandleAcks(
struct CRangeList incomingAcksList;
struct CRangeNode_Short *ranges;
int amountOfAckRanges, ackRangeIdx;
int containedValidAcks;
int numAcks, pos;
short minMsg, maxMsg;
dprintf("reading ackslist, position is %d\n", bitStream->readOffset);
pos = 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);
dprintf("read acks from %d to %d\n", pos, bitStream->readOffset);
amountOfAckRanges = incomingAcksList._._.list_size;
if (amountOfAckRanges == 0) {
@ -327,7 +425,7 @@ int HandleAcks(
return 1;
}
containedValidAcks = 0;
numAcks = 0;
ranges = (struct CRangeNode_Short*) incomingAcksList._._.values;
for (ackRangeIdx = 0; ackRangeIdx < amountOfAckRanges; ackRangeIdx++) {
minMsg = ranges[ackRangeIdx].minIndex;
@ -338,14 +436,14 @@ int HandleAcks(
continue;
}
containedValidAcks = 1;
numAcks += maxMsg - minMsg + 1;
HandleAcksForMessageRange(this, minMsg, maxMsg, timeNS);
/*ackslimit checked here*/
}
RangeList__dtor(&incomingAcksList);
return containedValidAcks;
return numAcks > 0;
}
/**
@ -397,6 +495,7 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
struct CRaknetTimeNS timeNS;
char hasAcks, wereAcksHandled;
int returnValue;
int packetCount;
dprintf("HandleSocketReceiveFromConnectedPlayerStart\n");
@ -415,21 +514,23 @@ int __stdcall ReliabilityLayer__HandleSocketReceiveFromConnectedPlayer(
wereAcksHandled = 0;
BitStream__Read(&bitStream, &hasAcks);
if (hasAcks) {
dprintf("has acks\n");
wereAcksHandled = HandleAcks(this, &bitStream, timeNS);
}
returnValue = wereAcksHandled;
packetCount = 0;
while (packet = ReliabilityLayer__CreateInternalPacketFromBitStream(
this, &bitStream, timeNS))
{
returnValue = 1;
returnValue |= 0x10000000;
packetCount++;
HandlePacket(this, packet, timeNS);
}
this->receivePacketCount++;
BitStream__dtor(&bitStream);
dprintf("HandleSocketReceiveFromConnectedPlayerEnd\n");
dprintf("HandleSocketReceiveFromConnectedPlayerEnd acks=%d packets=%d\n",
returnValue & 0xFFFFFFF, packetCount);
return returnValue;
#endif
}

View File

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