diff --git a/raknet/NetworkTypes.h b/raknet/NetworkTypes.h index 29726c1..37d5fcc 100644 --- a/raknet/NetworkTypes.h +++ b/raknet/NetworkTypes.h @@ -213,7 +213,7 @@ const int PING_TIMES_ARRAY_SIZE = 5; /// \attention 12/01/05 REGISTER_AS_REMOTE_PROCEDURE_CALL renamed to REGISTER_STATIC_RPC. Delete the old name sometime in the future //#pragma deprecated(REGISTER_AS_REMOTE_PROCEDURE_CALL) //#define REGISTER_AS_REMOTE_PROCEDURE_CALL(networkObject, functionName) REGISTER_STATIC_RPC(networkObject, functionName) -#define REGISTER_STATIC_RPC(networkObject, functionName) (networkObject)->RegisterAsRemoteProcedureCall((#functionName),(functionName)) +#define REGISTER_STATIC_RPC(networkObject, functionName) (networkObject)->RegisterAsRemoteProcedureCall((RPC_##functionName),(functionName)) /// \def CLASS_MEMBER_ID /// \ingroup RAKNET_RPC @@ -245,7 +245,7 @@ const int PING_TIMES_ARRAY_SIZE = 5; // 12/01/05 UNREGISTER_AS_REMOTE_PROCEDURE_CALL Renamed to UNREGISTER_STATIC_RPC. Delete the old name sometime in the future //#pragma deprecated(UNREGISTER_AS_REMOTE_PROCEDURE_CALL) //#define UNREGISTER_AS_REMOTE_PROCEDURE_CALL(networkObject,functionName) UNREGISTER_STATIC_RPC(networkObject,functionName) -#define UNREGISTER_STATIC_RPC(networkObject,functionName) (networkObject)->UnregisterAsRemoteProcedureCall((#functionName)) +#define UNREGISTER_STATIC_RPC(networkObject,functionName) (networkObject)->UnregisterAsRemoteProcedureCall((RPC_##functionName)) /// \def UNREGISTER_CLASS_INST_RPC /// \ingroup RAKNET_RPC diff --git a/raknet/RPCMap.cpp b/raknet/RPCMap.cpp index 88be0a0..bc23cfb 100644 --- a/raknet/RPCMap.cpp +++ b/raknet/RPCMap.cpp @@ -19,6 +19,9 @@ RPCMap::RPCMap() { + unsigned i; + for (i=0; i < RPC_SET_SIZE; i++) + rpcSet[i] = 0; } RPCMap::~RPCMap() { @@ -27,81 +30,36 @@ RPCMap::~RPCMap() void RPCMap::Clear(void) { unsigned i; - RPCNode *node; - for (i=0; i < rpcSet.Size(); i++) + for (i=0; i < RPC_SET_SIZE; i++) { - node=rpcSet[i]; - if (node) - { - delete [] node->uniqueIdentifier; - delete node; - } + if(rpcSet[i]) + delete rpcSet[i]; + rpcSet[i] = 0; } - rpcSet.Clear(); } RPCNode *RPCMap::GetNodeFromIndex(RPCIndex index) { - if ((unsigned)index < rpcSet.Size()) - return rpcSet[(unsigned)index]; - return 0; + return rpcSet[(unsigned)index];; } -RPCNode *RPCMap::GetNodeFromFunctionName(char *uniqueIdentifier) +RPCNode *RPCMap::GetNodeFromFunctionName(unsigned char uniqueIdentifier) { - unsigned index; - index=(unsigned)GetIndexFromFunctionName(uniqueIdentifier); - if ((RPCIndex)index!=UNDEFINED_RPC_INDEX) - return rpcSet[index]; - return 0; + return rpcSet[uniqueIdentifier]; } -RPCIndex RPCMap::GetIndexFromFunctionName(char *uniqueIdentifier) +RPCIndex RPCMap::GetIndexFromFunctionName(unsigned char uniqueIdentifier) { - unsigned index; - for (index=0; index < rpcSet.Size(); index++) - if (rpcSet[index] && strcmp(rpcSet[index]->uniqueIdentifier, uniqueIdentifier)==0) - return (RPCIndex) index; - return UNDEFINED_RPC_INDEX; + return (RPCIndex)uniqueIdentifier; } // Called from the user thread for the local system -void RPCMap::AddIdentifierWithFunction(char *uniqueIdentifier, void *functionPointer, bool isPointerToMember) +void RPCMap::AddIdentifierWithFunction(unsigned char uniqueIdentifier, void *functionPointer, bool isPointerToMember) { -#ifdef _DEBUG - assert(rpcSet.Size()+1 < MAX_RPC_MAP_SIZE); // If this hits change the typedef of RPCIndex to use an unsigned short - assert(uniqueIdentifier && uniqueIdentifier[0]); - assert(functionPointer); -#endif - - unsigned index, existingNodeIndex; RPCNode *node; - existingNodeIndex=GetIndexFromFunctionName(uniqueIdentifier); - if ((RPCIndex)existingNodeIndex!=UNDEFINED_RPC_INDEX) // Insert at any free spot. - { - // Trying to insert an identifier at any free slot and that identifier already exists - // The user should not insert nodes that already exist in the list -#ifdef _DEBUG -// assert(0); -#endif - return; - } - node = new RPCNode; - node->uniqueIdentifier = new char [strlen(uniqueIdentifier)+1]; - strcpy(node->uniqueIdentifier, uniqueIdentifier); + node->uniqueIdentifier=uniqueIdentifier; node->functionPointer=functionPointer; node->isPointerToMember=isPointerToMember; - // Insert into an empty spot if possible - for (index=0; index < rpcSet.Size(); index++) - { - if (rpcSet[index]==0) - { - rpcSet.Replace(node, 0, index); - return; - } - } - - rpcSet.Insert(node); // No empty spots available so just add to the end of the list - + rpcSet[uniqueIdentifier] = node; } diff --git a/raknet/RPCMap.h b/raknet/RPCMap.h index 9074aa0..6e25337 100644 --- a/raknet/RPCMap.h +++ b/raknet/RPCMap.h @@ -25,6 +25,8 @@ #include "NetworkTypes.h" #include "Export.h" +#define RPC_SET_SIZE 256 + /// \ingroup RAKNET_RPC /// \internal /// \brief A container class for a list of RPCNodes @@ -35,11 +37,12 @@ public: ~RPCMap(); void Clear(void); RPCNode *GetNodeFromIndex(RPCIndex index); - RPCNode *GetNodeFromFunctionName(char *uniqueIdentifier); - RPCIndex GetIndexFromFunctionName(char *uniqueIdentifier); - void AddIdentifierWithFunction(char *uniqueIdentifier, void *functionPointer, bool isPointerToMember); + RPCNode *GetNodeFromFunctionName(unsigned char uniqueIdentifier); + RPCIndex GetIndexFromFunctionName(unsigned char uniqueIdentifier); + void AddIdentifierWithFunction(unsigned char uniqueIdentifier, void *functionPointer, bool isPointerToMember); protected: DataStructures::List rpcSet; + RPCNode *rpcSet[RPC_SET_SIZE]; }; #endif diff --git a/raknet/RPCNode.h b/raknet/RPCNode.h index be9385f..b6f1fd6 100644 --- a/raknet/RPCNode.h +++ b/raknet/RPCNode.h @@ -37,8 +37,8 @@ class RakPeerInterface; struct RAK_DLL_EXPORT RPCNode { - /// String identifier of the RPC - char *uniqueIdentifier; + /// Identifier of the RPC + unsigned char uniqueIdentifier; /// Force casting of member functions to void * union diff --git a/raknet/RakPeer.cpp b/raknet/RakPeer.cpp index bfe98d9..8fb476d 100644 --- a/raknet/RakPeer.cpp +++ b/raknet/RakPeer.cpp @@ -1060,7 +1060,7 @@ void RakPeer::RegisterAsRemoteProcedureCall( char* uniqueID, void ( *functionPoi if ( uniqueID == 0 || uniqueID[ 0 ] == 0 || functionPointer == 0 ) return; - rpcMap.AddIdentifierWithFunction(uniqueID, (void*)functionPointer, false); + rpcMap.AddIdentifierWithFunction(uniqueID[0], (void*)functionPointer, false); /* char uppercaseUniqueID[ 256 ]; @@ -1092,7 +1092,7 @@ void RakPeer::RegisterClassMemberRPC( char* uniqueID, void *functionPointer ) if ( uniqueID == 0 || uniqueID[ 0 ] == 0 || functionPointer == 0 ) return; - rpcMap.AddIdentifierWithFunction(uniqueID, functionPointer, true); + rpcMap.AddIdentifierWithFunction(uniqueID[0], functionPointer, true); } // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -1171,33 +1171,10 @@ bool RakPeer::RPC( char* uniqueID, const char *data, unsigned int bitLength, Pac if ( uniqueID == 0 ) return false; - if ( strlen( uniqueID ) > 256 ) - { -#ifdef _DEBUG - assert( 0 ); -#endif - return false; // Unique ID is too long - } - if (replyFromTarget && blockOnRPCReply==true) - { - // TODO - this should be fixed eventually - // Prevent a bug where function A calls B (blocking) which calls C back on the sender, which calls D, and C is blocking. - // blockOnRPCReply is a shared variable so making it unset would unset both blocks, rather than the lowest on the callstack - // Fix by tracking which function the reply is for. - return false; - } - unsigned *sendList; -// bool callerAllocationDataUsed; unsigned sendListSize; - // All this code modifies bcs->data and bcs->numberOfBitsToSend in order to transform an RPC request into an actual packet for SendImmediate - RPCIndex rpcIndex; // Index into the list of RPC calls so we know what number to encode in the packet -// char *userData; // RPC ID (the name of it) and a pointer to the data sent by the user -// int extraBuffer; // How many data bytes were allocated to hold the RPC header - unsigned remoteSystemIndex, sendListIndex; // Iterates into the list of remote systems -// int dataBlockAllocationLength; // Total number of bytes to allocate for the packet -// char *writeTarget; // Used to hold either a block of allocated data or the externally allocated data + unsigned remoteSystemIndex, sendListIndex; sendListSize=0; bool routeSend; @@ -1260,37 +1237,10 @@ bool RakPeer::RPC( char* uniqueID, const char *data, unsigned int bitLength, Pac outgoingBitStream.Write(RakNet::GetTime()); } outgoingBitStream.Write((unsigned char) ID_RPC); - if (routeSend) - rpcIndex=UNDEFINED_RPC_INDEX; - else - rpcIndex=remoteSystemList[sendList[sendListIndex]].rpcMap.GetIndexFromFunctionName(uniqueID); // Lots of trouble but we can only use remoteSystem->[whatever] in this thread so that is why this command was buffered - if (rpcIndex!=UNDEFINED_RPC_INDEX) - { - // We have an RPC name to an index mapping, so write the index - outgoingBitStream.Write(false); - outgoingBitStream.WriteCompressed(rpcIndex); - } - else - { - // No mapping, so write the encoded RPC name - outgoingBitStream.Write(true); - stringCompressor->EncodeString(uniqueID, 256, &outgoingBitStream); - } - outgoingBitStream.Write((bool) ((replyFromTarget!=0)==true)); + + outgoingBitStream.Write(uniqueID, 1); + outgoingBitStream.WriteCompressed( bitLength ); - if (networkID==UNASSIGNED_NETWORK_ID) - { - // No object ID - outgoingBitStream.Write(false); - } - else - { - // Encode an object ID. This will use pointer to class member RPC - outgoingBitStream.Write(true); - outgoingBitStream.Write(networkID); - } - - if ( bitLength > 0 ) outgoingBitStream.WriteBits( (const unsigned char *) data, bitLength, false ); // Last param is false to write the raw data originally from another bitstream, rather than shifting from user data else @@ -1302,107 +1252,6 @@ bool RakPeer::RPC( char* uniqueID, const char *data, unsigned int bitLength, Pac Send(&outgoingBitStream, priority, reliability, orderingChannel, remoteSystemList[sendList[sendListIndex]].playerId, false); } -#if defined(_COMPATIBILITY_1) - delete [] sendList; -#endif - - if (replyFromTarget) - { - blockOnRPCReply=true; - // 04/20/06 Just do this transparently. - // We have to be able to read blocking packets out of order. Otherwise, if two systems were to send blocking RPC calls to each other at the same time, - // and they also had ordered packets waiting before the block, it would be impossible to unblock. - // assert(reliability==RELIABLE || reliability==UNRELIABLE); - replyFromTargetBS=replyFromTarget; - replyFromTargetPlayer=playerId; - replyFromTargetBroadcast=broadcast; - } - - // Do not enter this loop on blockOnRPCReply because it is a global which could be set to true by an RPC higher on the callstack, where one RPC was called while waiting for another RPC - if (replyFromTarget) -// if (blockOnRPCReply) - { -// Packet *p; - RakNetTime stopWaitingTime; -// RPCIndex arrivedRPCIndex; -// char uniqueIdentifier[256]; - if (reliability==UNRELIABLE) - if (playerId==UNASSIGNED_PLAYER_ID) - stopWaitingTime=RakNet::GetTime()+1500; // Lets guess the ave. ping is 500. Not important to be very accurate - else - stopWaitingTime=RakNet::GetTime()+GetAveragePing(playerId)*3; - - // For reliable messages, block until we get a reply or the connection is lost - // For unreliable messages, block until we get a reply, the connection is lost, or 3X the ping passes - while (blockOnRPCReply && - ((reliability==RELIABLE || reliability==RELIABLE_ORDERED || reliability==RELIABLE_SEQUENCED) || - RakNet::GetTime() < stopWaitingTime)) - { - - RakSleep(30); - - if (routeSend==false && ValidSendTarget(playerId, broadcast)==false) - return false; - - // I might not support processing other RPCs while blocking on one due to complexities I can't control - // Problem is FuncA calls FuncB which calls back to the sender FuncC. Sometimes it is desirable to call FuncC before returning a return value - // from FuncB - sometimes not. There is also a problem with recursion where FuncA calls FuncB which calls FuncA - sometimes valid if - // a different control path is taken in FuncA. (This can take many different forms) - /* - // Same as Receive, but doesn't automatically do RPCs - p = ReceiveIgnoreRPC(); - if (p) - { - // Process all RPC calls except for those calling the function we are currently blocking in (to prevent recursion). - if ( p->data[ 0 ] == ID_RPC ) - { - RakNet::BitStream temp((unsigned char *) p->data, p->length, false); - RPCNode *rpcNode; - temp.IgnoreBits(8); - bool nameIsEncoded; - temp.Read(nameIsEncoded); - if (nameIsEncoded) - { - stringCompressor->DecodeString((char*)uniqueIdentifier, 256, &temp); - } - else - { - temp.ReadCompressed( arrivedRPCIndex ); - rpcNode=rpcMap.GetNodeFromIndex( arrivedRPCIndex ); - if (rpcNode==0) - { - // Invalid RPC format -#ifdef _DEBUG - assert(0); -#endif - DeallocatePacket(p); - continue; - } - else - strcpy(uniqueIdentifier, rpcNode->uniqueIdentifier); - } - - if (strcmp(uniqueIdentifier, uniqueID)!=0) - { - HandleRPCPacket( ( char* ) p->data, p->length, p->playerId ); - DeallocatePacket(p); - } - else - { - PushBackPacket(p, false); - } - } - else - { - PushBackPacket(p, false); - } - } - */ - } - - blockOnRPCReply=false; - } - return true; }