the whole game
This commit is contained in:
299
project/lib_projects/raknet/jni/RaknetSources/ConnectionGraph2.cpp
Executable file
299
project/lib_projects/raknet/jni/RaknetSources/ConnectionGraph2.cpp
Executable file
@@ -0,0 +1,299 @@
|
||||
#include "NativeFeatureIncludes.h"
|
||||
#if _RAKNET_SUPPORT_ConnectionGraph2==1
|
||||
|
||||
#include "ConnectionGraph2.h"
|
||||
#include "RakPeerInterface.h"
|
||||
#include "MessageIdentifiers.h"
|
||||
#include "BitStream.h"
|
||||
|
||||
using namespace RakNet;
|
||||
|
||||
STATIC_FACTORY_DEFINITIONS(ConnectionGraph2,ConnectionGraph2);
|
||||
|
||||
int RakNet::ConnectionGraph2::RemoteSystemComp( const RakNetGUID &key, RemoteSystem * const &data )
|
||||
{
|
||||
if (key < data->guid)
|
||||
return -1;
|
||||
if (key > data->guid)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RakNet::ConnectionGraph2::SystemAddressAndGuidComp( const SystemAddressAndGuid &key, const SystemAddressAndGuid &data )
|
||||
{
|
||||
if (key.guid<data.guid)
|
||||
return -1;
|
||||
if (key.guid>data.guid)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
ConnectionGraph2::ConnectionGraph2()
|
||||
{
|
||||
autoProcessNewConnections=true;
|
||||
}
|
||||
ConnectionGraph2::~ConnectionGraph2()
|
||||
{
|
||||
|
||||
}
|
||||
bool ConnectionGraph2::GetConnectionListForRemoteSystem(RakNetGUID remoteSystemGuid, SystemAddress *saOut, RakNetGUID *guidOut, unsigned int *outLength)
|
||||
{
|
||||
if ((saOut==0 && guidOut==0) || outLength==0 || *outLength==0 || remoteSystemGuid==UNASSIGNED_RAKNET_GUID)
|
||||
{
|
||||
*outLength=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool objectExists;
|
||||
unsigned int idx = remoteSystems.GetIndexFromKey(remoteSystemGuid, &objectExists);
|
||||
if (objectExists==false)
|
||||
{
|
||||
*outLength=0;
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int idx2;
|
||||
if (remoteSystems[idx]->remoteConnections.Size() < *outLength)
|
||||
*outLength=remoteSystems[idx]->remoteConnections.Size();
|
||||
for (idx2=0; idx2 < *outLength; idx2++)
|
||||
{
|
||||
if (guidOut)
|
||||
guidOut[idx2]=remoteSystems[idx]->remoteConnections[idx2].guid;
|
||||
if (saOut)
|
||||
saOut[idx2]=remoteSystems[idx]->remoteConnections[idx2].systemAddress;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool ConnectionGraph2::ConnectionExists(RakNetGUID g1, RakNetGUID g2)
|
||||
{
|
||||
if (g1==g2)
|
||||
return false;
|
||||
|
||||
bool objectExists;
|
||||
unsigned int idx = remoteSystems.GetIndexFromKey(g1, &objectExists);
|
||||
if (objectExists==false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SystemAddressAndGuid sag;
|
||||
sag.guid=g2;
|
||||
return remoteSystems[idx]->remoteConnections.HasData(sag);
|
||||
}
|
||||
uint16_t ConnectionGraph2::GetPingBetweenSystems(RakNetGUID g1, RakNetGUID g2) const
|
||||
{
|
||||
if (g1==g2)
|
||||
return 0;
|
||||
|
||||
if (g1==rakPeerInterface->GetMyGUID())
|
||||
return (uint16_t) rakPeerInterface->GetAveragePing(g2);
|
||||
if (g2==rakPeerInterface->GetMyGUID())
|
||||
return (uint16_t) rakPeerInterface->GetAveragePing(g1);
|
||||
|
||||
bool objectExists;
|
||||
unsigned int idx = remoteSystems.GetIndexFromKey(g1, &objectExists);
|
||||
if (objectExists==false)
|
||||
{
|
||||
return (uint16_t) -1;
|
||||
}
|
||||
|
||||
SystemAddressAndGuid sag;
|
||||
sag.guid=g2;
|
||||
unsigned int idx2 = remoteSystems[idx]->remoteConnections.GetIndexFromKey(sag, &objectExists);
|
||||
if (objectExists==false)
|
||||
{
|
||||
return (uint16_t) -1;
|
||||
}
|
||||
return remoteSystems[idx]->remoteConnections[idx2].sendersPingToThatSystem;
|
||||
}
|
||||
|
||||
/// Returns the system with the lowest total ping among all its connections. This can be used as the 'best host' for a peer to peer session
|
||||
RakNetGUID ConnectionGraph2::GetLowestAveragePingSystem(void) const
|
||||
{
|
||||
float lowestPing=-1.0;
|
||||
unsigned int lowestPingIdx=(unsigned int) -1;
|
||||
float thisAvePing=0.0f;
|
||||
unsigned int idx, idx2;
|
||||
int ap, count=0;
|
||||
|
||||
for (idx=0; idx<remoteSystems.Size(); idx++)
|
||||
{
|
||||
thisAvePing=0.0f;
|
||||
|
||||
ap = rakPeerInterface->GetAveragePing(remoteSystems[idx]->guid);
|
||||
if (ap!=-1)
|
||||
{
|
||||
thisAvePing+=(float) ap;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count>0)
|
||||
{
|
||||
lowestPing=thisAvePing/count;
|
||||
}
|
||||
|
||||
for (idx=0; idx<remoteSystems.Size(); idx++)
|
||||
{
|
||||
thisAvePing=0.0f;
|
||||
count=0;
|
||||
|
||||
RemoteSystem *remoteSystem = remoteSystems[idx];
|
||||
for (idx2=0; idx2 < remoteSystem->remoteConnections.Size(); idx2++)
|
||||
{
|
||||
ap=remoteSystem->remoteConnections[idx2].sendersPingToThatSystem;
|
||||
if (ap!=-1)
|
||||
{
|
||||
thisAvePing+=(float) ap;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count>0 && (lowestPing==-1.0f || thisAvePing/count < lowestPing))
|
||||
{
|
||||
lowestPing=thisAvePing/count;
|
||||
lowestPingIdx=idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (lowestPingIdx==(unsigned int) -1)
|
||||
return rakPeerInterface->GetMyGUID();
|
||||
return remoteSystems[lowestPingIdx]->guid;
|
||||
}
|
||||
|
||||
void ConnectionGraph2::OnClosedConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
|
||||
{
|
||||
// Send notice to all existing connections
|
||||
RakNet::BitStream bs;
|
||||
if (lostConnectionReason==LCR_CONNECTION_LOST)
|
||||
bs.Write((MessageID)ID_REMOTE_CONNECTION_LOST);
|
||||
else
|
||||
bs.Write((MessageID)ID_REMOTE_DISCONNECTION_NOTIFICATION);
|
||||
bs.Write(systemAddress);
|
||||
bs.Write(rakNetGUID);
|
||||
SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);
|
||||
|
||||
bool objectExists;
|
||||
unsigned int idx = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
|
||||
if (objectExists)
|
||||
{
|
||||
RakNet::OP_DELETE(remoteSystems[idx],_FILE_AND_LINE_);
|
||||
remoteSystems.RemoveAtIndex(idx);
|
||||
}
|
||||
}
|
||||
void ConnectionGraph2::SetAutoProcessNewConnections(bool b)
|
||||
{
|
||||
autoProcessNewConnections=b;
|
||||
}
|
||||
bool ConnectionGraph2::GetAutoProcessNewConnections(void) const
|
||||
{
|
||||
return autoProcessNewConnections;
|
||||
}
|
||||
void ConnectionGraph2::AddParticipant(const SystemAddress &systemAddress, RakNetGUID rakNetGUID)
|
||||
{
|
||||
// Relay the new connection to other systems.
|
||||
RakNet::BitStream bs;
|
||||
bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
|
||||
bs.Write((uint32_t)1);
|
||||
bs.Write(systemAddress);
|
||||
bs.Write(rakNetGUID);
|
||||
bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(rakNetGUID));
|
||||
SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);
|
||||
|
||||
// Send everyone to the new guy
|
||||
DataStructures::List<SystemAddress> addresses;
|
||||
DataStructures::List<RakNetGUID> guids;
|
||||
rakPeerInterface->GetSystemList(addresses, guids);
|
||||
bs.Reset();
|
||||
bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
|
||||
BitSize_t writeOffset = bs.GetWriteOffset();
|
||||
bs.Write((uint32_t) addresses.Size());
|
||||
|
||||
unsigned int i;
|
||||
uint32_t count=0;
|
||||
for (i=0; i < addresses.Size(); i++)
|
||||
{
|
||||
if (addresses[i]==systemAddress)
|
||||
continue;
|
||||
|
||||
bs.Write(addresses[i]);
|
||||
bs.Write(guids[i]);
|
||||
bs.WriteCasted<uint16_t>(rakPeerInterface->GetAveragePing(guids[i]));
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count>0)
|
||||
{
|
||||
BitSize_t writeOffset2 = bs.GetWriteOffset();
|
||||
bs.SetWriteOffset(writeOffset);
|
||||
bs.Write(count);
|
||||
bs.SetWriteOffset(writeOffset2);
|
||||
SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false);
|
||||
}
|
||||
|
||||
bool objectExists;
|
||||
unsigned int ii = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
|
||||
if (objectExists==false)
|
||||
{
|
||||
RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(_FILE_AND_LINE_);
|
||||
remoteSystem->guid=rakNetGUID;
|
||||
remoteSystems.InsertAtIndex(remoteSystem,ii,_FILE_AND_LINE_);
|
||||
}
|
||||
}
|
||||
void ConnectionGraph2::GetParticipantList(DataStructures::OrderedList<RakNetGUID, RakNetGUID> &participantList)
|
||||
{
|
||||
participantList.Clear(true, _FILE_AND_LINE_);
|
||||
unsigned int i;
|
||||
for (i=0; i < remoteSystems.Size(); i++)
|
||||
participantList.InsertAtEnd(remoteSystems[i]->guid, _FILE_AND_LINE_);
|
||||
}
|
||||
void ConnectionGraph2::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
|
||||
{
|
||||
(void) isIncoming;
|
||||
if (autoProcessNewConnections)
|
||||
AddParticipant(systemAddress, rakNetGUID);
|
||||
}
|
||||
PluginReceiveResult ConnectionGraph2::OnReceive(Packet *packet)
|
||||
{
|
||||
if (packet->data[0]==ID_REMOTE_CONNECTION_LOST || packet->data[0]==ID_REMOTE_DISCONNECTION_NOTIFICATION)
|
||||
{
|
||||
bool objectExists;
|
||||
unsigned idx = remoteSystems.GetIndexFromKey(packet->guid, &objectExists);
|
||||
if (objectExists)
|
||||
{
|
||||
RakNet::BitStream bs(packet->data,packet->length,false);
|
||||
bs.IgnoreBytes(1);
|
||||
SystemAddressAndGuid saag;
|
||||
bs.Read(saag.systemAddress);
|
||||
bs.Read(saag.guid);
|
||||
unsigned long idx2 = remoteSystems[idx]->remoteConnections.GetIndexFromKey(saag, &objectExists);
|
||||
if (objectExists)
|
||||
remoteSystems[idx]->remoteConnections.RemoveAtIndex(idx2);
|
||||
}
|
||||
}
|
||||
else if (packet->data[0]==ID_REMOTE_NEW_INCOMING_CONNECTION)
|
||||
{
|
||||
bool objectExists;
|
||||
unsigned idx = remoteSystems.GetIndexFromKey(packet->guid, &objectExists);
|
||||
if (objectExists)
|
||||
{
|
||||
uint32_t numAddresses;
|
||||
RakNet::BitStream bs(packet->data,packet->length,false);
|
||||
bs.IgnoreBytes(1);
|
||||
bs.Read(numAddresses);
|
||||
for (unsigned int idx2=0; idx2 < numAddresses; idx2++)
|
||||
{
|
||||
SystemAddressAndGuid saag;
|
||||
bs.Read(saag.systemAddress);
|
||||
bs.Read(saag.guid);
|
||||
bs.Read(saag.sendersPingToThatSystem);
|
||||
bool objectExists;
|
||||
unsigned int ii = remoteSystems[idx]->remoteConnections.GetIndexFromKey(saag, &objectExists);
|
||||
if (objectExists==false)
|
||||
remoteSystems[idx]->remoteConnections.InsertAtIndex(saag,ii,_FILE_AND_LINE_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RR_CONTINUE_PROCESSING;
|
||||
}
|
||||
|
||||
#endif // _RAKNET_SUPPORT_*
|
||||
Reference in New Issue
Block a user