forked from Kolyah35/minecraft-pe-0.6.1
the whole game
This commit is contained in:
543
src/raknet/UDPProxyCoordinator.cpp
Executable file
543
src/raknet/UDPProxyCoordinator.cpp
Executable file
@@ -0,0 +1,543 @@
|
||||
#include "NativeFeatureIncludes.h"
|
||||
#if _RAKNET_SUPPORT_UDPProxyCoordinator==1 && _RAKNET_SUPPORT_UDPForwarder==1
|
||||
|
||||
#include "UDPProxyCoordinator.h"
|
||||
#include "BitStream.h"
|
||||
#include "UDPProxyCommon.h"
|
||||
#include "RakPeerInterface.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
#include "Rand.h"
|
||||
#include "GetTime.h"
|
||||
#include "UDPForwarder.h"
|
||||
|
||||
// Larger than the client version
|
||||
static const int DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME=2000;
|
||||
static const int DEFAULT_UNRESPONSIVE_PING_TIME=DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME+1000;
|
||||
|
||||
using namespace RakNet;
|
||||
|
||||
// bool operator<( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() < cls.ping;}
|
||||
// bool operator>( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() > cls.ping;}
|
||||
// bool operator==( const DataStructures::MLKeyRef<unsigned short> &inputKey, const UDPProxyCoordinator::ServerWithPing &cls ) {return inputKey.Get() == cls.ping;}
|
||||
|
||||
int UDPProxyCoordinator::ServerWithPingComp( const unsigned short &key, const UDPProxyCoordinator::ServerWithPing &data )
|
||||
{
|
||||
if (key < data.ping)
|
||||
return -1;
|
||||
if (key > data.ping)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UDPProxyCoordinator::ForwardingRequestComp( const SenderAndTargetAddress &key, ForwardingRequest* const &data)
|
||||
{
|
||||
if (key.senderClientAddress < data->sata.senderClientAddress )
|
||||
return -1;
|
||||
if (key.senderClientAddress > data->sata.senderClientAddress )
|
||||
return -1;
|
||||
if (key.targetClientAddress < data->sata.targetClientAddress )
|
||||
return -1;
|
||||
if (key.targetClientAddress > data->sata.targetClientAddress )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// bool operator<( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
|
||||
// {
|
||||
// return inputKey.Get().senderClientAddress < cls->sata.senderClientAddress ||
|
||||
// (inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress < cls->sata.targetClientAddress);
|
||||
// }
|
||||
// bool operator>( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
|
||||
// {
|
||||
// return inputKey.Get().senderClientAddress > cls->sata.senderClientAddress ||
|
||||
// (inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress > cls->sata.targetClientAddress);
|
||||
// }
|
||||
// bool operator==( const DataStructures::MLKeyRef<UDPProxyCoordinator::SenderAndTargetAddress> &inputKey, const UDPProxyCoordinator::ForwardingRequest *cls )
|
||||
// {
|
||||
// return inputKey.Get().senderClientAddress == cls->sata.senderClientAddress && inputKey.Get().targetClientAddress == cls->sata.targetClientAddress;
|
||||
// }
|
||||
|
||||
STATIC_FACTORY_DEFINITIONS(UDPProxyCoordinator,UDPProxyCoordinator);
|
||||
|
||||
UDPProxyCoordinator::UDPProxyCoordinator()
|
||||
{
|
||||
|
||||
}
|
||||
UDPProxyCoordinator::~UDPProxyCoordinator()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
void UDPProxyCoordinator::SetRemoteLoginPassword(RakNet::RakString password)
|
||||
{
|
||||
remoteLoginPassword=password;
|
||||
}
|
||||
void UDPProxyCoordinator::Update(void)
|
||||
{
|
||||
unsigned int idx;
|
||||
RakNet::TimeMS curTime = RakNet::GetTimeMS();
|
||||
ForwardingRequest *fw;
|
||||
idx=0;
|
||||
while (idx < forwardingRequestList.Size())
|
||||
{
|
||||
fw=forwardingRequestList[idx];
|
||||
if (fw->timeRequestedPings!=0 &&
|
||||
curTime > fw->timeRequestedPings + DEFAULT_UNRESPONSIVE_PING_TIME)
|
||||
{
|
||||
fw->OrderRemainingServersToTry();
|
||||
fw->timeRequestedPings=0;
|
||||
TryNextServer(fw->sata, fw);
|
||||
idx++;
|
||||
}
|
||||
else if (fw->timeoutAfterSuccess!=0 &&
|
||||
curTime > fw->timeoutAfterSuccess)
|
||||
{
|
||||
// Forwarding request succeeded, we waited a bit to prevent duplicates. Can forget about the entry now.
|
||||
RakNet::OP_DELETE(fw,_FILE_AND_LINE_);
|
||||
forwardingRequestList.RemoveAtIndex(idx);
|
||||
}
|
||||
else
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
PluginReceiveResult UDPProxyCoordinator::OnReceive(Packet *packet)
|
||||
{
|
||||
if (packet->data[0]==ID_UDP_PROXY_GENERAL && packet->length>1)
|
||||
{
|
||||
switch (packet->data[1])
|
||||
{
|
||||
case ID_UDP_PROXY_FORWARDING_REQUEST_FROM_CLIENT_TO_COORDINATOR:
|
||||
OnForwardingRequestFromClientToCoordinator(packet);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
case ID_UDP_PROXY_LOGIN_REQUEST_FROM_SERVER_TO_COORDINATOR:
|
||||
OnLoginRequestFromServerToCoordinator(packet);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
case ID_UDP_PROXY_FORWARDING_REPLY_FROM_SERVER_TO_COORDINATOR:
|
||||
OnForwardingReplyFromServerToCoordinator(packet);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
case ID_UDP_PROXY_PING_SERVERS_REPLY_FROM_CLIENT_TO_COORDINATOR:
|
||||
OnPingServersReplyFromClientToCoordinator(packet);
|
||||
return RR_STOP_PROCESSING_AND_DEALLOCATE;
|
||||
}
|
||||
}
|
||||
return RR_CONTINUE_PROCESSING;
|
||||
}
|
||||
void UDPProxyCoordinator::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
|
||||
{
|
||||
(void) lostConnectionReason;
|
||||
(void) rakNetGUID;
|
||||
|
||||
unsigned int idx, idx2;
|
||||
|
||||
idx=0;
|
||||
while (idx < forwardingRequestList.Size())
|
||||
{
|
||||
if (forwardingRequestList[idx]->requestingAddress==systemAddress)
|
||||
{
|
||||
// Guy disconnected before the attempt completed
|
||||
RakNet::OP_DELETE(forwardingRequestList[idx], _FILE_AND_LINE_);
|
||||
forwardingRequestList.RemoveAtIndex(idx );
|
||||
}
|
||||
else
|
||||
idx++;
|
||||
}
|
||||
|
||||
idx = serverList.GetIndexOf(systemAddress);
|
||||
if (idx!=(unsigned int)-1)
|
||||
{
|
||||
ForwardingRequest *fw;
|
||||
// For each pending client for this server, choose from remaining servers.
|
||||
for (idx2=0; idx2 < forwardingRequestList.Size(); idx2++)
|
||||
{
|
||||
fw = forwardingRequestList[idx2];
|
||||
if (fw->currentlyAttemptedServerAddress==systemAddress)
|
||||
{
|
||||
// Try the next server
|
||||
TryNextServer(fw->sata, fw);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove dead server
|
||||
serverList.RemoveAtIndexFast(idx);
|
||||
}
|
||||
}
|
||||
void UDPProxyCoordinator::OnForwardingRequestFromClientToCoordinator(Packet *packet)
|
||||
{
|
||||
RakNet::BitStream incomingBs(packet->data, packet->length, false);
|
||||
incomingBs.IgnoreBytes(2);
|
||||
SystemAddress sourceAddress;
|
||||
incomingBs.Read(sourceAddress);
|
||||
if (sourceAddress==UNASSIGNED_SYSTEM_ADDRESS)
|
||||
sourceAddress=packet->systemAddress;
|
||||
SystemAddress targetAddress;
|
||||
RakNetGUID targetGuid;
|
||||
bool usesAddress=false;
|
||||
incomingBs.Read(usesAddress);
|
||||
if (usesAddress)
|
||||
{
|
||||
incomingBs.Read(targetAddress);
|
||||
targetGuid=rakPeerInterface->GetGuidFromSystemAddress(targetAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
incomingBs.Read(targetGuid);
|
||||
targetAddress=rakPeerInterface->GetSystemAddressFromGuid(targetGuid);
|
||||
}
|
||||
ForwardingRequest *fw = RakNet::OP_NEW<ForwardingRequest>(_FILE_AND_LINE_);
|
||||
fw->timeoutAfterSuccess=0;
|
||||
incomingBs.Read(fw->timeoutOnNoDataMS);
|
||||
bool hasServerSelectionBitstream=false;
|
||||
incomingBs.Read(hasServerSelectionBitstream);
|
||||
if (hasServerSelectionBitstream)
|
||||
incomingBs.Read(&(fw->serverSelectionBitstream));
|
||||
|
||||
RakNet::BitStream outgoingBs;
|
||||
SenderAndTargetAddress sata;
|
||||
sata.senderClientAddress=sourceAddress;
|
||||
sata.targetClientAddress=targetAddress;
|
||||
sata.targetClientGuid=targetGuid;
|
||||
sata.senderClientGuid=rakPeerInterface->GetGuidFromSystemAddress(sourceAddress);
|
||||
SenderAndTargetAddress sataReversed;
|
||||
sataReversed.senderClientAddress=targetAddress;
|
||||
sataReversed.targetClientAddress=sourceAddress;
|
||||
sataReversed.senderClientGuid=sata.targetClientGuid;
|
||||
sataReversed.targetClientGuid=sata.senderClientGuid;
|
||||
|
||||
unsigned int insertionIndex;
|
||||
bool objectExists1, objectExists2;
|
||||
insertionIndex=forwardingRequestList.GetIndexFromKey(sata, &objectExists1);
|
||||
forwardingRequestList.GetIndexFromKey(sataReversed, &objectExists2);
|
||||
|
||||
if (objectExists1 || objectExists2)
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
|
||||
outgoingBs.Write(sata.senderClientAddress);
|
||||
outgoingBs.Write(targetAddress);
|
||||
outgoingBs.Write(targetGuid);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
RakNet::OP_DELETE(fw, _FILE_AND_LINE_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (serverList.Size()==0)
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_SERVERS_ONLINE);
|
||||
outgoingBs.Write(sata.senderClientAddress);
|
||||
outgoingBs.Write(targetAddress);
|
||||
outgoingBs.Write(targetGuid);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
RakNet::OP_DELETE(fw, _FILE_AND_LINE_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rakPeerInterface->GetConnectionState(targetAddress)!=IS_CONNECTED && usesAddress==false)
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_RECIPIENT_GUID_NOT_CONNECTED_TO_COORDINATOR);
|
||||
outgoingBs.Write(sata.senderClientAddress);
|
||||
outgoingBs.Write(targetAddress);
|
||||
outgoingBs.Write(targetGuid);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
RakNet::OP_DELETE(fw, _FILE_AND_LINE_);
|
||||
return;
|
||||
}
|
||||
|
||||
fw->sata=sata;
|
||||
fw->requestingAddress=packet->systemAddress;
|
||||
|
||||
if (serverList.Size()>1)
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_PING_SERVERS_FROM_COORDINATOR_TO_CLIENT);
|
||||
outgoingBs.Write(sourceAddress);
|
||||
outgoingBs.Write(targetAddress);
|
||||
outgoingBs.Write(targetGuid);
|
||||
unsigned short serverListSize = (unsigned short) serverList.Size();
|
||||
outgoingBs.Write(serverListSize);
|
||||
unsigned int idx;
|
||||
for (idx=0; idx < serverList.Size(); idx++)
|
||||
outgoingBs.Write(serverList[idx]);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sourceAddress, false);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, targetAddress, false);
|
||||
fw->timeRequestedPings=RakNet::GetTimeMS();
|
||||
unsigned int copyIndex;
|
||||
for (copyIndex=0; copyIndex < serverList.Size(); copyIndex++)
|
||||
fw->remainingServersToTry.Push(serverList[copyIndex], _FILE_AND_LINE_ );
|
||||
forwardingRequestList.InsertAtIndex(fw, insertionIndex, _FILE_AND_LINE_ );
|
||||
}
|
||||
else
|
||||
{
|
||||
fw->timeRequestedPings=0;
|
||||
fw->currentlyAttemptedServerAddress=serverList[0];
|
||||
forwardingRequestList.InsertAtIndex(fw, insertionIndex, _FILE_AND_LINE_ );
|
||||
SendForwardingRequest(sourceAddress, targetAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS);
|
||||
}
|
||||
}
|
||||
|
||||
void UDPProxyCoordinator::SendForwardingRequest(SystemAddress sourceAddress, SystemAddress targetAddress, SystemAddress serverAddress, RakNet::TimeMS timeoutOnNoDataMS)
|
||||
{
|
||||
RakNet::BitStream outgoingBs;
|
||||
// Send request to desired server
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_REQUEST_FROM_COORDINATOR_TO_SERVER);
|
||||
outgoingBs.Write(sourceAddress);
|
||||
outgoingBs.Write(targetAddress);
|
||||
outgoingBs.Write(timeoutOnNoDataMS);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, serverAddress, false);
|
||||
}
|
||||
void UDPProxyCoordinator::OnLoginRequestFromServerToCoordinator(Packet *packet)
|
||||
{
|
||||
RakNet::BitStream incomingBs(packet->data, packet->length, false);
|
||||
incomingBs.IgnoreBytes(2);
|
||||
RakNet::RakString password;
|
||||
incomingBs.Read(password);
|
||||
RakNet::BitStream outgoingBs;
|
||||
|
||||
if (remoteLoginPassword.IsEmpty())
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_NO_PASSWORD_SET_FROM_COORDINATOR_TO_SERVER);
|
||||
outgoingBs.Write(password);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (remoteLoginPassword!=password)
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_WRONG_PASSWORD_FROM_COORDINATOR_TO_SERVER);
|
||||
outgoingBs.Write(password);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int insertionIndex;
|
||||
insertionIndex=serverList.GetIndexOf(packet->systemAddress);
|
||||
if (insertionIndex!=(unsigned int)-1)
|
||||
{
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_ALREADY_LOGGED_IN_FROM_COORDINATOR_TO_SERVER);
|
||||
outgoingBs.Write(password);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
return;
|
||||
}
|
||||
serverList.Push(packet->systemAddress, _FILE_AND_LINE_ );
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_LOGIN_SUCCESS_FROM_COORDINATOR_TO_SERVER);
|
||||
outgoingBs.Write(password);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
|
||||
}
|
||||
void UDPProxyCoordinator::OnForwardingReplyFromServerToCoordinator(Packet *packet)
|
||||
{
|
||||
RakNet::BitStream incomingBs(packet->data, packet->length, false);
|
||||
incomingBs.IgnoreBytes(2);
|
||||
SenderAndTargetAddress sata;
|
||||
incomingBs.Read(sata.senderClientAddress);
|
||||
incomingBs.Read(sata.targetClientAddress);
|
||||
bool objectExists;
|
||||
unsigned int index = forwardingRequestList.GetIndexFromKey(sata, &objectExists);
|
||||
if (objectExists==false)
|
||||
{
|
||||
// The guy disconnected before the request finished
|
||||
return;
|
||||
}
|
||||
ForwardingRequest *fw = forwardingRequestList[index];
|
||||
sata.senderClientGuid = fw->sata.senderClientGuid;
|
||||
sata.targetClientGuid = fw->sata.targetClientGuid;
|
||||
|
||||
UDPForwarderResult success;
|
||||
unsigned char c;
|
||||
incomingBs.Read(c);
|
||||
success=(UDPForwarderResult)c;
|
||||
|
||||
RakNet::BitStream outgoingBs;
|
||||
if (success==UDPFORWARDER_SUCCESS)
|
||||
{
|
||||
char serverIP[64];
|
||||
packet->systemAddress.ToString(false,serverIP);
|
||||
unsigned short forwardingPort;
|
||||
incomingBs.Read(forwardingPort);
|
||||
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_SUCCEEDED);
|
||||
outgoingBs.Write(sata.senderClientAddress);
|
||||
outgoingBs.Write(sata.targetClientAddress);
|
||||
outgoingBs.Write(sata.targetClientGuid);
|
||||
outgoingBs.Write(RakNet::RakString(serverIP));
|
||||
outgoingBs.Write(forwardingPort);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
|
||||
|
||||
outgoingBs.Reset();
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_FORWARDING_NOTIFICATION);
|
||||
outgoingBs.Write(sata.senderClientAddress);
|
||||
outgoingBs.Write(sata.targetClientAddress);
|
||||
outgoingBs.Write(sata.targetClientGuid);
|
||||
outgoingBs.Write(RakNet::RakString(serverIP));
|
||||
outgoingBs.Write(forwardingPort);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, sata.targetClientAddress, false);
|
||||
|
||||
// 05/18/09 Keep the entry around for some time after success, so duplicates are reported if attempting forwarding from the target system before notification of success
|
||||
fw->timeoutAfterSuccess=RakNet::GetTimeMS()+fw->timeoutOnNoDataMS;
|
||||
// forwardingRequestList.RemoveAtIndex(index);
|
||||
// RakNet::OP_DELETE(fw,_FILE_AND_LINE_);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (success==UDPFORWARDER_NO_SOCKETS)
|
||||
{
|
||||
// Try next server
|
||||
TryNextServer(sata, fw);
|
||||
}
|
||||
else
|
||||
{
|
||||
RakAssert(success==UDPFORWARDER_FORWARDING_ALREADY_EXISTS);
|
||||
|
||||
// Return in progress
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_IN_PROGRESS);
|
||||
outgoingBs.Write(sata.senderClientAddress);
|
||||
outgoingBs.Write(sata.targetClientAddress);
|
||||
outgoingBs.Write(sata.targetClientGuid);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, fw->requestingAddress, false);
|
||||
forwardingRequestList.RemoveAtIndex(index);
|
||||
RakNet::OP_DELETE(fw,_FILE_AND_LINE_);
|
||||
}
|
||||
}
|
||||
void UDPProxyCoordinator::OnPingServersReplyFromClientToCoordinator(Packet *packet)
|
||||
{
|
||||
RakNet::BitStream incomingBs(packet->data, packet->length, false);
|
||||
incomingBs.IgnoreBytes(2);
|
||||
unsigned short serversToPingSize;
|
||||
SystemAddress serverAddress;
|
||||
SenderAndTargetAddress sata;
|
||||
incomingBs.Read(sata.senderClientAddress);
|
||||
incomingBs.Read(sata.targetClientAddress);
|
||||
bool objectExists;
|
||||
unsigned int index = forwardingRequestList.GetIndexFromKey(sata, &objectExists);
|
||||
if (objectExists==false)
|
||||
return;
|
||||
unsigned short idx;
|
||||
ServerWithPing swp;
|
||||
ForwardingRequest *fw = forwardingRequestList[index];
|
||||
if (fw->timeRequestedPings==0)
|
||||
return;
|
||||
|
||||
incomingBs.Read(serversToPingSize);
|
||||
if (packet->systemAddress==sata.senderClientAddress)
|
||||
{
|
||||
for (idx=0; idx < serversToPingSize; idx++)
|
||||
{
|
||||
incomingBs.Read(swp.serverAddress);
|
||||
incomingBs.Read(swp.ping);
|
||||
unsigned int index2;
|
||||
for (index2=0; index2 < fw->sourceServerPings.Size(); index2++)
|
||||
{
|
||||
if (fw->sourceServerPings[index2].ping >= swp.ping )
|
||||
break;
|
||||
}
|
||||
fw->sourceServerPings.Insert(swp, index2, _FILE_AND_LINE_);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (idx=0; idx < serversToPingSize; idx++)
|
||||
{
|
||||
incomingBs.Read(swp.serverAddress);
|
||||
incomingBs.Read(swp.ping);
|
||||
|
||||
unsigned int index2;
|
||||
for (index2=0; index2 < fw->targetServerPings.Size(); index2++)
|
||||
{
|
||||
if (fw->targetServerPings[index2].ping >= swp.ping )
|
||||
break;
|
||||
}
|
||||
fw->sourceServerPings.Insert(swp, index2, _FILE_AND_LINE_);
|
||||
}
|
||||
}
|
||||
|
||||
// Both systems have to give us pings to progress here. Otherwise will timeout in Update()
|
||||
if (fw->sourceServerPings.Size()>0 &&
|
||||
fw->targetServerPings.Size()>0)
|
||||
{
|
||||
fw->OrderRemainingServersToTry();
|
||||
fw->timeRequestedPings=0;
|
||||
TryNextServer(fw->sata, fw);
|
||||
}
|
||||
}
|
||||
void UDPProxyCoordinator::TryNextServer(SenderAndTargetAddress sata, ForwardingRequest *fw)
|
||||
{
|
||||
bool pickedGoodServer=false;
|
||||
while(fw->remainingServersToTry.Size()>0)
|
||||
{
|
||||
fw->currentlyAttemptedServerAddress=fw->remainingServersToTry.Pop();
|
||||
if (serverList.GetIndexOf(fw->currentlyAttemptedServerAddress)!=(unsigned int)-1)
|
||||
{
|
||||
pickedGoodServer=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pickedGoodServer==false)
|
||||
{
|
||||
SendAllBusy(sata.senderClientAddress, sata.targetClientAddress, sata.targetClientGuid, fw->requestingAddress);
|
||||
forwardingRequestList.Remove(sata);
|
||||
RakNet::OP_DELETE(fw,_FILE_AND_LINE_);
|
||||
return;
|
||||
}
|
||||
|
||||
SendForwardingRequest(sata.senderClientAddress, sata.targetClientAddress, fw->currentlyAttemptedServerAddress, fw->timeoutOnNoDataMS);
|
||||
}
|
||||
void UDPProxyCoordinator::SendAllBusy(SystemAddress senderClientAddress, SystemAddress targetClientAddress, RakNetGUID targetClientGuid, SystemAddress requestingAddress)
|
||||
{
|
||||
RakNet::BitStream outgoingBs;
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_GENERAL);
|
||||
outgoingBs.Write((MessageID)ID_UDP_PROXY_ALL_SERVERS_BUSY);
|
||||
outgoingBs.Write(senderClientAddress);
|
||||
outgoingBs.Write(targetClientAddress);
|
||||
outgoingBs.Write(targetClientGuid);
|
||||
rakPeerInterface->Send(&outgoingBs, MEDIUM_PRIORITY, RELIABLE_ORDERED, 0, requestingAddress, false);
|
||||
}
|
||||
void UDPProxyCoordinator::Clear(void)
|
||||
{
|
||||
serverList.Clear(true, _FILE_AND_LINE_);
|
||||
for (unsigned int i=0; i < forwardingRequestList.Size(); i++)
|
||||
{
|
||||
RakNet::OP_DELETE(forwardingRequestList[i],_FILE_AND_LINE_);
|
||||
}
|
||||
forwardingRequestList.Clear(false, _FILE_AND_LINE_);
|
||||
}
|
||||
void UDPProxyCoordinator::ForwardingRequest::OrderRemainingServersToTry(void)
|
||||
{
|
||||
//DataStructures::Multilist<ML_ORDERED_LIST,UDPProxyCoordinator::ServerWithPing,unsigned short> swpList;
|
||||
DataStructures::OrderedList<unsigned short, UDPProxyCoordinator::ServerWithPing, ServerWithPingComp> swpList;
|
||||
// swpList.SetSortOrder(true);
|
||||
|
||||
if (sourceServerPings.Size()==0 && targetServerPings.Size()==0)
|
||||
return;
|
||||
|
||||
unsigned int idx;
|
||||
UDPProxyCoordinator::ServerWithPing swp;
|
||||
for (idx=0; idx < remainingServersToTry.Size(); idx++)
|
||||
{
|
||||
swp.serverAddress=remainingServersToTry[idx];
|
||||
swp.ping=0;
|
||||
if (sourceServerPings.Size())
|
||||
swp.ping+=(unsigned short) (sourceServerPings[idx].ping);
|
||||
else
|
||||
swp.ping+=(unsigned short) (DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME);
|
||||
if (targetServerPings.Size())
|
||||
swp.ping+=(unsigned short) (targetServerPings[idx].ping);
|
||||
else
|
||||
swp.ping+=(unsigned short) (DEFAULT_CLIENT_UNRESPONSIVE_PING_TIME);
|
||||
swpList.Insert(swp.ping, swp, false, _FILE_AND_LINE_);
|
||||
}
|
||||
remainingServersToTry.Clear(_FILE_AND_LINE_ );
|
||||
for (idx=0; idx < swpList.Size(); idx++)
|
||||
{
|
||||
remainingServersToTry.Push(swpList[idx].serverAddress, _FILE_AND_LINE_ );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _RAKNET_SUPPORT_*
|
||||
Reference in New Issue
Block a user