00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_PacketizedTCP==1
00003
00004 #include "PacketizedTCP.h"
00005 #include "NativeTypes.h"
00006 #include "BitStream.h"
00007 #include "MessageIdentifiers.h"
00008 #include "RakAlloca.h"
00009
00010 typedef uint32_t PTCPHeader;
00011
00012 PacketizedTCP::PacketizedTCP()
00013 {
00014
00015 }
00016 PacketizedTCP::~PacketizedTCP()
00017 {
00018 ClearAllConnections();
00019 }
00020
00021 bool PacketizedTCP::Start(unsigned short port, unsigned short maxIncomingConnections, int threadPriority)
00022 {
00023 bool success = TCPInterface::Start(port, maxIncomingConnections,0,threadPriority);
00024 if (success)
00025 {
00026 unsigned int i;
00027 for (i=0; i < messageHandlerList.Size(); i++)
00028 messageHandlerList[i]->OnRakPeerStartup();
00029 }
00030 return success;
00031 }
00032
00033 void PacketizedTCP::Stop(void)
00034 {
00035 unsigned int i;
00036 for (i=0; i < messageHandlerList.Size(); i++)
00037 messageHandlerList[i]->OnRakPeerShutdown();
00038 for (i=0; i < waitingPackets.Size(); i++)
00039 DeallocatePacket(waitingPackets[i]);
00040 TCPInterface::Stop();
00041 ClearAllConnections();
00042 }
00043
00044 void PacketizedTCP::Send( const char *data, unsigned length, SystemAddress systemAddress, bool broadcast )
00045 {
00046 PTCPHeader dataLength;
00047 dataLength=length;
00048 #ifndef __BITSTREAM_NATIVE_END
00049 if (RakNet::BitStream::DoEndianSwap())
00050 RakNet::BitStream::ReverseBytes((unsigned char*) &length,(unsigned char*) &dataLength,sizeof(dataLength));
00051 #else
00052 dataLength=length;
00053 #endif
00054
00055 unsigned int lengthsArray[2];
00056 const char *dataArray[2];
00057 dataArray[0]=(char*) &dataLength;
00058 dataArray[1]=data;
00059 lengthsArray[0]=sizeof(dataLength);
00060 lengthsArray[1]=length;
00061 TCPInterface::SendList(dataArray,lengthsArray,2,systemAddress,broadcast);
00062 }
00063 bool PacketizedTCP::SendList( const char **data, const int *lengths, const int numParameters, SystemAddress systemAddress, bool broadcast )
00064 {
00065 if (isStarted==false)
00066 return false;
00067 if (data==0)
00068 return false;
00069 if (systemAddress==UNASSIGNED_SYSTEM_ADDRESS && broadcast==false)
00070 return false;
00071 PTCPHeader totalLengthOfUserData=0;
00072 int i;
00073 for (i=0; i < numParameters; i++)
00074 {
00075 if (lengths[i]>0)
00076 totalLengthOfUserData+=lengths[i];
00077 }
00078 if (totalLengthOfUserData==0)
00079 return false;
00080
00081 PTCPHeader dataLength;
00082 #ifndef __BITSTREAM_NATIVE_END
00083 if (RakNet::BitStream::DoEndianSwap())
00084 RakNet::BitStream::ReverseBytes((unsigned char*) &totalLengthOfUserData,(unsigned char*) &dataLength,sizeof(dataLength));
00085 #else
00086 dataLength=totalLengthOfUserData;
00087 #endif
00088
00089
00090 unsigned int lengthsArray[512];
00091 const char *dataArray[512];
00092 dataArray[0]=(char*) &dataLength;
00093 lengthsArray[0]=sizeof(dataLength);
00094 for (int i=0; i < 512 && i < numParameters; i++)
00095 {
00096 dataArray[i+1]=data[i];
00097 lengthsArray[i+1]=lengths[i];
00098 }
00099 return TCPInterface::SendList(dataArray,lengthsArray,numParameters+1,systemAddress,broadcast);
00100 }
00101 void PacketizedTCP::PushNotificationsToQueues(void)
00102 {
00103 SystemAddress sa;
00104 sa = TCPInterface::HasNewIncomingConnection();
00105 if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
00106 {
00107 _newIncomingConnections.Push(sa, __FILE__, __LINE__ );
00108 AddToConnectionList(sa);
00109 unsigned int i;
00110 for (i=0; i < messageHandlerList.Size(); i++)
00111 messageHandlerList[i]->OnNewConnection(sa, UNASSIGNED_RAKNET_GUID, true);
00112 }
00113
00114 sa = TCPInterface::HasFailedConnectionAttempt();
00115 if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
00116 {
00117 _failedConnectionAttempts.Push(sa, __FILE__, __LINE__ );
00118 unsigned int i;
00119 for (i=0; i < messageHandlerList.Size(); i++)
00120 {
00121 Packet p;
00122 p.systemAddress=sa;
00123 p.data=0;
00124 p.length=0;
00125 p.bitSize=0;
00126 messageHandlerList[i]->OnFailedConnectionAttempt(&p, FCAR_CONNECTION_ATTEMPT_FAILED);
00127 }
00128 }
00129
00130 sa = TCPInterface::HasLostConnection();
00131 if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
00132 {
00133 _lostConnections.Push(sa, __FILE__, __LINE__ );
00134 RemoveFromConnectionList(sa);
00135 unsigned int i;
00136 for (i=0; i < messageHandlerList.Size(); i++)
00137 messageHandlerList[i]->OnClosedConnection(sa, UNASSIGNED_RAKNET_GUID, LCR_DISCONNECTION_NOTIFICATION);
00138 }
00139
00140 sa = TCPInterface::HasCompletedConnectionAttempt();
00141 if (sa!=UNASSIGNED_SYSTEM_ADDRESS)
00142 {
00143 _completedConnectionAttempts.Push(sa, __FILE__, __LINE__ );
00144 AddToConnectionList(sa);
00145 unsigned int i;
00146 for (i=0; i < messageHandlerList.Size(); i++)
00147 messageHandlerList[i]->OnNewConnection(sa, UNASSIGNED_RAKNET_GUID, true);
00148 }
00149 }
00150 Packet* PacketizedTCP::Receive( void )
00151 {
00152 PushNotificationsToQueues();
00153
00154 unsigned int i;
00155 for (i=0; i < messageHandlerList.Size(); i++)
00156 messageHandlerList[i]->Update();
00157
00158 Packet *outgoingPacket=ReturnOutgoingPacket();
00159 if (outgoingPacket)
00160 return outgoingPacket;
00161
00162 Packet *incomingPacket;
00163 incomingPacket = TCPInterface::Receive();
00164 unsigned int index;
00165
00166 while (incomingPacket)
00167 {
00168 if (connections.Has(incomingPacket->systemAddress))
00169 index = connections.GetIndexAtKey(incomingPacket->systemAddress);
00170 else
00171 index=(unsigned int) -1;
00172 if ((unsigned int)index==(unsigned int)-1)
00173 {
00174 DeallocatePacket(incomingPacket);
00175 incomingPacket = TCPInterface::Receive();
00176 continue;
00177 }
00178
00179
00180 if (incomingPacket->deleteData==true)
00181 {
00182
00183 SystemAddress systemAddressFromPacket;
00184 if (index < connections.Size())
00185 {
00186 DataStructures::ByteQueue *bq = connections[index];
00187
00188 bq->WriteBytes((const char*) incomingPacket->data,incomingPacket->length, __FILE__,__LINE__);
00189 systemAddressFromPacket=incomingPacket->systemAddress;
00190 PTCPHeader dataLength;
00191
00192
00193 bq->ReadBytes((char*) &dataLength,sizeof(PTCPHeader),true);
00194 if (RakNet::BitStream::DoEndianSwap())
00195 RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &dataLength,sizeof(dataLength));
00196
00197 if (bq->GetBytesWritten()>=dataLength+sizeof(PTCPHeader))
00198 {
00199 do
00200 {
00201 bq->IncrementReadOffset(sizeof(PTCPHeader));
00202 outgoingPacket = RakNet::OP_NEW<Packet>(__FILE__, __LINE__);
00203 outgoingPacket->length=dataLength;
00204 outgoingPacket->bitSize=BYTES_TO_BITS(dataLength);
00205 outgoingPacket->guid=UNASSIGNED_RAKNET_GUID;
00206 outgoingPacket->systemAddress=systemAddressFromPacket;
00207 outgoingPacket->deleteData=false;
00208 outgoingPacket->data=(unsigned char*) rakMalloc_Ex(dataLength, __FILE__, __LINE__);
00209 if (outgoingPacket->data==0)
00210 {
00211 notifyOutOfMemory(__FILE__, __LINE__);
00212 RakNet::OP_DELETE(outgoingPacket,__FILE__,__LINE__);
00213 return 0;
00214 }
00215 bq->ReadBytes((char*) outgoingPacket->data,dataLength,false);
00216
00217 waitingPackets.Push(outgoingPacket, __FILE__, __LINE__ );
00218
00219
00220 if (bq->ReadBytes((char*) &dataLength,sizeof(PTCPHeader),true))
00221 {
00222 if (RakNet::BitStream::DoEndianSwap())
00223 RakNet::BitStream::ReverseBytesInPlace((unsigned char*) &dataLength,sizeof(dataLength));
00224 }
00225 else
00226 break;
00227 } while (bq->GetBytesWritten()>=dataLength+sizeof(PTCPHeader));
00228 }
00229 else
00230 {
00231
00232 unsigned int oldWritten = bq->GetBytesWritten()-incomingPacket->length;
00233 unsigned int newWritten = bq->GetBytesWritten();
00234
00235
00236 if (newWritten/65536!=oldWritten/65536)
00237 {
00238 outgoingPacket = RakNet::OP_NEW<Packet>(__FILE__, __LINE__);
00239 outgoingPacket->length=sizeof(MessageID) +
00240 sizeof(unsigned int)*2 +
00241 sizeof(unsigned int) +
00242 65536;
00243 outgoingPacket->bitSize=BYTES_TO_BITS(incomingPacket->length);
00244 outgoingPacket->guid=UNASSIGNED_RAKNET_GUID;
00245 outgoingPacket->systemAddress=incomingPacket->systemAddress;
00246 outgoingPacket->deleteData=false;
00247 outgoingPacket->data=(unsigned char*) rakMalloc_Ex(outgoingPacket->length, __FILE__, __LINE__);
00248 if (outgoingPacket->data==0)
00249 {
00250 notifyOutOfMemory(__FILE__, __LINE__);
00251 RakNet::OP_DELETE(outgoingPacket,__FILE__,__LINE__);
00252 return 0;
00253 }
00254
00255 outgoingPacket->data[0]=(MessageID)ID_DOWNLOAD_PROGRESS;
00256 unsigned int totalParts=dataLength/65536;
00257 unsigned int partIndex=newWritten/65536;
00258 unsigned int oneChunkSize=65536;
00259 memcpy(outgoingPacket->data+sizeof(MessageID), &partIndex, sizeof(unsigned int));
00260 memcpy(outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*1, &totalParts, sizeof(unsigned int));
00261 memcpy(outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*2, &oneChunkSize, sizeof(unsigned int));
00262 bq->IncrementReadOffset(sizeof(PTCPHeader));
00263 bq->ReadBytes((char*) outgoingPacket->data+sizeof(MessageID)+sizeof(unsigned int)*3,oneChunkSize,true);
00264 bq->DecrementReadOffset(sizeof(PTCPHeader));
00265
00266 waitingPackets.Push(outgoingPacket, __FILE__, __LINE__ );
00267 }
00268 }
00269
00270 }
00271
00272 DeallocatePacket(incomingPacket);
00273 incomingPacket=0;
00274 }
00275 else
00276 waitingPackets.Push(incomingPacket, __FILE__, __LINE__ );
00277
00278 incomingPacket = TCPInterface::Receive();
00279 }
00280
00281 return ReturnOutgoingPacket();
00282 }
00283 Packet *PacketizedTCP::ReturnOutgoingPacket(void)
00284 {
00285 Packet *outgoingPacket=0;
00286 unsigned int i;
00287 while (outgoingPacket==0 && waitingPackets.IsEmpty()==false)
00288 {
00289 outgoingPacket=waitingPackets.Pop();
00290 PluginReceiveResult pluginResult;
00291 for (i=0; i < messageHandlerList.Size(); i++)
00292 {
00293 pluginResult=messageHandlerList[i]->OnReceive(outgoingPacket);
00294 if (pluginResult==RR_STOP_PROCESSING_AND_DEALLOCATE)
00295 {
00296 DeallocatePacket( outgoingPacket );
00297 outgoingPacket=0;
00298 break;
00299 }
00300 else if (pluginResult==RR_STOP_PROCESSING)
00301 {
00302 outgoingPacket=0;
00303 break;
00304 }
00305 }
00306 }
00307
00308 return outgoingPacket;
00309 }
00310
00311 void PacketizedTCP::AttachPlugin( PluginInterface2 *plugin )
00312 {
00313 if (messageHandlerList.GetIndexOf(plugin)==MAX_UNSIGNED_LONG)
00314 {
00315 messageHandlerList.Insert(plugin, __FILE__, __LINE__);
00316 plugin->SetPacketizedTCP(this);
00317 plugin->OnAttach();
00318 }
00319 }
00320 void PacketizedTCP::DetachPlugin( PluginInterface2 *plugin )
00321 {
00322 if (plugin==0)
00323 return;
00324
00325 unsigned int index;
00326 index = messageHandlerList.GetIndexOf(plugin);
00327 if (index!=MAX_UNSIGNED_LONG)
00328 {
00329 messageHandlerList[index]->OnDetach();
00330
00331 messageHandlerList[index]=messageHandlerList[messageHandlerList.Size()-1];
00332 messageHandlerList.RemoveFromEnd();
00333 plugin->SetPacketizedTCP(0);
00334 }
00335 }
00336 void PacketizedTCP::CloseConnection( SystemAddress systemAddress )
00337 {
00338 RemoveFromConnectionList(systemAddress);
00339 unsigned int i;
00340 for (i=0; i < messageHandlerList.Size(); i++)
00341 messageHandlerList[i]->OnClosedConnection(systemAddress, UNASSIGNED_RAKNET_GUID, LCR_CLOSED_BY_USER);
00342 TCPInterface::CloseConnection(systemAddress);
00343 }
00344 void PacketizedTCP::RemoveFromConnectionList(SystemAddress sa)
00345 {
00346 if (sa==UNASSIGNED_SYSTEM_ADDRESS)
00347 return;
00348 if (connections.Has(sa))
00349 {
00350 unsigned int index = connections.GetIndexAtKey(sa);
00351 if (index!=(unsigned int)-1)
00352 {
00353 RakNet::OP_DELETE(connections[index],__FILE__,__LINE__);
00354 connections.RemoveAtIndex(index);
00355 }
00356 }
00357 }
00358 void PacketizedTCP::AddToConnectionList(SystemAddress sa)
00359 {
00360 if (sa==UNASSIGNED_SYSTEM_ADDRESS)
00361 return;
00362 connections.SetNew(sa, RakNet::OP_NEW<DataStructures::ByteQueue>(__FILE__, __LINE__));
00363 }
00364 void PacketizedTCP::ClearAllConnections(void)
00365 {
00366 unsigned int i;
00367 for (i=0; i < connections.Size(); i++)
00368 RakNet::OP_DELETE(connections[i],__FILE__,__LINE__);
00369 connections.Clear();
00370 }
00371 SystemAddress PacketizedTCP::HasCompletedConnectionAttempt(void)
00372 {
00373 PushNotificationsToQueues();
00374
00375 if (_completedConnectionAttempts.IsEmpty()==false)
00376 return _completedConnectionAttempts.Pop();
00377 return UNASSIGNED_SYSTEM_ADDRESS;
00378 }
00379 SystemAddress PacketizedTCP::HasFailedConnectionAttempt(void)
00380 {
00381 PushNotificationsToQueues();
00382
00383 if (_failedConnectionAttempts.IsEmpty()==false)
00384 return _failedConnectionAttempts.Pop();
00385 return UNASSIGNED_SYSTEM_ADDRESS;
00386 }
00387 SystemAddress PacketizedTCP::HasNewIncomingConnection(void)
00388 {
00389 PushNotificationsToQueues();
00390
00391 if (_newIncomingConnections.IsEmpty()==false)
00392 return _newIncomingConnections.Pop();
00393 return UNASSIGNED_SYSTEM_ADDRESS;
00394 }
00395 SystemAddress PacketizedTCP::HasLostConnection(void)
00396 {
00397 PushNotificationsToQueues();
00398
00399 if (_lostConnections.IsEmpty()==false)
00400 return _lostConnections.Pop();
00401 return UNASSIGNED_SYSTEM_ADDRESS;
00402 }
00403
00404 #endif // _RAKNET_SUPPORT_*