mirror of
https://github.com/dashr9230/SA-MP.git
synced 2024-12-22 14:37:29 +08:00
[raknet] Match all RPCMap member functions
* Match `RakPeer::RegisterAsRemoteProcedureCall(...)` * Match `RakPeer::RegisterClassMemberRPC(...)` * Match `RakPeer::RPC(...)` * Update `NetworkTypes.h`
This commit is contained in:
parent
5c8db97f0d
commit
8ca8b43b86
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<RPCNode *> rpcSet;
|
||||
RPCNode *rpcSet[RPC_SET_SIZE];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user