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:
parent
a4a19a8614
commit
495fa7d745
9
common.c
9
common.c
|
@ -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)
|
||||
{
|
||||
|
|
16
common.h
16
common.h
|
@ -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);
|
||||
|
|
119
reliability.c
119
reliability.c
|
@ -84,6 +84,8 @@ int HandlePacketHole(
|
|||
return 1;
|
||||
}
|
||||
|
||||
dprintf("packet hole is %d\n", holeSize);
|
||||
|
||||
if (holeSize > 0x8000) {
|
||||
/*? underflow apparently*/
|
||||
this->statistics_duplicateMessagesReceived++;
|
||||
|
@ -153,27 +155,123 @@ 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
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/* vim: set filetype=c ts=8 noexpandtab: */
|
||||
|
||||
#define COMPRESS_PRINT
|
||||
//#define COMPRESS_PRINT
|
||||
|
||||
#include "common.h"
|
||||
#include "uncompress.h"
|
||||
|
|
Loading…
Reference in New Issue
Block a user