OK, first of all, this code will *not* work with the big netcode changes on EQlive. This is ONLY for people who run older-version servers.
That said, this rewrite to netcode will fix a lot of existing issues such as login bug, insta-LD bug, and in general is a lot more stable than the current netcode.
Simply do the following swaps in the below /common/ files.
EQNetwork.cpp
Swap out EQNetworkConnection::Process for:
Code:
#ifdef WIN32
void EQNetworkConnection::Process(SOCKET sock) {
#else
void EQNetworkConnection::Process(int sock) {
#endif
if (!CheckNetActive())
return;
InQueue_Struct* iqs = 0;
while ((iqs = InQueuePop())) {
MakeEQPacket(iqs->app, iqs->ackreq);
safe_delete(iqs->app);
delete iqs;
}
CreateCombinedPacket();
if (timeout_timer->Check()) {
Close();
}
fraglist.CheckTimers();
if (datarate_timer->Check(0))
{
datarate_timer->Start();
dataflow -= datarate_tic;
if (dataflow < 0)
dataflow = 0;
}
EQNetworkPacket* pack;
int32 size;
uchar* data;
sockaddr_in to;
memset(&to, 0, sizeof(to));
to.sin_family = AF_INET;
to.sin_port = rPort;
to.sin_addr.s_addr = rIP;
LinkedListIterator<EQNetworkPacket*> iterator(SendQueue);
iterator.Reset();
if (iterator.MoreElements()) {
keep_alive_timer->Start();
}
else if (IsFree()) {
SetState(EQNC_Finished);
}
#ifdef PRIORITYTEST
if(DataQueueFull() && GetState() == EQNC_Active && queue_check_timer->Check())
{
PacketPriority();
}
#endif
int nas=0, ka=0;
//This sends out "pure" packets that verify to the client that it and the server is still on talking terms
if ( (GetState() == EQNC_Active) && ((nas=no_ack_sent_timer->Check(0)) || (ka=keep_alive_timer->Check(0))) )
{
APPLAYER outapp;
outapp.opcode = 0xFFFF;
outapp.priority = 5;
MakeEQPacket(&outapp, ka);
}
iterator.Reset();
while (iterator.MoreElements() && (!DataQueueFull())) {
pack = iterator.GetData();
if (GetState() != EQNC_Active || (pack->SentCount == 0 && Timer::GetCurrentTime() >= (pack->LastSent+1000)))
{
cout<<""; //Magic cout. This tiny artifical pause will keep the packet process from sending out packets too rapidly and getting them discarded in the process. Especially important during log in/zone processes.
pack->SentCount = 1; //A packet that's been sent shouldn't be resent as long as the connection is moving along smoothly, this just inflates packetrate and causes trouble.
if (GetState() == EQNC_Active && pack->dwARQ == arsp_response + 10) //This code checks if 10 packets have been sent since last ARSP ("we got this packet yo") response from client, and if so, tags those ten packets that haven't been verifiably recieved for a resend. Should probably be condensed into a function for cleanliness :P
{
LinkedListIterator<EQNetworkPacket*> iterator2(SendQueue);
iterator2.Reset();
while (iterator2.MoreElements())
{
EQNetworkPacket* pack2 = iterator2.GetData();
if (pack2->dwARQ == pack->dwARQ)
break;
iterator2.Advance();
}
}
if (pack->HDR.a2_Closing && pack->HDR.a6_Closing) //Closing bits. Terminates the connection properly.
{
size = pack->ReturnPacket(&data);
sendto(sock, (char*) data, size, 0, (sockaddr*) &to, sizeof(to));
delete[] data;
iterator.RemoveCurrent();
continue;
}
else if (GetState() != EQNC_Active) { //Nothing but closing bits to be sent after a connection close. It's not recieved, so why waste processing power?
iterator.RemoveCurrent();
continue;
}
else //SendOut
{
size = pack->ReturnPacket(&data);
sendto(sock, (char*) data, size, 0, (sockaddr*) &to, sizeof(to));
delete[] data;
if (!pack->HDR.a1_ARQ) { //Wtf is this for?
iterator.RemoveCurrent();
continue;
}
dataflow += size;
pack->LastSent = Timer::GetCurrentTime();
}
}
iterator.Advance();
if (!iterator.MoreElements()) //This terminates the process properly after a closed connection has cleaned out the queue.
{
if (GetState() != EQNC_Active)
{
SetState(EQNC_Error);
}
}
}
}
Add this line to the IncomingARSP() function, just below iterator.Reset();
Code:
arsp_response = arsp;
Add this line to EQNetworkConnection::EQNetworkConnection
Add this line under the private part of the EQNetworkConnection class in EQNetwork.h
Code:
int16 arsp_response;
There, you're done. Pat yourself on the back and feel free to feedback any issues.