| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "NativeFeatureIncludes.h"
- #if _RAKNET_SUPPORT_RPC4Plugin==1
- #include "RPC4Plugin.h"
- #include "MessageIdentifiers.h"
- #include "RakPeerInterface.h"
- #include "PacketizedTCP.h"
- #include "RakSleep.h"
- #include "RakNetDefines.h"
- #include "DS_Queue.h"
- //#include "GetTime.h"
- using namespace RakNet;
- STATIC_FACTORY_DEFINITIONS(RPC4,RPC4);
- struct GlobalRegistration
- {
- void ( *registerFunctionPointer ) ( RakNet::BitStream *userData, Packet *packet );
- void ( *registerBlockingFunctionPointer ) ( RakNet::BitStream *userData, RakNet::BitStream *returnData, Packet *packet );
- char functionName[RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH];
- MessageID messageId;
- int callPriority;
- };
- static GlobalRegistration globalRegistrationBuffer[RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS];
- static unsigned int globalRegistrationIndex=0;
- RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ))
- {
- RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
- unsigned int i;
- for (i=0; uniqueID[i]; i++)
- {
- RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
- globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
- }
- globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=functionPointer;
- globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=0;
- globalRegistrationBuffer[globalRegistrationIndex].callPriority=0xFFFFFFFF;
- globalRegistrationIndex++;
- }
- RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ), int callPriority)
- {
- RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
- unsigned int i;
- for (i=0; uniqueID[i]; i++)
- {
- RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
- globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
- }
- globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=functionPointer;
- globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=0;
- RakAssert(callPriority!=(int) 0xFFFFFFFF);
- globalRegistrationBuffer[globalRegistrationIndex].callPriority=callPriority;
- globalRegistrationIndex++;
- }
- RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, RakNet::BitStream *returnData, Packet *packet ))
- {
- RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
- unsigned int i;
- for (i=0; uniqueID[i]; i++)
- {
- RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
- globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
- }
- globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=0;
- globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=functionPointer;
- globalRegistrationIndex++;
- }
- RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, MessageID messageId)
- {
- RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
- unsigned int i;
- for (i=0; uniqueID[i]; i++)
- {
- RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
- globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
- }
- globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=0;
- globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=0;
- globalRegistrationBuffer[globalRegistrationIndex].messageId=messageId;
- globalRegistrationIndex++;
- }
- enum RPC4Identifiers
- {
- ID_RPC4_CALL,
- ID_RPC4_RETURN,
- ID_RPC4_SIGNAL,
- };
- int RPC4::LocalSlotObjectComp( const LocalSlotObject &key, const LocalSlotObject &data )
- {
- if (key.callPriority>data.callPriority)
- return -1;
- if (key.callPriority==data.callPriority)
- {
- if (key.registrationCount<data.registrationCount)
- return -1;
- if (key.registrationCount==data.registrationCount)
- return 0;
- return 1;
- }
- return 1;
- }
- int RPC4::LocalCallbackComp(const MessageID &key, RPC4::LocalCallback* const &data )
- {
- if (key < data->messageId)
- return -1;
- if (key > data->messageId)
- return 1;
- return 0;
- }
- RPC4::RPC4()
- {
- gotBlockingReturnValue=false;
- nextSlotRegistrationCount=0;
- interruptSignal=false;
- }
- RPC4::~RPC4()
- {
- unsigned int i;
- for (i=0; i < localCallbacks.Size(); i++)
- {
- RakNet::OP_DELETE(localCallbacks[i],_FILE_AND_LINE_);
- }
- DataStructures::List<RakNet::RakString> keyList;
- DataStructures::List<LocalSlot*> outputList;
- localSlots.GetAsList(outputList,keyList,_FILE_AND_LINE_);
- unsigned int j;
- for (j=0; j < outputList.Size(); j++)
- {
- RakNet::OP_DELETE(outputList[j],_FILE_AND_LINE_);
- }
- localSlots.Clear(_FILE_AND_LINE_);
- }
- bool RPC4::RegisterFunction(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ))
- {
- DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID);
- if (skhi.IsInvalid()==false)
- return false;
- registeredNonblockingFunctions.Push(uniqueID,functionPointer,_FILE_AND_LINE_);
- return true;
- }
- void RPC4::RegisterSlot(const char *sharedIdentifier, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ), int callPriority)
- {
- LocalSlotObject lso(nextSlotRegistrationCount++, callPriority, functionPointer);
- DataStructures::HashIndex idx = GetLocalSlotIndex(sharedIdentifier);
- LocalSlot *localSlot;
- if (idx.IsInvalid())
- {
- localSlot = RakNet::OP_NEW<LocalSlot>(_FILE_AND_LINE_);
- localSlots.Push(sharedIdentifier, localSlot,_FILE_AND_LINE_);
- }
- else
- {
- localSlot=localSlots.ItemAtIndex(idx);
- }
- localSlot->slotObjects.Insert(lso,lso,true,_FILE_AND_LINE_);
- }
- bool RPC4::RegisterBlockingFunction(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, RakNet::BitStream *returnData, Packet *packet ))
- {
- DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(uniqueID);
- if (skhi.IsInvalid()==false)
- return false;
- registeredBlockingFunctions.Push(uniqueID,functionPointer,_FILE_AND_LINE_);
- return true;
- }
- void RPC4::RegisterLocalCallback(const char* uniqueID, MessageID messageId)
- {
- bool objectExists;
- unsigned int index;
- LocalCallback *lc;
- RakNet::RakString str;
- str=uniqueID;
- index = localCallbacks.GetIndexFromKey(messageId,&objectExists);
- if (objectExists)
- {
- lc = localCallbacks[index];
- index = lc->functions.GetIndexFromKey(str,&objectExists);
- if (objectExists==false)
- lc->functions.InsertAtIndex(str,index,_FILE_AND_LINE_);
- }
- else
- {
- lc = RakNet::OP_NEW<LocalCallback>(_FILE_AND_LINE_);
- lc->messageId=messageId;
- lc->functions.Insert(str,str,false,_FILE_AND_LINE_);
- localCallbacks.InsertAtIndex(lc,index,_FILE_AND_LINE_);
- }
- }
- bool RPC4::UnregisterFunction(const char* uniqueID)
- {
- void ( *f ) ( RakNet::BitStream *, Packet * );
- return registeredNonblockingFunctions.Pop(f,uniqueID,_FILE_AND_LINE_);
- }
- bool RPC4::UnregisterBlockingFunction(const char* uniqueID)
- {
- void ( *f ) ( RakNet::BitStream *, RakNet::BitStream *,Packet * );
- return registeredBlockingFunctions.Pop(f,uniqueID,_FILE_AND_LINE_);
- }
- bool RPC4::UnregisterLocalCallback(const char* uniqueID, MessageID messageId)
- {
- bool objectExists;
- unsigned int index, index2;
- LocalCallback *lc;
- RakNet::RakString str;
- str=uniqueID;
- index = localCallbacks.GetIndexFromKey(messageId,&objectExists);
- if (objectExists)
- {
- lc = localCallbacks[index];
- index2 = lc->functions.GetIndexFromKey(str,&objectExists);
- if (objectExists)
- {
- lc->functions.RemoveAtIndex(index2);
- if (lc->functions.Size()==0)
- {
- RakNet::OP_DELETE(lc,_FILE_AND_LINE_);
- localCallbacks.RemoveAtIndex(index);
- return true;
- }
- }
- }
- return false;
- }
- bool RPC4::UnregisterSlot(const char* sharedIdentifier)
- {
- DataStructures::HashIndex hi = localSlots.GetIndexOf(sharedIdentifier);
- if (hi.IsInvalid()==false)
- {
- LocalSlot *ls = localSlots.ItemAtIndex(hi);
- RakNet::OP_DELETE(ls, _FILE_AND_LINE_);
- localSlots.RemoveAtIndex(hi, _FILE_AND_LINE_);
- return true;
- }
-
- return false;
- }
- void RPC4::CallLoopback( const char* uniqueID, RakNet::BitStream * bitStream )
- {
- Packet *p=0;
- DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID);
- if (skhi.IsInvalid()==true)
- {
- if (rakPeerInterface)
- p=AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1);
- #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
- else
- p=tcpInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1);
- #endif
- if (rakPeerInterface)
- p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
- #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
- else
- p->guid=UNASSIGNED_RAKNET_GUID;
- #endif
- p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
- p->systemAddress.systemIndex=(SystemIndex)-1;
- p->data[0]=ID_RPC_REMOTE_ERROR;
- p->data[1]=RPC_ERROR_FUNCTION_NOT_REGISTERED;
- strcpy((char*) p->data+2, uniqueID);
-
- PushBackPacketUnified(p,false);
- return;
- }
- RakNet::BitStream out;
- out.Write((MessageID) ID_RPC_PLUGIN);
- out.Write((MessageID) ID_RPC4_CALL);
- out.WriteCompressed(uniqueID);
- out.Write(false); // nonblocking
- if (bitStream)
- {
- bitStream->ResetReadPointer();
- out.AlignWriteToByteBoundary();
- out.Write(bitStream);
- }
- if (rakPeerInterface)
- p=AllocatePacketUnified(out.GetNumberOfBytesUsed());
- #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
- else
- p=tcpInterface->AllocatePacket(out.GetNumberOfBytesUsed());
- #endif
- if (rakPeerInterface)
- p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
- #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
- else
- p->guid=UNASSIGNED_RAKNET_GUID;
- #endif
- p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
- p->systemAddress.systemIndex=(SystemIndex)-1;
- memcpy(p->data,out.GetData(),out.GetNumberOfBytesUsed());
- PushBackPacketUnified(p,false);
- return;
- }
- void RPC4::Call( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast )
- {
- RakNet::BitStream out;
- out.Write((MessageID) ID_RPC_PLUGIN);
- out.Write((MessageID) ID_RPC4_CALL);
- out.WriteCompressed(uniqueID);
- out.Write(false); // Nonblocking
- if (bitStream)
- {
- bitStream->ResetReadPointer();
- out.AlignWriteToByteBoundary();
- out.Write(bitStream);
- }
- SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast);
- }
- bool RPC4::CallBlocking( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, RakNet::BitStream *returnData )
- {
- RakNet::BitStream out;
- out.Write((MessageID) ID_RPC_PLUGIN);
- out.Write((MessageID) ID_RPC4_CALL);
- out.WriteCompressed(uniqueID);
- out.Write(true); // Blocking
- if (bitStream)
- {
- bitStream->ResetReadPointer();
- out.AlignWriteToByteBoundary();
- out.Write(bitStream);
- }
- RakAssert(returnData);
- RakAssert(rakPeerInterface);
- ConnectionState cs;
- cs = rakPeerInterface->GetConnectionState(systemIdentifier);
- if (cs!=IS_CONNECTED)
- return false;
- SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,false);
- returnData->Reset();
- blockingReturnValue.Reset();
- gotBlockingReturnValue=false;
- Packet *packet;
- DataStructures::Queue<Packet*> packetQueue;
- while (gotBlockingReturnValue==false)
- {
- // TODO - block, filter until gotBlockingReturnValue==true or ID_CONNECTION_LOST or ID_DISCONNECTION_NOTIFICXATION or ID_RPC_REMOTE_ERROR/RPC_ERROR_FUNCTION_NOT_REGISTERED
- RakSleep(30);
- packet=rakPeerInterface->Receive();
- if (packet)
- {
- if (
- (packet->data[0]==ID_CONNECTION_LOST || packet->data[0]==ID_DISCONNECTION_NOTIFICATION) &&
- ((systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID && packet->guid==systemIdentifier.rakNetGuid) ||
- (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS && packet->systemAddress==systemIdentifier.systemAddress))
- )
- {
- // Push back to head in reverse order
- rakPeerInterface->PushBackPacket(packet,true);
- while (packetQueue.Size())
- rakPeerInterface->PushBackPacket(packetQueue.Pop(),true);
- return false;
- }
- else if (packet->data[0]==ID_RPC_REMOTE_ERROR && packet->data[1]==RPC_ERROR_FUNCTION_NOT_REGISTERED)
- {
- RakNet::RakString functionName;
- RakNet::BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2);
- bsIn.Read(functionName);
- if (functionName==uniqueID)
- {
- // Push back to head in reverse order
- rakPeerInterface->PushBackPacket(packet,true);
- while (packetQueue.Size())
- rakPeerInterface->PushBackPacket(packetQueue.Pop(),true);
- return false;
- }
- else
- {
- packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
- }
- }
- else
- {
- packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
- }
- }
- }
- returnData->Write(blockingReturnValue);
- returnData->ResetReadPointer();
- return true;
- }
- void RPC4::Signal(const char *sharedIdentifier, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, bool invokeLocal)
- {
- RakNet::BitStream out;
- out.Write((MessageID) ID_RPC_PLUGIN);
- out.Write((MessageID) ID_RPC4_SIGNAL);
- out.WriteCompressed(sharedIdentifier);
- if (bitStream)
- {
- bitStream->ResetReadPointer();
- out.AlignWriteToByteBoundary();
- out.Write(bitStream);
- }
- SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast);
- if (invokeLocal)
- {
- //TimeUS t1 = GetTimeUS();
- DataStructures::HashIndex functionIndex;
- functionIndex = localSlots.GetIndexOf(sharedIdentifier);
- //TimeUS t2 = GetTimeUS();
- if (functionIndex.IsInvalid())
- return;
-
- Packet p;
- p.guid=rakPeerInterface->GetMyGUID();
- p.systemAddress=rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS);
- p.wasGeneratedLocally=true;
- RakNet::BitStream *bsptr, bstemp;
- if (bitStream)
- {
- bitStream->ResetReadPointer();
- p.length=bitStream->GetNumberOfBytesUsed();
- p.bitSize=bitStream->GetNumberOfBitsUsed();
- bsptr=bitStream;
- }
- else
- {
- p.length=0;
- p.bitSize=0;
- bsptr=&bstemp;
- }
- //TimeUS t3 = GetTimeUS();
- InvokeSignal(functionIndex, bsptr, &p);
- //TimeUS t4 = GetTimeUS();
- //printf("b1: %I64d\n", t2-t1);
- //printf("b2: %I64d\n", t3-t2);
- //printf("b3: %I64d\n", t4-t3);
- }
- }
- void RPC4::InvokeSignal(DataStructures::HashIndex functionIndex, RakNet::BitStream *serializedParameters, Packet *packet)
- {
- if (functionIndex.IsInvalid())
- return;
- //TimeUS t1 = GetTimeUS();
- //TimeUS t2=0;
- //TimeUS t3=0;
- interruptSignal=false;
- LocalSlot *localSlot = localSlots.ItemAtIndex(functionIndex);
- unsigned int i;
- i=0;
- while (i < localSlot->slotObjects.Size())
- {
- //t2 = GetTimeUS();
- localSlot->slotObjects[i].functionPointer(serializedParameters, packet);
- //t3 = GetTimeUS();
- // Not threadsafe
- if (interruptSignal==true)
- break;
- serializedParameters->ResetReadPointer();
- i++;
- }
- //TimeUS t4 = GetTimeUS();
- //printf("b1: %I64d\n", t2-t1);
- //printf("b2: %I64d\n", t3-t2);
- //printf("b3: %I64d\n", t4-t3);
- }
- void RPC4::InterruptSignal(void)
- {
- interruptSignal=true;
- }
- void RPC4::OnAttach(void)
- {
- unsigned int i;
- for (i=0; i < globalRegistrationIndex; i++)
- {
- if (globalRegistrationBuffer[i].registerFunctionPointer)
- {
- if (globalRegistrationBuffer[i].callPriority==(int)0xFFFFFFFF)
- RegisterFunction(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].registerFunctionPointer);
- else
- RegisterSlot(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].registerFunctionPointer, globalRegistrationBuffer[i].callPriority);
- }
- else if (globalRegistrationBuffer[i].registerBlockingFunctionPointer)
- RegisterBlockingFunction(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].registerBlockingFunctionPointer);
- else
- RegisterLocalCallback(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].messageId);
- }
- }
- PluginReceiveResult RPC4::OnReceive(Packet *packet)
- {
- if (packet->data[0]==ID_RPC_PLUGIN)
- {
- RakNet::BitStream bsIn(packet->data,packet->length,false);
- bsIn.IgnoreBytes(2);
- if (packet->data[1]==ID_RPC4_CALL)
- {
- RakNet::RakString functionName;
- bsIn.ReadCompressed(functionName);
- bool isBlocking=false;
- bsIn.Read(isBlocking);
- if (isBlocking==false)
- {
- DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(functionName.C_String());
- if (skhi.IsInvalid())
- {
- RakNet::BitStream bsOut;
- bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR);
- bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED);
- bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1);
- SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- void ( *fp ) ( RakNet::BitStream *, Packet * );
- fp = registeredNonblockingFunctions.ItemAtIndex(skhi);
- bsIn.AlignReadToByteBoundary();
- fp(&bsIn,packet);
- }
- else
- {
- DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(functionName.C_String());
- if (skhi.IsInvalid())
- {
- RakNet::BitStream bsOut;
- bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR);
- bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED);
- bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1);
- SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- void ( *fp ) ( RakNet::BitStream *, RakNet::BitStream *, Packet * );
- fp = registeredBlockingFunctions.ItemAtIndex(skhi);
- RakNet::BitStream returnData;
- bsIn.AlignReadToByteBoundary();
- fp(&bsIn, &returnData, packet);
- RakNet::BitStream out;
- out.Write((MessageID) ID_RPC_PLUGIN);
- out.Write((MessageID) ID_RPC4_RETURN);
- returnData.ResetReadPointer();
- out.AlignWriteToByteBoundary();
- out.Write(returnData);
- SendUnified(&out,IMMEDIATE_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
- }
- }
- else if (packet->data[1]==ID_RPC4_SIGNAL)
- {
- RakNet::RakString sharedIdentifier;
- bsIn.ReadCompressed(sharedIdentifier);
- DataStructures::HashIndex functionIndex;
- functionIndex = localSlots.GetIndexOf(sharedIdentifier);
- RakNet::BitStream serializedParameters;
- bsIn.AlignReadToByteBoundary();
- bsIn.Read(&serializedParameters);
- InvokeSignal(functionIndex, &serializedParameters, packet);
- }
- else
- {
- RakAssert(packet->data[1]==ID_RPC4_RETURN);
- blockingReturnValue.Reset();
- blockingReturnValue.Write(bsIn);
- gotBlockingReturnValue=true;
- }
-
- return RR_STOP_PROCESSING_AND_DEALLOCATE;
- }
- bool objectExists;
- unsigned int index, index2;
- index = localCallbacks.GetIndexFromKey(packet->data[0],&objectExists);
- if (objectExists)
- {
- LocalCallback *lc;
- lc = localCallbacks[index];
- for (index2=0; index2 < lc->functions.Size(); index2++)
- {
- RakNet::BitStream bsIn(packet->data, packet->length, false);
- DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(lc->functions[index2].C_String());
- if (skhi.IsInvalid()==false)
- {
- void ( *fp ) ( RakNet::BitStream *, Packet * );
- fp = registeredNonblockingFunctions.ItemAtIndex(skhi);
- bsIn.AlignReadToByteBoundary();
- fp(&bsIn,packet);
- }
- }
- }
- return RR_CONTINUE_PROCESSING;
- }
- DataStructures::HashIndex RPC4::GetLocalSlotIndex(const char *sharedIdentifier)
- {
- return localSlots.GetIndexOf(sharedIdentifier);
- }
- #endif // _RAKNET_SUPPORT_*
|