RPC4Plugin.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*
  2. * Copyright (c) 2014, Oculus VR, Inc.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under the BSD-style license found in the
  6. * LICENSE file in the root directory of this source tree. An additional grant
  7. * of patent rights can be found in the PATENTS file in the same directory.
  8. *
  9. */
  10. #include "NativeFeatureIncludes.h"
  11. #if _RAKNET_SUPPORT_RPC4Plugin==1
  12. #include "RPC4Plugin.h"
  13. #include "MessageIdentifiers.h"
  14. #include "RakPeerInterface.h"
  15. #include "PacketizedTCP.h"
  16. #include "RakSleep.h"
  17. #include "RakNetDefines.h"
  18. #include "DS_Queue.h"
  19. //#include "GetTime.h"
  20. using namespace RakNet;
  21. STATIC_FACTORY_DEFINITIONS(RPC4,RPC4);
  22. struct GlobalRegistration
  23. {
  24. void ( *registerFunctionPointer ) ( RakNet::BitStream *userData, Packet *packet );
  25. void ( *registerBlockingFunctionPointer ) ( RakNet::BitStream *userData, RakNet::BitStream *returnData, Packet *packet );
  26. char functionName[RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH];
  27. MessageID messageId;
  28. int callPriority;
  29. };
  30. static GlobalRegistration globalRegistrationBuffer[RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS];
  31. static unsigned int globalRegistrationIndex=0;
  32. RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ))
  33. {
  34. RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
  35. unsigned int i;
  36. for (i=0; uniqueID[i]; i++)
  37. {
  38. RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
  39. globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
  40. }
  41. globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=functionPointer;
  42. globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=0;
  43. globalRegistrationBuffer[globalRegistrationIndex].callPriority=0xFFFFFFFF;
  44. globalRegistrationIndex++;
  45. }
  46. RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ), int callPriority)
  47. {
  48. RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
  49. unsigned int i;
  50. for (i=0; uniqueID[i]; i++)
  51. {
  52. RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
  53. globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
  54. }
  55. globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=functionPointer;
  56. globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=0;
  57. RakAssert(callPriority!=(int) 0xFFFFFFFF);
  58. globalRegistrationBuffer[globalRegistrationIndex].callPriority=callPriority;
  59. globalRegistrationIndex++;
  60. }
  61. RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, RakNet::BitStream *returnData, Packet *packet ))
  62. {
  63. RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
  64. unsigned int i;
  65. for (i=0; uniqueID[i]; i++)
  66. {
  67. RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
  68. globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
  69. }
  70. globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=0;
  71. globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=functionPointer;
  72. globalRegistrationIndex++;
  73. }
  74. RPC4GlobalRegistration::RPC4GlobalRegistration(const char* uniqueID, MessageID messageId)
  75. {
  76. RakAssert(globalRegistrationIndex!=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTIONS);
  77. unsigned int i;
  78. for (i=0; uniqueID[i]; i++)
  79. {
  80. RakAssert(i<=RPC4_GLOBAL_REGISTRATION_MAX_FUNCTION_NAME_LENGTH-1);
  81. globalRegistrationBuffer[globalRegistrationIndex].functionName[i]=uniqueID[i];
  82. }
  83. globalRegistrationBuffer[globalRegistrationIndex].registerFunctionPointer=0;
  84. globalRegistrationBuffer[globalRegistrationIndex].registerBlockingFunctionPointer=0;
  85. globalRegistrationBuffer[globalRegistrationIndex].messageId=messageId;
  86. globalRegistrationIndex++;
  87. }
  88. enum RPC4Identifiers
  89. {
  90. ID_RPC4_CALL,
  91. ID_RPC4_RETURN,
  92. ID_RPC4_SIGNAL,
  93. };
  94. int RPC4::LocalSlotObjectComp( const LocalSlotObject &key, const LocalSlotObject &data )
  95. {
  96. if (key.callPriority>data.callPriority)
  97. return -1;
  98. if (key.callPriority==data.callPriority)
  99. {
  100. if (key.registrationCount<data.registrationCount)
  101. return -1;
  102. if (key.registrationCount==data.registrationCount)
  103. return 0;
  104. return 1;
  105. }
  106. return 1;
  107. }
  108. int RPC4::LocalCallbackComp(const MessageID &key, RPC4::LocalCallback* const &data )
  109. {
  110. if (key < data->messageId)
  111. return -1;
  112. if (key > data->messageId)
  113. return 1;
  114. return 0;
  115. }
  116. RPC4::RPC4()
  117. {
  118. gotBlockingReturnValue=false;
  119. nextSlotRegistrationCount=0;
  120. interruptSignal=false;
  121. }
  122. RPC4::~RPC4()
  123. {
  124. unsigned int i;
  125. for (i=0; i < localCallbacks.Size(); i++)
  126. {
  127. RakNet::OP_DELETE(localCallbacks[i],_FILE_AND_LINE_);
  128. }
  129. DataStructures::List<RakNet::RakString> keyList;
  130. DataStructures::List<LocalSlot*> outputList;
  131. localSlots.GetAsList(outputList,keyList,_FILE_AND_LINE_);
  132. unsigned int j;
  133. for (j=0; j < outputList.Size(); j++)
  134. {
  135. RakNet::OP_DELETE(outputList[j],_FILE_AND_LINE_);
  136. }
  137. localSlots.Clear(_FILE_AND_LINE_);
  138. }
  139. bool RPC4::RegisterFunction(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ))
  140. {
  141. DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID);
  142. if (skhi.IsInvalid()==false)
  143. return false;
  144. registeredNonblockingFunctions.Push(uniqueID,functionPointer,_FILE_AND_LINE_);
  145. return true;
  146. }
  147. void RPC4::RegisterSlot(const char *sharedIdentifier, void ( *functionPointer ) ( RakNet::BitStream *userData, Packet *packet ), int callPriority)
  148. {
  149. LocalSlotObject lso(nextSlotRegistrationCount++, callPriority, functionPointer);
  150. DataStructures::HashIndex idx = GetLocalSlotIndex(sharedIdentifier);
  151. LocalSlot *localSlot;
  152. if (idx.IsInvalid())
  153. {
  154. localSlot = RakNet::OP_NEW<LocalSlot>(_FILE_AND_LINE_);
  155. localSlots.Push(sharedIdentifier, localSlot,_FILE_AND_LINE_);
  156. }
  157. else
  158. {
  159. localSlot=localSlots.ItemAtIndex(idx);
  160. }
  161. localSlot->slotObjects.Insert(lso,lso,true,_FILE_AND_LINE_);
  162. }
  163. bool RPC4::RegisterBlockingFunction(const char* uniqueID, void ( *functionPointer ) ( RakNet::BitStream *userData, RakNet::BitStream *returnData, Packet *packet ))
  164. {
  165. DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(uniqueID);
  166. if (skhi.IsInvalid()==false)
  167. return false;
  168. registeredBlockingFunctions.Push(uniqueID,functionPointer,_FILE_AND_LINE_);
  169. return true;
  170. }
  171. void RPC4::RegisterLocalCallback(const char* uniqueID, MessageID messageId)
  172. {
  173. bool objectExists;
  174. unsigned int index;
  175. LocalCallback *lc;
  176. RakNet::RakString str;
  177. str=uniqueID;
  178. index = localCallbacks.GetIndexFromKey(messageId,&objectExists);
  179. if (objectExists)
  180. {
  181. lc = localCallbacks[index];
  182. index = lc->functions.GetIndexFromKey(str,&objectExists);
  183. if (objectExists==false)
  184. lc->functions.InsertAtIndex(str,index,_FILE_AND_LINE_);
  185. }
  186. else
  187. {
  188. lc = RakNet::OP_NEW<LocalCallback>(_FILE_AND_LINE_);
  189. lc->messageId=messageId;
  190. lc->functions.Insert(str,str,false,_FILE_AND_LINE_);
  191. localCallbacks.InsertAtIndex(lc,index,_FILE_AND_LINE_);
  192. }
  193. }
  194. bool RPC4::UnregisterFunction(const char* uniqueID)
  195. {
  196. void ( *f ) ( RakNet::BitStream *, Packet * );
  197. return registeredNonblockingFunctions.Pop(f,uniqueID,_FILE_AND_LINE_);
  198. }
  199. bool RPC4::UnregisterBlockingFunction(const char* uniqueID)
  200. {
  201. void ( *f ) ( RakNet::BitStream *, RakNet::BitStream *,Packet * );
  202. return registeredBlockingFunctions.Pop(f,uniqueID,_FILE_AND_LINE_);
  203. }
  204. bool RPC4::UnregisterLocalCallback(const char* uniqueID, MessageID messageId)
  205. {
  206. bool objectExists;
  207. unsigned int index, index2;
  208. LocalCallback *lc;
  209. RakNet::RakString str;
  210. str=uniqueID;
  211. index = localCallbacks.GetIndexFromKey(messageId,&objectExists);
  212. if (objectExists)
  213. {
  214. lc = localCallbacks[index];
  215. index2 = lc->functions.GetIndexFromKey(str,&objectExists);
  216. if (objectExists)
  217. {
  218. lc->functions.RemoveAtIndex(index2);
  219. if (lc->functions.Size()==0)
  220. {
  221. RakNet::OP_DELETE(lc,_FILE_AND_LINE_);
  222. localCallbacks.RemoveAtIndex(index);
  223. return true;
  224. }
  225. }
  226. }
  227. return false;
  228. }
  229. bool RPC4::UnregisterSlot(const char* sharedIdentifier)
  230. {
  231. DataStructures::HashIndex hi = localSlots.GetIndexOf(sharedIdentifier);
  232. if (hi.IsInvalid()==false)
  233. {
  234. LocalSlot *ls = localSlots.ItemAtIndex(hi);
  235. RakNet::OP_DELETE(ls, _FILE_AND_LINE_);
  236. localSlots.RemoveAtIndex(hi, _FILE_AND_LINE_);
  237. return true;
  238. }
  239. return false;
  240. }
  241. void RPC4::CallLoopback( const char* uniqueID, RakNet::BitStream * bitStream )
  242. {
  243. Packet *p=0;
  244. DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(uniqueID);
  245. if (skhi.IsInvalid()==true)
  246. {
  247. if (rakPeerInterface)
  248. p=AllocatePacketUnified(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1);
  249. #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
  250. else
  251. p=tcpInterface->AllocatePacket(sizeof(MessageID)+sizeof(unsigned char)+(unsigned int) strlen(uniqueID)+1);
  252. #endif
  253. if (rakPeerInterface)
  254. p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
  255. #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
  256. else
  257. p->guid=UNASSIGNED_RAKNET_GUID;
  258. #endif
  259. p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
  260. p->systemAddress.systemIndex=(SystemIndex)-1;
  261. p->data[0]=ID_RPC_REMOTE_ERROR;
  262. p->data[1]=RPC_ERROR_FUNCTION_NOT_REGISTERED;
  263. strcpy((char*) p->data+2, uniqueID);
  264. PushBackPacketUnified(p,false);
  265. return;
  266. }
  267. RakNet::BitStream out;
  268. out.Write((MessageID) ID_RPC_PLUGIN);
  269. out.Write((MessageID) ID_RPC4_CALL);
  270. out.WriteCompressed(uniqueID);
  271. out.Write(false); // nonblocking
  272. if (bitStream)
  273. {
  274. bitStream->ResetReadPointer();
  275. out.AlignWriteToByteBoundary();
  276. out.Write(bitStream);
  277. }
  278. if (rakPeerInterface)
  279. p=AllocatePacketUnified(out.GetNumberOfBytesUsed());
  280. #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
  281. else
  282. p=tcpInterface->AllocatePacket(out.GetNumberOfBytesUsed());
  283. #endif
  284. if (rakPeerInterface)
  285. p->guid=rakPeerInterface->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS);
  286. #if _RAKNET_SUPPORT_PacketizedTCP==1 && _RAKNET_SUPPORT_TCPInterface==1
  287. else
  288. p->guid=UNASSIGNED_RAKNET_GUID;
  289. #endif
  290. p->systemAddress=UNASSIGNED_SYSTEM_ADDRESS;
  291. p->systemAddress.systemIndex=(SystemIndex)-1;
  292. memcpy(p->data,out.GetData(),out.GetNumberOfBytesUsed());
  293. PushBackPacketUnified(p,false);
  294. return;
  295. }
  296. void RPC4::Call( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast )
  297. {
  298. RakNet::BitStream out;
  299. out.Write((MessageID) ID_RPC_PLUGIN);
  300. out.Write((MessageID) ID_RPC4_CALL);
  301. out.WriteCompressed(uniqueID);
  302. out.Write(false); // Nonblocking
  303. if (bitStream)
  304. {
  305. bitStream->ResetReadPointer();
  306. out.AlignWriteToByteBoundary();
  307. out.Write(bitStream);
  308. }
  309. SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast);
  310. }
  311. bool RPC4::CallBlocking( const char* uniqueID, RakNet::BitStream * bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, RakNet::BitStream *returnData )
  312. {
  313. RakNet::BitStream out;
  314. out.Write((MessageID) ID_RPC_PLUGIN);
  315. out.Write((MessageID) ID_RPC4_CALL);
  316. out.WriteCompressed(uniqueID);
  317. out.Write(true); // Blocking
  318. if (bitStream)
  319. {
  320. bitStream->ResetReadPointer();
  321. out.AlignWriteToByteBoundary();
  322. out.Write(bitStream);
  323. }
  324. RakAssert(returnData);
  325. RakAssert(rakPeerInterface);
  326. ConnectionState cs;
  327. cs = rakPeerInterface->GetConnectionState(systemIdentifier);
  328. if (cs!=IS_CONNECTED)
  329. return false;
  330. SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,false);
  331. returnData->Reset();
  332. blockingReturnValue.Reset();
  333. gotBlockingReturnValue=false;
  334. Packet *packet;
  335. DataStructures::Queue<Packet*> packetQueue;
  336. while (gotBlockingReturnValue==false)
  337. {
  338. // TODO - block, filter until gotBlockingReturnValue==true or ID_CONNECTION_LOST or ID_DISCONNECTION_NOTIFICXATION or ID_RPC_REMOTE_ERROR/RPC_ERROR_FUNCTION_NOT_REGISTERED
  339. RakSleep(30);
  340. packet=rakPeerInterface->Receive();
  341. if (packet)
  342. {
  343. if (
  344. (packet->data[0]==ID_CONNECTION_LOST || packet->data[0]==ID_DISCONNECTION_NOTIFICATION) &&
  345. ((systemIdentifier.rakNetGuid!=UNASSIGNED_RAKNET_GUID && packet->guid==systemIdentifier.rakNetGuid) ||
  346. (systemIdentifier.systemAddress!=UNASSIGNED_SYSTEM_ADDRESS && packet->systemAddress==systemIdentifier.systemAddress))
  347. )
  348. {
  349. // Push back to head in reverse order
  350. rakPeerInterface->PushBackPacket(packet,true);
  351. while (packetQueue.Size())
  352. rakPeerInterface->PushBackPacket(packetQueue.Pop(),true);
  353. return false;
  354. }
  355. else if (packet->data[0]==ID_RPC_REMOTE_ERROR && packet->data[1]==RPC_ERROR_FUNCTION_NOT_REGISTERED)
  356. {
  357. RakNet::RakString functionName;
  358. RakNet::BitStream bsIn(packet->data,packet->length,false);
  359. bsIn.IgnoreBytes(2);
  360. bsIn.Read(functionName);
  361. if (functionName==uniqueID)
  362. {
  363. // Push back to head in reverse order
  364. rakPeerInterface->PushBackPacket(packet,true);
  365. while (packetQueue.Size())
  366. rakPeerInterface->PushBackPacket(packetQueue.Pop(),true);
  367. return false;
  368. }
  369. else
  370. {
  371. packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
  372. }
  373. }
  374. else
  375. {
  376. packetQueue.PushAtHead(packet,0,_FILE_AND_LINE_);
  377. }
  378. }
  379. }
  380. returnData->Write(blockingReturnValue);
  381. returnData->ResetReadPointer();
  382. return true;
  383. }
  384. void RPC4::Signal(const char *sharedIdentifier, RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingChannel, const AddressOrGUID systemIdentifier, bool broadcast, bool invokeLocal)
  385. {
  386. RakNet::BitStream out;
  387. out.Write((MessageID) ID_RPC_PLUGIN);
  388. out.Write((MessageID) ID_RPC4_SIGNAL);
  389. out.WriteCompressed(sharedIdentifier);
  390. if (bitStream)
  391. {
  392. bitStream->ResetReadPointer();
  393. out.AlignWriteToByteBoundary();
  394. out.Write(bitStream);
  395. }
  396. SendUnified(&out,priority,reliability,orderingChannel,systemIdentifier,broadcast);
  397. if (invokeLocal)
  398. {
  399. //TimeUS t1 = GetTimeUS();
  400. DataStructures::HashIndex functionIndex;
  401. functionIndex = localSlots.GetIndexOf(sharedIdentifier);
  402. //TimeUS t2 = GetTimeUS();
  403. if (functionIndex.IsInvalid())
  404. return;
  405. Packet p;
  406. p.guid=rakPeerInterface->GetMyGUID();
  407. p.systemAddress=rakPeerInterface->GetInternalID(UNASSIGNED_SYSTEM_ADDRESS);
  408. p.wasGeneratedLocally=true;
  409. RakNet::BitStream *bsptr, bstemp;
  410. if (bitStream)
  411. {
  412. bitStream->ResetReadPointer();
  413. p.length=bitStream->GetNumberOfBytesUsed();
  414. p.bitSize=bitStream->GetNumberOfBitsUsed();
  415. bsptr=bitStream;
  416. }
  417. else
  418. {
  419. p.length=0;
  420. p.bitSize=0;
  421. bsptr=&bstemp;
  422. }
  423. //TimeUS t3 = GetTimeUS();
  424. InvokeSignal(functionIndex, bsptr, &p);
  425. //TimeUS t4 = GetTimeUS();
  426. //printf("b1: %I64d\n", t2-t1);
  427. //printf("b2: %I64d\n", t3-t2);
  428. //printf("b3: %I64d\n", t4-t3);
  429. }
  430. }
  431. void RPC4::InvokeSignal(DataStructures::HashIndex functionIndex, RakNet::BitStream *serializedParameters, Packet *packet)
  432. {
  433. if (functionIndex.IsInvalid())
  434. return;
  435. //TimeUS t1 = GetTimeUS();
  436. //TimeUS t2=0;
  437. //TimeUS t3=0;
  438. interruptSignal=false;
  439. LocalSlot *localSlot = localSlots.ItemAtIndex(functionIndex);
  440. unsigned int i;
  441. i=0;
  442. while (i < localSlot->slotObjects.Size())
  443. {
  444. //t2 = GetTimeUS();
  445. localSlot->slotObjects[i].functionPointer(serializedParameters, packet);
  446. //t3 = GetTimeUS();
  447. // Not threadsafe
  448. if (interruptSignal==true)
  449. break;
  450. serializedParameters->ResetReadPointer();
  451. i++;
  452. }
  453. //TimeUS t4 = GetTimeUS();
  454. //printf("b1: %I64d\n", t2-t1);
  455. //printf("b2: %I64d\n", t3-t2);
  456. //printf("b3: %I64d\n", t4-t3);
  457. }
  458. void RPC4::InterruptSignal(void)
  459. {
  460. interruptSignal=true;
  461. }
  462. void RPC4::OnAttach(void)
  463. {
  464. unsigned int i;
  465. for (i=0; i < globalRegistrationIndex; i++)
  466. {
  467. if (globalRegistrationBuffer[i].registerFunctionPointer)
  468. {
  469. if (globalRegistrationBuffer[i].callPriority==(int)0xFFFFFFFF)
  470. RegisterFunction(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].registerFunctionPointer);
  471. else
  472. RegisterSlot(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].registerFunctionPointer, globalRegistrationBuffer[i].callPriority);
  473. }
  474. else if (globalRegistrationBuffer[i].registerBlockingFunctionPointer)
  475. RegisterBlockingFunction(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].registerBlockingFunctionPointer);
  476. else
  477. RegisterLocalCallback(globalRegistrationBuffer[i].functionName, globalRegistrationBuffer[i].messageId);
  478. }
  479. }
  480. PluginReceiveResult RPC4::OnReceive(Packet *packet)
  481. {
  482. if (packet->data[0]==ID_RPC_PLUGIN)
  483. {
  484. RakNet::BitStream bsIn(packet->data,packet->length,false);
  485. bsIn.IgnoreBytes(2);
  486. if (packet->data[1]==ID_RPC4_CALL)
  487. {
  488. RakNet::RakString functionName;
  489. bsIn.ReadCompressed(functionName);
  490. bool isBlocking=false;
  491. bsIn.Read(isBlocking);
  492. if (isBlocking==false)
  493. {
  494. DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(functionName.C_String());
  495. if (skhi.IsInvalid())
  496. {
  497. RakNet::BitStream bsOut;
  498. bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR);
  499. bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED);
  500. bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1);
  501. SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
  502. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  503. }
  504. void ( *fp ) ( RakNet::BitStream *, Packet * );
  505. fp = registeredNonblockingFunctions.ItemAtIndex(skhi);
  506. bsIn.AlignReadToByteBoundary();
  507. fp(&bsIn,packet);
  508. }
  509. else
  510. {
  511. DataStructures::HashIndex skhi = registeredBlockingFunctions.GetIndexOf(functionName.C_String());
  512. if (skhi.IsInvalid())
  513. {
  514. RakNet::BitStream bsOut;
  515. bsOut.Write((unsigned char) ID_RPC_REMOTE_ERROR);
  516. bsOut.Write((unsigned char) RPC_ERROR_FUNCTION_NOT_REGISTERED);
  517. bsOut.Write(functionName.C_String(),(unsigned int) functionName.GetLength()+1);
  518. SendUnified(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
  519. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  520. }
  521. void ( *fp ) ( RakNet::BitStream *, RakNet::BitStream *, Packet * );
  522. fp = registeredBlockingFunctions.ItemAtIndex(skhi);
  523. RakNet::BitStream returnData;
  524. bsIn.AlignReadToByteBoundary();
  525. fp(&bsIn, &returnData, packet);
  526. RakNet::BitStream out;
  527. out.Write((MessageID) ID_RPC_PLUGIN);
  528. out.Write((MessageID) ID_RPC4_RETURN);
  529. returnData.ResetReadPointer();
  530. out.AlignWriteToByteBoundary();
  531. out.Write(returnData);
  532. SendUnified(&out,IMMEDIATE_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
  533. }
  534. }
  535. else if (packet->data[1]==ID_RPC4_SIGNAL)
  536. {
  537. RakNet::RakString sharedIdentifier;
  538. bsIn.ReadCompressed(sharedIdentifier);
  539. DataStructures::HashIndex functionIndex;
  540. functionIndex = localSlots.GetIndexOf(sharedIdentifier);
  541. RakNet::BitStream serializedParameters;
  542. bsIn.AlignReadToByteBoundary();
  543. bsIn.Read(&serializedParameters);
  544. InvokeSignal(functionIndex, &serializedParameters, packet);
  545. }
  546. else
  547. {
  548. RakAssert(packet->data[1]==ID_RPC4_RETURN);
  549. blockingReturnValue.Reset();
  550. blockingReturnValue.Write(bsIn);
  551. gotBlockingReturnValue=true;
  552. }
  553. return RR_STOP_PROCESSING_AND_DEALLOCATE;
  554. }
  555. bool objectExists;
  556. unsigned int index, index2;
  557. index = localCallbacks.GetIndexFromKey(packet->data[0],&objectExists);
  558. if (objectExists)
  559. {
  560. LocalCallback *lc;
  561. lc = localCallbacks[index];
  562. for (index2=0; index2 < lc->functions.Size(); index2++)
  563. {
  564. RakNet::BitStream bsIn(packet->data, packet->length, false);
  565. DataStructures::HashIndex skhi = registeredNonblockingFunctions.GetIndexOf(lc->functions[index2].C_String());
  566. if (skhi.IsInvalid()==false)
  567. {
  568. void ( *fp ) ( RakNet::BitStream *, Packet * );
  569. fp = registeredNonblockingFunctions.ItemAtIndex(skhi);
  570. bsIn.AlignReadToByteBoundary();
  571. fp(&bsIn,packet);
  572. }
  573. }
  574. }
  575. return RR_CONTINUE_PROCESSING;
  576. }
  577. DataStructures::HashIndex RPC4::GetLocalSlotIndex(const char *sharedIdentifier)
  578. {
  579. return localSlots.GetIndexOf(sharedIdentifier);
  580. }
  581. #endif // _RAKNET_SUPPORT_*
粤ICP备19079148号