00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_ConnectionGraph2==1
00003
00004 #include "ConnectionGraph2.h"
00005 #include "RakPeerInterface.h"
00006 #include "MessageIdentifiers.h"
00007 #include "BitStream.h"
00008
00009 int ConnectionGraph2::RemoteSystemComp( const RakNetGUID &key, RemoteSystem * const &data )
00010 {
00011 if (key < data->guid)
00012 return -1;
00013 if (key > data->guid)
00014 return 1;
00015 return 0;
00016 }
00017
00018 int ConnectionGraph2::SystemAddressAndGuidComp( const SystemAddressAndGuid &key, const SystemAddressAndGuid &data )
00019 {
00020 if (key.guid<data.guid)
00021 return -1;
00022 if (key.guid>data.guid)
00023 return 1;
00024 return 0;
00025 }
00026
00027 bool ConnectionGraph2::GetConnectionListForRemoteSystem(RakNetGUID remoteSystemGuid, SystemAddress *saOut, RakNetGUID *guidOut, unsigned int *outLength)
00028 {
00029 if ((saOut==0 && guidOut==0) || outLength==0 || *outLength==0 || remoteSystemGuid==UNASSIGNED_RAKNET_GUID)
00030 {
00031 *outLength=0;
00032 return false;
00033 }
00034
00035 bool objectExists;
00036 unsigned int idx = remoteSystems.GetIndexFromKey(remoteSystemGuid, &objectExists);
00037 if (objectExists==false)
00038 {
00039 *outLength=0;
00040 return false;
00041 }
00042
00043 unsigned int idx2;
00044 if (remoteSystems[idx]->remoteConnections.Size() < *outLength)
00045 *outLength=remoteSystems[idx]->remoteConnections.Size();
00046 for (idx2=0; idx2 < *outLength; idx2++)
00047 {
00048 if (guidOut)
00049 guidOut[idx2]=remoteSystems[idx]->remoteConnections[idx2].guid;
00050 if (saOut)
00051 saOut[idx2]=remoteSystems[idx]->remoteConnections[idx2].systemAddress;
00052 }
00053 return true;
00054 }
00055 bool ConnectionGraph2::ConnectionExists(RakNetGUID g1, RakNetGUID g2)
00056 {
00057 if (g1==g2)
00058 return false;
00059
00060 bool objectExists;
00061 unsigned int idx = remoteSystems.GetIndexFromKey(g1, &objectExists);
00062 if (objectExists==false)
00063 {
00064 return false;
00065 }
00066 SystemAddressAndGuid sag;
00067 sag.guid=g2;
00068 return remoteSystems[idx]->remoteConnections.HasData(sag);
00069 }
00070 void ConnectionGraph2::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
00071 {
00072
00073 RakNet::BitStream bs;
00074 if (lostConnectionReason==LCR_CONNECTION_LOST)
00075 bs.Write((MessageID)ID_REMOTE_CONNECTION_LOST);
00076 else
00077 bs.Write((MessageID)ID_REMOTE_DISCONNECTION_NOTIFICATION);
00078 bs.Write(systemAddress);
00079 bs.Write(rakNetGUID);
00080 SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);
00081
00082 bool objectExists;
00083 unsigned int idx = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
00084 if (objectExists)
00085 {
00086 RakNet::OP_DELETE(remoteSystems[idx],__FILE__,__LINE__);
00087 remoteSystems.RemoveAtIndex(idx);
00088 }
00089 }
00090 void ConnectionGraph2::OnNewConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, bool isIncoming)
00091 {
00092 (void) isIncoming;
00093
00094
00095 RakNet::BitStream bs;
00096 bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
00097 bs.Write((uint32_t)1);
00098 bs.Write(systemAddress);
00099 bs.Write(rakNetGUID);
00100 SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,true);
00101
00102
00103 DataStructures::List<SystemAddress> addresses;
00104 DataStructures::List<RakNetGUID> guids;
00105 rakPeerInterface->GetSystemList(addresses, guids);
00106 bs.Reset();
00107 bs.Write((MessageID)ID_REMOTE_NEW_INCOMING_CONNECTION);
00108 BitSize_t writeOffset = bs.GetWriteOffset();
00109 bs.Write((uint32_t) addresses.Size());
00110
00111 unsigned int i;
00112 uint32_t count=0;
00113 for (i=0; i < addresses.Size(); i++)
00114 {
00115 if (addresses[i]==systemAddress)
00116 continue;
00117
00118 bs.Write(addresses[i]);
00119 bs.Write(guids[i]);
00120 count++;
00121 }
00122
00123 if (count>0)
00124 {
00125 BitSize_t writeOffset2 = bs.GetWriteOffset();
00126 bs.SetWriteOffset(writeOffset);
00127 bs.Write(count);
00128 bs.SetWriteOffset(writeOffset2);
00129 SendUnified(&bs,HIGH_PRIORITY,RELIABLE_ORDERED,0,systemAddress,false);
00130 }
00131
00132 bool objectExists;
00133 unsigned int ii = remoteSystems.GetIndexFromKey(rakNetGUID, &objectExists);
00134 if (objectExists==false)
00135 {
00136 RemoteSystem* remoteSystem = RakNet::OP_NEW<RemoteSystem>(__FILE__,__LINE__);
00137 remoteSystem->guid=rakNetGUID;
00138 remoteSystems.InsertAtIndex(remoteSystem,ii,__FILE__,__LINE__);
00139 }
00140 }
00141 PluginReceiveResult ConnectionGraph2::OnReceive(Packet *packet)
00142 {
00143 if (packet->data[0]==ID_REMOTE_CONNECTION_LOST || packet->data[0]==ID_REMOTE_DISCONNECTION_NOTIFICATION)
00144 {
00145 bool objectExists;
00146 unsigned idx = remoteSystems.GetIndexFromKey(packet->guid, &objectExists);
00147 if (objectExists)
00148 {
00149 RakNet::BitStream bs(packet->data,packet->length,false);
00150 bs.IgnoreBytes(1);
00151 SystemAddressAndGuid saag;
00152 bs.Read(saag.systemAddress);
00153 bs.Read(saag.guid);
00154 remoteSystems[idx]->remoteConnections.Remove(saag);
00155 }
00156 }
00157 else if (packet->data[0]==ID_REMOTE_NEW_INCOMING_CONNECTION)
00158 {
00159 bool objectExists;
00160 unsigned idx = remoteSystems.GetIndexFromKey(packet->guid, &objectExists);
00161 if (objectExists)
00162 {
00163 uint32_t numAddresses;
00164 RakNet::BitStream bs(packet->data,packet->length,false);
00165 bs.IgnoreBytes(1);
00166 bs.Read(numAddresses);
00167 for (unsigned int idx2=0; idx2 < numAddresses; idx2++)
00168 {
00169 SystemAddressAndGuid saag;
00170 bs.Read(saag.systemAddress);
00171 bs.Read(saag.guid);
00172 bool objectExists;
00173 unsigned int ii = remoteSystems[idx]->remoteConnections.GetIndexFromKey(saag, &objectExists);
00174 if (objectExists==false)
00175 remoteSystems[idx]->remoteConnections.InsertAtIndex(saag,ii,__FILE__,__LINE__);
00176 }
00177 }
00178 }
00179
00180 return RR_CONTINUE_PROCESSING;
00181 }
00182
00183 #endif // _RAKNET_SUPPORT_*