00001 #include "NativeFeatureIncludes.h"
00002 #if _RAKNET_SUPPORT_AutoRPC==1
00003
00004 #include "AutoRPC.h"
00005 #include "RakMemoryOverride.h"
00006 #include "RakAssert.h"
00007 #include "StringCompressor.h"
00008 #include "BitStream.h"
00009
00010 #include "RakPeerInterface.h"
00011 #include "MessageIdentifiers.h"
00012 #include "NetworkIDObject.h"
00013 #include "NetworkIDManager.h"
00014 #include <stdlib.h>
00015
00016 using namespace RakNet;
00017
00018 #ifdef _MSC_VER
00019 #pragma warning( push )
00020 #endif
00021
00022 int AutoRPC::RemoteRPCFunctionComp( const RPCIdentifier &key, const RemoteRPCFunction &data )
00023 {
00024 if (key.isObjectMember==false && data.identifier.isObjectMember==true)
00025 return -1;
00026 if (key.isObjectMember==true && data.identifier.isObjectMember==false)
00027 return 1;
00028 return strcmp(key.uniqueIdentifier, data.identifier.uniqueIdentifier);
00029 }
00030
00031 AutoRPC::AutoRPC()
00032 {
00033 currentExecution[0]=0;
00034 networkIdManager=0;
00035 outgoingTimestamp=0;
00036 outgoingPriority=HIGH_PRIORITY;
00037 outgoingReliability=RELIABLE_ORDERED;
00038 outgoingOrderingChannel=0;
00039 outgoingBroadcast=true;
00040 incomingTimeStamp=0;
00041 DataStructures::Map<SystemAddress, DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *>::IMPLEMENT_DEFAULT_COMPARISON();
00042 }
00043
00044 AutoRPC::~AutoRPC()
00045 {
00046 Clear();
00047 }
00048 void AutoRPC::SetNetworkIDManager(NetworkIDManager *idMan)
00049 {
00050 networkIdManager=idMan;
00051 }
00052 bool AutoRPC::RegisterFunction(const char *uniqueIdentifier, void *functionPtr, bool isObjectMember, char parameterCount)
00053 {
00054 if (uniqueIdentifier==0 || functionPtr==0)
00055 {
00056 RakAssert(0);
00057 return false;
00058 }
00059
00060 RPCIdentifier identifier;
00061 identifier.isObjectMember=isObjectMember;
00062 identifier.uniqueIdentifier=(char*) uniqueIdentifier;
00063 unsigned localIndex = GetLocalFunctionIndex(identifier);
00064
00065 if (localIndex!=(unsigned)-1 && localFunctions[localIndex].functionPtr!=0)
00066 return false;
00067 if (localIndex!=(unsigned)-1)
00068 {
00069
00070 localFunctions[localIndex].functionPtr=functionPtr;
00071 localFunctions[localIndex].parameterCount=parameterCount;
00072 }
00073 else
00074 {
00075
00076 LocalRPCFunction func;
00077 func.functionPtr=functionPtr;
00078 func.identifier.isObjectMember=isObjectMember;
00079 func.identifier.uniqueIdentifier = (char*) rakMalloc_Ex(strlen(uniqueIdentifier)+1, __FILE__, __LINE__);
00080 func.parameterCount=parameterCount;
00081 strcpy(func.identifier.uniqueIdentifier, uniqueIdentifier);
00082 localFunctions.Insert(func, __FILE__, __LINE__);
00083 }
00084 return true;
00085 }
00086 bool AutoRPC::UnregisterFunction(const char *uniqueIdentifier, bool isObjectMember)
00087 {
00088 if (uniqueIdentifier==0)
00089 {
00090 RakAssert(0);
00091 return false;
00092 }
00093
00094 RPCIdentifier identifier;
00095 identifier.isObjectMember=isObjectMember;
00096 identifier.uniqueIdentifier=(char*) uniqueIdentifier;
00097 unsigned localIndex = GetLocalFunctionIndex(identifier);
00098
00099 if (localIndex==(unsigned)-1)
00100 return false;
00101
00102 localFunctions[localIndex].functionPtr=0;
00103 return true;
00104 }
00105 void AutoRPC::SetTimestamp(RakNetTime timeStamp)
00106 {
00107 outgoingTimestamp=timeStamp;
00108 }
00109 void AutoRPC::SetSendParams(PacketPriority priority, PacketReliability reliability, char orderingChannel)
00110 {
00111 outgoingPriority=priority;
00112 outgoingReliability=reliability;
00113 outgoingOrderingChannel=orderingChannel;
00114 }
00115 void AutoRPC::SetRecipientAddress(AddressOrGUID systemIdentifier, bool broadcast)
00116 {
00117 outgoingSystemIdentifier=systemIdentifier;
00118 outgoingBroadcast=broadcast;
00119 }
00120 void AutoRPC::SetRecipientObject(NetworkID networkID)
00121 {
00122 outgoingNetworkID=networkID;
00123 }
00124 RakNet::BitStream *AutoRPC::SetOutgoingExtraData(void)
00125 {
00126 return &outgoingExtraData;
00127 }
00128 RakNetTime AutoRPC::GetLastSenderTimestamp(void) const
00129 {
00130 return incomingTimeStamp;
00131 }
00132 SystemAddress AutoRPC::GetLastSenderAddress(void) const
00133 {
00134 return incomingSystemAddress;
00135 }
00136 RakPeerInterface *AutoRPC::GetRakPeer(void) const
00137 {
00138 return rakPeerInterface;
00139 }
00140 const char *AutoRPC::GetCurrentExecution(void) const
00141 {
00142 return (const char *) currentExecution;
00143 }
00144 RakNet::BitStream *AutoRPC::GetIncomingExtraData(void)
00145 {
00146 return &incomingExtraData;
00147 }
00148 bool AutoRPC::SendCall(const char *uniqueIdentifier, const char *stack, unsigned int bytesOnStack, char parameterCount)
00149 {
00150 SystemAddress systemAddr;
00151 RPCIdentifier identifier;
00152 unsigned int outerIndex;
00153 unsigned int innerIndex;
00154
00155 if (uniqueIdentifier==0)
00156 return false;
00157
00158 identifier.uniqueIdentifier=(char*) uniqueIdentifier;
00159 identifier.isObjectMember=(outgoingNetworkID!=UNASSIGNED_NETWORK_ID);
00160
00161 RakNet::BitStream bs;
00162 if (outgoingTimestamp!=0)
00163 {
00164 bs.Write((MessageID)ID_TIMESTAMP);
00165 bs.Write(outgoingTimestamp);
00166 }
00167 bs.Write((MessageID)ID_AUTO_RPC_CALL);
00168 if (parameterCount>=0)
00169 {
00170 bs.Write(true);
00171 bs.Write(parameterCount);
00172 }
00173 else
00174 {
00175 bs.Write(false);
00176 }
00177 bs.WriteCompressed(outgoingExtraData.GetNumberOfBitsUsed());
00178 bs.Write(&outgoingExtraData);
00179 if (outgoingNetworkID!=UNASSIGNED_NETWORK_ID)
00180 {
00181 bs.Write(true);
00182 bs.Write(outgoingNetworkID);
00183 }
00184 else
00185 {
00186 bs.Write(false);
00187 }
00188
00189 bs.AlignWriteToByteBoundary();
00190 BitSize_t writeOffset = bs.GetWriteOffset();
00191 SystemAddress outgoingSystemAddress;
00192 if (outgoingSystemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID)
00193 outgoingSystemAddress = rakPeerInterface->GetSystemAddressFromGuid(outgoingSystemIdentifier.rakNetGuid);
00194 else
00195 outgoingSystemAddress = outgoingSystemIdentifier.systemAddress;
00196 if (outgoingBroadcast)
00197 {
00198 unsigned systemIndex;
00199 for (systemIndex=0; systemIndex < rakPeerInterface->GetMaximumNumberOfPeers(); systemIndex++)
00200 {
00201 systemAddr=rakPeerInterface->GetSystemAddressFromIndex(systemIndex);
00202 if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS && systemAddr!=outgoingSystemAddress)
00203 {
00204 if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex))
00205 {
00206
00207 bs.Write(true);
00208 bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex);
00209 }
00210 else
00211 {
00212 bs.Write(false);
00213 stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0);
00214 }
00215
00216 bs.WriteCompressed(bytesOnStack);
00217 bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack);
00218 SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false);
00219
00220
00221 bs.SetWriteOffset(writeOffset);
00222 }
00223 }
00224 }
00225 else
00226 {
00227 systemAddr = outgoingSystemAddress;
00228 if (systemAddr!=UNASSIGNED_SYSTEM_ADDRESS)
00229 {
00230 if (GetRemoteFunctionIndex(systemAddr, identifier, &outerIndex, &innerIndex))
00231 {
00232
00233 bs.Write(true);
00234 bs.WriteCompressed(remoteFunctions[outerIndex]->operator [](innerIndex).functionIndex);
00235 }
00236 else
00237 {
00238 bs.Write(false);
00239 stringCompressor->EncodeString(uniqueIdentifier, 512, &bs, 0);
00240 }
00241
00242 bs.WriteCompressed(bytesOnStack);
00243 bs.WriteAlignedBytes((const unsigned char*) stack, bytesOnStack);
00244 SendUnified(&bs, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddr, false);
00245 }
00246 else
00247 return false;
00248 }
00249 return true;
00250 }
00251 void AutoRPC::OnAttach(void)
00252 {
00253 outgoingSystemIdentifier.SetUndefined();
00254 outgoingNetworkID=UNASSIGNED_NETWORK_ID;
00255 incomingSystemAddress=UNASSIGNED_SYSTEM_ADDRESS;
00256
00257 }
00258 PluginReceiveResult AutoRPC::OnReceive(Packet *packet)
00259 {
00260 RakNetTime timestamp=0;
00261 unsigned char packetIdentifier, packetDataOffset;
00262 if ( ( unsigned char ) packet->data[ 0 ] == ID_TIMESTAMP )
00263 {
00264 if ( packet->length > sizeof( unsigned char ) + sizeof( RakNetTime ) )
00265 {
00266 packetIdentifier = ( unsigned char ) packet->data[ sizeof( unsigned char ) + sizeof( RakNetTime ) ];
00267
00268 RakNet::BitStream tsBs(packet->data+sizeof(MessageID),packet->length-1,false);
00269 tsBs.Read(timestamp);
00270 packetDataOffset=sizeof( unsigned char )*2 + sizeof( RakNetTime );
00271 }
00272 else
00273 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00274 }
00275 else
00276 {
00277 packetIdentifier = ( unsigned char ) packet->data[ 0 ];
00278 packetDataOffset=sizeof( unsigned char );
00279 }
00280
00281 switch (packetIdentifier)
00282 {
00283 case ID_AUTO_RPC_CALL:
00284 incomingTimeStamp=timestamp;
00285 incomingSystemAddress=packet->systemAddress;
00286 OnAutoRPCCall(packet->systemAddress, packet->data+packetDataOffset, packet->length-packetDataOffset);
00287 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00288 case ID_AUTO_RPC_REMOTE_INDEX:
00289 OnRPCRemoteIndex(packet->systemAddress, packet->data+packetDataOffset, packet->length-packetDataOffset);
00290 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00291 case ID_AUTO_RPC_UNKNOWN_REMOTE_INDEX:
00292 OnRPCUnknownRemoteIndex(packet->systemAddress, packet->data+packetDataOffset, packet->length-packetDataOffset, timestamp);
00293 return RR_STOP_PROCESSING_AND_DEALLOCATE;
00294 }
00295
00296 return RR_CONTINUE_PROCESSING;
00297 }
00298 void AutoRPC::OnClosedConnection(SystemAddress systemAddress, RakNetGUID rakNetGUID, PI2_LostConnectionReason lostConnectionReason )
00299 {
00300 (void) rakNetGUID;
00301 (void) lostConnectionReason;
00302
00303 if (remoteFunctions.Has(systemAddress))
00304 {
00305 DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions.Get(systemAddress);
00306 unsigned i;
00307 for (i=0; i < theList->Size(); i++)
00308 {
00309 if (theList->operator [](i).identifier.uniqueIdentifier)
00310 rakFree_Ex(theList->operator [](i).identifier.uniqueIdentifier, __FILE__, __LINE__ );
00311 }
00312 RakNet::OP_DELETE(theList, __FILE__, __LINE__);
00313 remoteFunctions.Delete(systemAddress);
00314 }
00315 }
00316 void AutoRPC::OnAutoRPCCall(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes)
00317 {
00318 RakNet::BitStream bs(data,lengthInBytes,false);
00319
00320 bool hasParameterCount=false;
00321 char parameterCount;
00322 char inputStack[ARPC_MAX_STACK_SIZE];
00323 NetworkIDObject *networkIdObject;
00324 NetworkID networkId;
00325 bool hasNetworkId=false;
00326 bool hasFunctionIndex=false;
00327 unsigned int functionIndex;
00328 unsigned int bytesOnStack;
00329 char strIdentifier[512];
00330 int numberOfBitsUsed;
00331 incomingExtraData.Reset();
00332 bs.Read(hasParameterCount);
00333 if (hasParameterCount)
00334 bs.Read(parameterCount);
00335 else
00336 parameterCount=-1;
00337 bs.ReadCompressed(numberOfBitsUsed);
00338 if (numberOfBitsUsed > (int) incomingExtraData.GetNumberOfBitsAllocated())
00339 incomingExtraData.AddBitsAndReallocate(numberOfBitsUsed-(int) incomingExtraData.GetNumberOfBitsAllocated());
00340 bs.ReadBits(incomingExtraData.GetData(), numberOfBitsUsed, false);
00341 incomingExtraData.SetWriteOffset(numberOfBitsUsed);
00342
00343
00344
00345
00346
00347 bs.Read(hasNetworkId);
00348 if (hasNetworkId)
00349 {
00350 bs.Read(networkId);
00351 if (networkIdManager==0 && (networkIdManager=rakPeerInterface->GetNetworkIDManager())==0)
00352 {
00353
00354 SendError(systemAddress, RPC_ERROR_NETWORK_ID_MANAGER_UNAVAILABLE, "");
00355 return;
00356 }
00357 networkIdObject = networkIdManager->GET_OBJECT_FROM_ID<NetworkIDObject*>(networkId);
00358 if (networkIdObject==0)
00359 {
00360
00361 SendError(systemAddress, RPC_ERROR_OBJECT_DOES_NOT_EXIST, "");
00362 return;
00363 }
00364 }
00365 else
00366 {
00367 networkIdObject=0;
00368 }
00369 bs.AlignReadToByteBoundary();
00370 bs.Read(hasFunctionIndex);
00371 if (hasFunctionIndex)
00372 bs.ReadCompressed(functionIndex);
00373 else
00374 stringCompressor->DecodeString(strIdentifier,512,&bs,0);
00375 bs.ReadCompressed(bytesOnStack);
00376 bs.ReadAlignedBytes((unsigned char *) inputStack,bytesOnStack);
00377 if (hasFunctionIndex)
00378 {
00379 if (functionIndex>localFunctions.Size())
00380 {
00381
00382
00383 SendError(systemAddress, RPC_ERROR_FUNCTION_INDEX_OUT_OF_RANGE, "");
00384 return;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 }
00421 else
00422 {
00423
00424 for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++)
00425 {
00426 if (localFunctions[functionIndex].identifier.isObjectMember == (networkIdObject!=0) &&
00427 strcmp(localFunctions[functionIndex].identifier.uniqueIdentifier, strIdentifier)==0)
00428 {
00429
00430 RakNet::BitStream outgoingBitstream;
00431 outgoingBitstream.Write((MessageID)ID_AUTO_RPC_REMOTE_INDEX);
00432 outgoingBitstream.Write(hasNetworkId);
00433 outgoingBitstream.WriteCompressed(functionIndex);
00434 stringCompressor->EncodeString(strIdentifier,512,&outgoingBitstream,0);
00435 SendUnified(&outgoingBitstream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, systemAddress, false);
00436 break;
00437 }
00438 }
00439
00440 if (functionIndex==localFunctions.Size())
00441 {
00442 for (functionIndex=0; functionIndex < localFunctions.Size(); functionIndex++)
00443 {
00444 if (strcmp(localFunctions[functionIndex].identifier.uniqueIdentifier, strIdentifier)==0)
00445 {
00446 if (localFunctions[functionIndex].identifier.isObjectMember==true && networkIdObject==0)
00447 {
00448
00449 SendError(systemAddress, RPC_ERROR_CALLING_CPP_AS_C, strIdentifier);
00450 return;
00451 }
00452
00453 if (localFunctions[functionIndex].identifier.isObjectMember==false && networkIdObject!=0)
00454 {
00455
00456 SendError(systemAddress, RPC_ERROR_CALLING_C_AS_CPP, strIdentifier);
00457 return;
00458 }
00459 }
00460 }
00461
00462 SendError(systemAddress, RPC_ERROR_FUNCTION_NOT_REGISTERED, strIdentifier);
00463 return;
00464 }
00465 }
00466
00467 if (localFunctions[functionIndex].functionPtr==0)
00468 {
00469
00470 SendError(systemAddress, RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED, localFunctions[functionIndex].identifier.uniqueIdentifier);
00471 return;
00472 }
00473
00474 if (bytesOnStack > ARPC_MAX_STACK_SIZE)
00475 {
00476
00477 SendError(systemAddress, RPC_ERROR_STACK_TOO_SMALL, localFunctions[functionIndex].identifier.uniqueIdentifier);
00478 return;
00479 }
00480
00481 if (localFunctions[functionIndex].parameterCount>=0 && parameterCount>=0 && parameterCount!=localFunctions[functionIndex].parameterCount)
00482 {
00483
00484 SendError(systemAddress, RPC_ERROR_INCORRECT_NUMBER_OF_PARAMETERS, localFunctions[functionIndex].identifier.uniqueIdentifier);
00485 return;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494 GenRPC::CallParams call;
00495
00496 if (DeserializeParametersAndBuildCall(call, inputStack, bytesOnStack, this, networkIdObject)==false)
00497 {
00498
00499 SendError(systemAddress, RPC_ERROR_STACK_DESERIALIZATION_FAILED, localFunctions[functionIndex].identifier.uniqueIdentifier);
00500 return;
00501 }
00502
00503 strncpy(currentExecution, localFunctions[functionIndex].identifier.uniqueIdentifier, sizeof(currentExecution)-1);
00504
00505 if (!CallWithStack( call, localFunctions[functionIndex].functionPtr)){
00506
00507 SendError(systemAddress, RPC_ERROR_STACK_DESERIALIZATION_FAILED, currentExecution);
00508 return;
00509 }
00510
00511
00512 currentExecution[0]=0;
00513 }
00514 void AutoRPC::OnRPCRemoteIndex(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes)
00515 {
00516
00517
00518 bool objectExists;
00519 char strIdentifier[512];
00520 unsigned int insertionIndex;
00521 unsigned int remoteIndex;
00522 RemoteRPCFunction newRemoteFunction;
00523 RakNet::BitStream bs(data,lengthInBytes,false);
00524 RPCIdentifier identifier;
00525 bs.Read(identifier.isObjectMember);
00526 bs.ReadCompressed(remoteIndex);
00527 stringCompressor->DecodeString(strIdentifier,512,&bs,0);
00528 identifier.uniqueIdentifier=strIdentifier;
00529
00530 if (strIdentifier[0]==0)
00531 return;
00532
00533 DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList;
00534 if (remoteFunctions.Has(systemAddress))
00535 {
00536 theList = remoteFunctions.Get(systemAddress);
00537 insertionIndex=theList->GetIndexFromKey(identifier, &objectExists);
00538 if (objectExists==false)
00539 {
00540 newRemoteFunction.functionIndex=remoteIndex;
00541 newRemoteFunction.identifier.isObjectMember=identifier.isObjectMember;
00542 newRemoteFunction.identifier.uniqueIdentifier = (char*) rakMalloc_Ex(strlen(strIdentifier)+1, __FILE__, __LINE__);
00543 strcpy(newRemoteFunction.identifier.uniqueIdentifier, strIdentifier);
00544 theList->InsertAtIndex(newRemoteFunction, insertionIndex, __FILE__, __LINE__);
00545 }
00546 }
00547 else
00548 {
00549 theList = RakNet::OP_NEW<DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> >( __FILE__, __LINE__ );
00550
00551 newRemoteFunction.functionIndex=remoteIndex;
00552 newRemoteFunction.identifier.isObjectMember=identifier.isObjectMember;
00553 newRemoteFunction.identifier.uniqueIdentifier = (char*) rakMalloc_Ex(strlen(strIdentifier)+1, __FILE__, __LINE__);
00554 strcpy(newRemoteFunction.identifier.uniqueIdentifier, strIdentifier);
00555 theList->InsertAtEnd(newRemoteFunction, __FILE__, __LINE__);
00556
00557 remoteFunctions.SetNew(systemAddress,theList);
00558 }
00559 }
00560 void AutoRPC::OnRPCUnknownRemoteIndex(SystemAddress systemAddress, unsigned char *data, unsigned int lengthInBytes, RakNetTime timestamp)
00561 {
00562 char inputStack[ARPC_MAX_STACK_SIZE];
00563 NetworkID networkId;
00564 bool hasNetworkId=false;
00565 unsigned int functionIndex;
00566 unsigned int bytesOnStack;
00567 int numberOfBitsUsed;
00568 char parameterCount;
00569 bool hasParameterCount=false;
00570
00571 RakNet::BitStream extraData;
00572 RakNet::BitStream bs(data,lengthInBytes,false);
00573 bs.Read(hasParameterCount);
00574 if (hasParameterCount)
00575 bs.Read(parameterCount);
00576 bs.ReadCompressed(functionIndex);
00577 bs.ReadCompressed(numberOfBitsUsed);
00578 extraData.AddBitsAndReallocate(numberOfBitsUsed);
00579 bs.ReadBits(extraData.GetData(), numberOfBitsUsed, false);
00580 extraData.SetWriteOffset(numberOfBitsUsed);
00581 bs.Read(hasNetworkId);
00582 if (hasNetworkId)
00583 bs.Read(networkId);
00584 bs.ReadCompressed(bytesOnStack);
00585 bs.ReadAlignedBytes((unsigned char*) inputStack, bytesOnStack);
00586
00587 unsigned outerIndex;
00588 if (remoteFunctions.Has(systemAddress))
00589 {
00590 outerIndex = remoteFunctions.GetIndexAtKey(systemAddress);
00591 DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[outerIndex];
00592 unsigned i;
00593 for (i=0; i < theList->Size(); i++)
00594 {
00595 if (theList->operator [](i).functionIndex==functionIndex)
00596 {
00597 RakNet::BitStream out;
00598
00599 if (timestamp!=0)
00600 {
00601 out.Write((MessageID)ID_TIMESTAMP);
00602 out.Write(timestamp);
00603 }
00604 out.Write((MessageID)ID_AUTO_RPC_CALL);
00605 if (parameterCount>=0)
00606 {
00607 out.Write(true);
00608 out.Write(parameterCount);
00609 }
00610 else
00611 {
00612 out.Write(false);
00613 }
00614 out.WriteCompressed(numberOfBitsUsed);
00615 out.Write(&extraData);
00616 out.Write(hasNetworkId);
00617 if (hasNetworkId)
00618 out.Write(networkId);
00619 out.AlignWriteToByteBoundary();
00620 out.Write(false);
00621 stringCompressor->EncodeString(theList->operator [](i).identifier.uniqueIdentifier, 512, &out, 0);
00622 out.WriteCompressed(bytesOnStack);
00623 out.WriteAlignedBytes((const unsigned char*) inputStack, bytesOnStack);
00624 SendUnified(&out, outgoingPriority, outgoingReliability, outgoingOrderingChannel, systemAddress, false);
00625 return;
00626 }
00627 }
00628 }
00629
00630
00631 Packet *p = rakPeerInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char));
00632 RakNet::BitStream bs2(p->data, sizeof(MessageID)+sizeof(unsigned char), false);
00633 bs2.SetWriteOffset(0);
00634 bs2.Write((MessageID)ID_RPC_REMOTE_ERROR);
00635 bs2.Write((unsigned char)RPC_ERROR_FUNCTION_NO_LONGER_REGISTERED);
00636 stringCompressor->EncodeString("",256,&bs,0);
00637 p->systemAddress=systemAddress;
00638 rakPeerInterface->PushBackPacket(p, false);
00639
00640 }
00641 void AutoRPC::SendError(SystemAddress target, unsigned char errorCode, const char *functionName)
00642 {
00643 RakNet::BitStream bs;
00644 bs.Write((MessageID)ID_RPC_REMOTE_ERROR);
00645 bs.Write(errorCode);
00646 stringCompressor->EncodeString(functionName,256,&bs,0);
00647 SendUnified(&bs, HIGH_PRIORITY, RELIABLE_ORDERED, 0, target, false);
00648 }
00649 void AutoRPC::OnRakPeerShutdown(void)
00650 {
00651 Clear();
00652 }
00653 void AutoRPC::Clear(void)
00654 {
00655 unsigned i,j;
00656 for (j=0; j < remoteFunctions.Size(); j++)
00657 {
00658 DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[j];
00659 for (i=0; i < theList->Size(); i++)
00660 {
00661 if (theList->operator [](i).identifier.uniqueIdentifier)
00662 rakFree_Ex(theList->operator [](i).identifier.uniqueIdentifier, __FILE__, __LINE__ );
00663 }
00664 RakNet::OP_DELETE(theList, __FILE__, __LINE__);
00665 }
00666 for (i=0; i < localFunctions.Size(); i++)
00667 {
00668 if (localFunctions[i].identifier.uniqueIdentifier)
00669 rakFree_Ex(localFunctions[i].identifier.uniqueIdentifier, __FILE__, __LINE__ );
00670 }
00671 localFunctions.Clear(false, __FILE__, __LINE__);
00672 remoteFunctions.Clear();
00673 outgoingExtraData.Reset();
00674 incomingExtraData.Reset();
00675 }
00676 unsigned AutoRPC::GetLocalFunctionIndex(AutoRPC::RPCIdentifier identifier)
00677 {
00678 unsigned i;
00679 for (i=0; i < localFunctions.Size(); i++)
00680 {
00681 if (localFunctions[i].identifier.isObjectMember==identifier.isObjectMember &&
00682 strcmp(localFunctions[i].identifier.uniqueIdentifier,identifier.uniqueIdentifier)==0)
00683 return i;
00684 }
00685 return (unsigned) -1;
00686 }
00687 bool AutoRPC::GetRemoteFunctionIndex(SystemAddress systemAddress, AutoRPC::RPCIdentifier identifier, unsigned int *outerIndex, unsigned int *innerIndex)
00688 {
00689 bool objectExists=false;
00690 if (remoteFunctions.Has(systemAddress))
00691 {
00692 *outerIndex = remoteFunctions.GetIndexAtKey(systemAddress);
00693 DataStructures::OrderedList<RPCIdentifier, RemoteRPCFunction, AutoRPC::RemoteRPCFunctionComp> *theList = remoteFunctions[*outerIndex];
00694 *innerIndex = theList->GetIndexFromKey(identifier, &objectExists);
00695 }
00696 return objectExists;
00697 }
00698
00699
00700 #ifdef _MSC_VER
00701 #pragma warning( pop )
00702 #endif
00703
00704 #endif // _RAKNET_SUPPORT_*