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"
|
#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)
|
||||||
{
|
{
|
||||||
|
|
16
common.h
16
common.h
|
@ -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);
|
||||||
|
|
119
reliability.c
119
reliability.c
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user