mastercommon.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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 "MasterCommon.h"
  11. #include "RakNetworkFactory.h"
  12. #include "RakPeerInterface.h"
  13. #include <cstring>
  14. #include "GetTime.h"
  15. #include "StringCompressor.h"
  16. #include "BitStream.h"
  17. using namespace RakNet;
  18. // For debugging
  19. #include <cstdio>
  20. GameServerRule::GameServerRule()
  21. {
  22. key=0;
  23. stringValue=0;
  24. intValue=-1;
  25. }
  26. GameServerRule::~GameServerRule()
  27. {
  28. if (key)
  29. delete [] key;
  30. if (stringValue)
  31. delete [] stringValue;
  32. }
  33. GameServer::GameServer()
  34. {
  35. connectionIdentifier=UNASSIGNED_PLAYER_ID;
  36. nextPingTime=0;
  37. failedPingResponses=0;
  38. lastUpdateTime=RakNet::GetTime();
  39. }
  40. GameServer::~GameServer()
  41. {
  42. Clear();
  43. }
  44. void GameServer::Clear()
  45. {
  46. unsigned i;
  47. for (i=0; i < serverRules.Size(); i++)
  48. delete serverRules[i];
  49. serverRules.Clear();
  50. }
  51. bool GameServer::FindKey(char *key)
  52. {
  53. unsigned i;
  54. for (i=0; i < serverRules.Size(); i++)
  55. if (strcmp(serverRules[i]->key, key)==0)
  56. {
  57. keyIndex=i;
  58. return true;
  59. }
  60. keyIndex=-1;
  61. return false;
  62. }
  63. GameServerList::GameServerList()
  64. {
  65. }
  66. GameServerList::~GameServerList()
  67. {
  68. Clear();
  69. }
  70. void GameServerList::Clear(void)
  71. {
  72. unsigned i;
  73. for (i=0; i < serverList.Size(); i++)
  74. delete serverList[i];
  75. serverList.Clear();
  76. }
  77. void GameServerList::SortOnKey(char *key, bool ascending)
  78. {
  79. unsigned i;
  80. // Set keyindex
  81. for (i=0; i < serverList.Size(); i++)
  82. serverList[i]->FindKey(key);
  83. QuickSort(0, serverList.Size()-1,ascending);
  84. }
  85. void GameServerList::QuickSort(int low, int high, bool ascending)
  86. {
  87. int pivot;
  88. if ( high > low )
  89. {
  90. pivot = Partition( low, high, ascending);
  91. QuickSort( low, pivot-1,ascending);
  92. QuickSort( pivot+1, high,ascending);
  93. }
  94. }
  95. int EQ(GameServer *left, GameServer *right)
  96. {
  97. if (left->keyIndex==-1 || right->keyIndex==-1)
  98. return true;
  99. if (left->serverRules[left->keyIndex]->stringValue)
  100. return strcmp(left->serverRules[left->keyIndex]->stringValue,right->serverRules[right->keyIndex]->stringValue)==0;
  101. else
  102. return left->serverRules[left->keyIndex]->intValue == right->serverRules[right->keyIndex]->intValue;
  103. }
  104. int LT(GameServer *left, GameServer *right)
  105. {
  106. if (left->keyIndex==-1)
  107. return true;
  108. if (right->keyIndex==-1)
  109. return false;
  110. if (left->serverRules[left->keyIndex]->stringValue)
  111. return strcmp(left->serverRules[left->keyIndex]->stringValue,right->serverRules[right->keyIndex]->stringValue) < 0;
  112. else
  113. return left->serverRules[left->keyIndex]->intValue < right->serverRules[right->keyIndex]->intValue;
  114. }
  115. int LTEQ(GameServer *left, GameServer *right)
  116. {
  117. return LT(left, right) || EQ(left, right);
  118. }
  119. int GT(GameServer *left, GameServer *right)
  120. {
  121. if (left->keyIndex==-1)
  122. return false;
  123. if (right->keyIndex==-1)
  124. return true;
  125. if (left->serverRules[left->keyIndex]->stringValue)
  126. return strcmp(left->serverRules[left->keyIndex]->stringValue,right->serverRules[right->keyIndex]->stringValue) > 0;
  127. else
  128. return left->serverRules[left->keyIndex]->intValue > right->serverRules[right->keyIndex]->intValue;
  129. }
  130. int GTEQ(GameServer *left, GameServer *right)
  131. {
  132. return GT(left, right) || EQ(left, right);
  133. }
  134. int GameServerList::Partition(int low, int high, bool ascending)
  135. {
  136. int left, right, pivot;
  137. GameServer *pivot_item, *temp;
  138. pivot_item = serverList[low];
  139. pivot = left = low;
  140. right = high;
  141. while ( left < right )
  142. {
  143. if (ascending)
  144. {
  145. /* Move left while item < pivot */
  146. while( LTEQ(serverList[left], pivot_item) && left < high) left++;
  147. /* Move right while item > pivot */
  148. while( GT(serverList[right], pivot_item) && right > 0) right--;
  149. if ( left < right )
  150. {
  151. temp=serverList[left];
  152. serverList[left]=serverList[right];
  153. serverList[right]=temp;
  154. }
  155. }
  156. else
  157. {
  158. while( GTEQ(serverList[left], pivot_item) && left < high) left++;
  159. while( LT(serverList[right], pivot_item) && right > 0) right--;
  160. if ( left < right )
  161. {
  162. temp=serverList[left];
  163. serverList[left]=serverList[right];
  164. serverList[right]=temp;
  165. }
  166. }
  167. }
  168. /* right is final position for the pivot */
  169. serverList[low] = serverList[right];
  170. serverList[right] = pivot_item;
  171. return right;
  172. }
  173. int GameServerList::GetIndexByPlayerID(PlayerID playerID)
  174. {
  175. int i;
  176. for (i=0; i < (int)serverList.Size(); i++)
  177. {
  178. if (serverList[i]->connectionIdentifier==playerID)
  179. return i;
  180. }
  181. return -1;
  182. }
  183. MasterCommon::MasterCommon()
  184. {
  185. // rakPeer = RakNetworkFactory::GetRakPeerInterface();
  186. }
  187. void MasterCommon::ClearServerList(void)
  188. {
  189. gameServerList.Clear();
  190. }
  191. void MasterCommon::SortServerListOnKey(char *ruleIdentifier, bool ascending)
  192. {
  193. gameServerList.SortOnKey(ruleIdentifier, ascending);
  194. }
  195. unsigned int MasterCommon::GetServerListSize(void)
  196. {
  197. return gameServerList.serverList.Size();
  198. }
  199. int MasterCommon::GetServerListRuleAsInt(int serverIndex, char *ruleIdentifier, bool *identifierFound)
  200. {
  201. int keyIndex;
  202. if (serverIndex >= (int)gameServerList.serverList.Size())
  203. {
  204. *identifierFound=false;
  205. return -1;
  206. }
  207. gameServerList.serverList[serverIndex]->FindKey(ruleIdentifier);
  208. keyIndex=gameServerList.serverList[serverIndex]->keyIndex;
  209. if (keyIndex==-1)
  210. {
  211. *identifierFound=false;
  212. return -1;
  213. }
  214. if (gameServerList.serverList[serverIndex]->serverRules[keyIndex]->stringValue)
  215. {
  216. *identifierFound=false;
  217. return -1;
  218. }
  219. *identifierFound=true;
  220. return gameServerList.serverList[serverIndex]->serverRules[keyIndex]->intValue;
  221. }
  222. const char* MasterCommon::GetServerListRuleAsString(int serverIndex, char *ruleIdentifier, bool *identifierFound)
  223. {
  224. int keyIndex;
  225. if (serverIndex >= (int)gameServerList.serverList.Size())
  226. {
  227. *identifierFound=false;
  228. return "serverIndex out of bounds";
  229. }
  230. gameServerList.serverList[serverIndex]->FindKey(ruleIdentifier);
  231. keyIndex=gameServerList.serverList[serverIndex]->keyIndex;
  232. if (keyIndex==-1)
  233. {
  234. *identifierFound=false;
  235. return "Server does not contain specified rule";
  236. }
  237. if (gameServerList.serverList[serverIndex]->serverRules[keyIndex]->stringValue==0)
  238. {
  239. *identifierFound=false;
  240. return "Server rule is not a string. Use GetServerListRuleAsInt";
  241. }
  242. *identifierFound=true;
  243. return gameServerList.serverList[serverIndex]->serverRules[keyIndex]->stringValue;
  244. }
  245. bool MasterCommon::IsReservedRuleIdentifier(char *ruleIdentifier)
  246. {
  247. if (strcmp(ruleIdentifier, "Ping")==0 ||
  248. strcmp(ruleIdentifier, "IP")==0 ||
  249. strcmp(ruleIdentifier, "Port")==0)
  250. return true;
  251. return false;
  252. }
  253. void MasterCommon::AddDefaultRulesToServer(GameServer *gameServer, PlayerID playerID)
  254. {
  255. GameServerRule *gameServerRule;
  256. // Every server has NUMBER_OF_DEFAULT_MASTER_SERVER_KEYS keys by default: IP, port, and ping
  257. gameServerRule = new GameServerRule;
  258. gameServerRule->key=new char[strlen("IP")+1];
  259. strcpy(gameServerRule->key, "IP");
  260. gameServerRule->stringValue=new char[22]; // Should be enough to hold an IP address
  261. strncpy(gameServerRule->stringValue, rakPeer->PlayerIDToDottedIP(playerID), 21);
  262. gameServerRule->stringValue[21]=0;
  263. gameServer->serverRules.Insert(gameServerRule);
  264. gameServerRule = new GameServerRule;
  265. gameServerRule->key=new char[strlen("Port")+1];
  266. strcpy(gameServerRule->key, "Port");
  267. gameServerRule->intValue=playerID.port;
  268. gameServer->serverRules.Insert(gameServerRule);
  269. gameServerRule = new GameServerRule;
  270. gameServerRule->key=new char[strlen("Ping")+1];
  271. strcpy(gameServerRule->key, "Ping");
  272. gameServerRule->intValue=9999;
  273. gameServer->serverRules.Insert(gameServerRule);
  274. }
  275. void MasterCommon::HandlePong(Packet *packet)
  276. {
  277. // Find the server specified by packet
  278. int serverIndex;
  279. unsigned int pingTime;
  280. serverIndex=gameServerList.GetIndexByPlayerID(packet->playerId);
  281. if (serverIndex>=0)
  282. {
  283. gameServerList.serverList[serverIndex]->failedPingResponses=0;
  284. if (gameServerList.serverList[serverIndex]->FindKey("Ping"))
  285. {
  286. RakNet::BitStream ptime( packet->data+1, sizeof(unsigned int), false);
  287. ptime.Read(pingTime);
  288. gameServerList.serverList[serverIndex]->serverRules[gameServerList.serverList[serverIndex]->keyIndex]->intValue=pingTime;
  289. #ifdef _SHOW_MASTER_SERVER_PRINTF
  290. printf("Got pong. Ping=%i\n", pingTime);
  291. #endif
  292. }
  293. #ifdef _DEBUG
  294. else
  295. // No ping key!
  296. assert(0);
  297. #endif
  298. }
  299. }
  300. bool MasterCommon::UpdateServerRule(GameServer *gameServer, char *ruleIdentifier, char *stringData, int intData)
  301. {
  302. GameServerRule *gameServerRule;
  303. gameServer->lastUpdateTime=RakNet::GetTime();
  304. // Add the rule to our local server. If it changes the local server, set a flag so we upload the
  305. // local server on the next update.
  306. if (gameServer->FindKey(ruleIdentifier))
  307. {
  308. // Is the data the same?
  309. if (gameServer->serverRules[gameServer->keyIndex]->stringValue)
  310. {
  311. if (stringData==0)
  312. {
  313. // No string. Delete the string and use int data instead
  314. delete [] gameServer->serverRules[gameServer->keyIndex]->stringValue;
  315. gameServer->serverRules[gameServer->keyIndex]->stringValue=0;
  316. gameServer->serverRules[gameServer->keyIndex]->intValue=intData;
  317. return true;
  318. }
  319. else if (strcmp(gameServer->serverRules[gameServer->keyIndex]->stringValue, stringData)!=0)
  320. {
  321. // Different string
  322. delete [] gameServer->serverRules[gameServer->keyIndex]->stringValue;
  323. gameServer->serverRules[gameServer->keyIndex]->stringValue = new char [strlen(stringData)+1];
  324. strcpy(gameServer->serverRules[gameServer->keyIndex]->stringValue, stringData);
  325. return true;
  326. }
  327. }
  328. else
  329. {
  330. if (stringData)
  331. {
  332. // Has a string where there is currently none
  333. gameServer->serverRules[gameServer->keyIndex]->stringValue = new char [strlen(stringData)+1];
  334. strcpy(gameServer->serverRules[gameServer->keyIndex]->stringValue, stringData);
  335. gameServer->serverRules[gameServer->keyIndex]->intValue=-1;
  336. return true;
  337. }
  338. else if (gameServer->serverRules[gameServer->keyIndex]->intValue!=intData)
  339. {
  340. // Different int value
  341. gameServer->serverRules[gameServer->keyIndex]->intValue=intData;
  342. return true;
  343. }
  344. }
  345. }
  346. else
  347. {
  348. // No such key. Add a new one.
  349. gameServerRule = new GameServerRule;
  350. gameServerRule->key=new char[strlen(ruleIdentifier)+1];
  351. strcpy(gameServerRule->key, ruleIdentifier);
  352. if (stringData)
  353. {
  354. gameServerRule->stringValue=new char[strlen(stringData)+1];
  355. strcpy(gameServerRule->stringValue, stringData);
  356. }
  357. else
  358. {
  359. gameServerRule->intValue=intData;
  360. }
  361. gameServer->serverRules.Insert(gameServerRule);
  362. return true;
  363. }
  364. return false;
  365. }
  366. bool MasterCommon::RemoveServerRule(GameServer *gameServer, char *ruleIdentifier)
  367. {
  368. if (gameServer->FindKey(ruleIdentifier))
  369. {
  370. delete gameServer->serverRules[gameServer->keyIndex];
  371. gameServer->serverRules.RemoveAtIndex(gameServer->keyIndex);
  372. return true;
  373. }
  374. return false;
  375. }
  376. void MasterCommon::SerializePlayerID(PlayerID *playerID, BitStream *outputBitStream)
  377. {
  378. outputBitStream->Write(playerID->binaryAddress);
  379. outputBitStream->Write(playerID->port);
  380. }
  381. void MasterCommon::SerializeRule(GameServerRule *gameServerRule, BitStream *outputBitStream)
  382. {
  383. stringCompressor->EncodeString(gameServerRule->key, 256, outputBitStream);
  384. if (gameServerRule->stringValue)
  385. {
  386. outputBitStream->Write(true);
  387. stringCompressor->EncodeString(gameServerRule->stringValue, 256, outputBitStream);
  388. }
  389. else
  390. {
  391. outputBitStream->Write(false);
  392. outputBitStream->WriteCompressed(gameServerRule->intValue);
  393. }
  394. }
  395. void MasterCommon::DeserializePlayerID(PlayerID *playerID, BitStream *inputBitStream)
  396. {
  397. *playerID=UNASSIGNED_PLAYER_ID;
  398. inputBitStream->Read(playerID->binaryAddress);
  399. inputBitStream->Read(playerID->port);
  400. }
  401. GameServerRule * MasterCommon::DeserializeRule(BitStream *inputBitStream)
  402. {
  403. char output[256];
  404. bool isAString;
  405. GameServerRule *newRule;
  406. newRule = new GameServerRule;
  407. stringCompressor->DecodeString(output, 256, inputBitStream);
  408. if (output[0]==0)
  409. {
  410. #ifdef _DEBUG
  411. assert(0);
  412. #endif
  413. return 0;
  414. }
  415. newRule->key = new char [strlen(output)+1];
  416. strcpy(newRule->key, output);
  417. if (inputBitStream->Read(isAString)==false)
  418. {
  419. #ifdef _DEBUG
  420. assert(0);
  421. #endif
  422. return 0;
  423. }
  424. if (isAString)
  425. {
  426. stringCompressor->DecodeString(output, 256, inputBitStream);
  427. if (output[0]==0)
  428. {
  429. #ifdef _DEBUG
  430. assert(0);
  431. #endif
  432. return 0;
  433. }
  434. newRule->stringValue = new char[strlen(output)+1];
  435. strcpy(newRule->stringValue, output);
  436. }
  437. else
  438. {
  439. if (inputBitStream->ReadCompressed(newRule->intValue)==false)
  440. {
  441. #ifdef _DEBUG
  442. assert(0);
  443. #endif
  444. return 0;
  445. }
  446. }
  447. return newRule;
  448. }
  449. void MasterCommon::SerializeServer(GameServer *gameServer, BitStream *outputBitStream)
  450. {
  451. unsigned serverIndex;
  452. unsigned short numberOfRulesToWrite;
  453. numberOfRulesToWrite=0;
  454. // Find out how many rules to write.
  455. for (serverIndex=0; serverIndex < gameServer->serverRules.Size(); serverIndex++)
  456. {
  457. // We don't write reserved identifiers
  458. if (IsReservedRuleIdentifier(gameServer->serverRules[serverIndex]->key)==false)
  459. numberOfRulesToWrite++;
  460. }
  461. // Write the server identifier
  462. SerializePlayerID(&(gameServer->connectionIdentifier), outputBitStream);
  463. // Write the number of rules
  464. outputBitStream->WriteCompressed(numberOfRulesToWrite);
  465. // Write all the rules
  466. for (serverIndex=0; serverIndex < gameServer->serverRules.Size(); serverIndex++)
  467. {
  468. if (IsReservedRuleIdentifier(gameServer->serverRules[serverIndex]->key))
  469. continue;
  470. SerializeRule(gameServer->serverRules[serverIndex], outputBitStream);
  471. }
  472. }
  473. GameServer * MasterCommon::DeserializeServer(BitStream *inputBitStream)
  474. {
  475. unsigned serverIndex;
  476. unsigned short numberOfRulesToWrite;
  477. GameServer *gameServer;
  478. GameServerRule *gameServerRule;
  479. gameServer= new GameServer;
  480. DeserializePlayerID(&(gameServer->connectionIdentifier), inputBitStream);
  481. // Read the number of rules
  482. if (inputBitStream->ReadCompressed(numberOfRulesToWrite)==false)
  483. {
  484. delete gameServer;
  485. return 0;
  486. }
  487. // Read all the rules
  488. for (serverIndex=0; serverIndex < numberOfRulesToWrite; serverIndex++)
  489. {
  490. gameServerRule = DeserializeRule(inputBitStream);
  491. if (gameServerRule==0)
  492. {
  493. delete gameServer;
  494. return 0;
  495. }
  496. if (IsReservedRuleIdentifier(gameServerRule->key))
  497. delete gameServerRule;
  498. else
  499. gameServer->serverRules.Insert(gameServerRule);
  500. }
  501. return gameServer;
  502. }
  503. void MasterCommon::UpdateServer(GameServer *destination, GameServer *source, bool deleteSingleRules)
  504. {
  505. unsigned sourceRuleIndex,destinationRuleIndex;
  506. destination->lastUpdateTime=RakNet::GetTime();
  507. // If (deleteSingleRules) then delete any rules that exist in the old and not in the new
  508. if (deleteSingleRules)
  509. {
  510. destinationRuleIndex=0;
  511. while (destinationRuleIndex < destination->serverRules.Size())
  512. {
  513. if (IsReservedRuleIdentifier(destination->serverRules[destinationRuleIndex]->key)==false &&
  514. source->FindKey(destination->serverRules[destinationRuleIndex]->key)==false)
  515. {
  516. delete destination->serverRules[destinationRuleIndex];
  517. destination->serverRules.RemoveAtIndex(destinationRuleIndex);
  518. }
  519. else
  520. destinationRuleIndex++;
  521. }
  522. }
  523. // Go through all the rules.
  524. for (sourceRuleIndex=0; sourceRuleIndex < source->serverRules.Size(); sourceRuleIndex++)
  525. {
  526. if (IsReservedRuleIdentifier(source->serverRules[sourceRuleIndex]->key))
  527. continue;
  528. // Add any fields that exist in the new and do not exist in the old
  529. // Update any fields that exist in both
  530. UpdateServerRule(destination, source->serverRules[sourceRuleIndex]->key, source->serverRules[sourceRuleIndex]->stringValue, source->serverRules[sourceRuleIndex]->intValue);
  531. }
  532. }
  533. GameServer* MasterCommon::UpdateServerList(GameServer *gameServer, bool deleteSingleRules, bool *newServerAdded)
  534. {
  535. int searchIndex;
  536. if (gameServer==0)
  537. {
  538. #ifdef _DEBUG
  539. assert(0);
  540. #endif
  541. return 0;
  542. }
  543. // Find the existing game server that matches this port/address.
  544. searchIndex = gameServerList.GetIndexByPlayerID(gameServer->connectionIdentifier);
  545. if (searchIndex<0)
  546. {
  547. // If not found, then add it to the list.
  548. AddDefaultRulesToServer(gameServer, gameServer->connectionIdentifier);
  549. gameServerList.serverList.Insert(gameServer);
  550. *newServerAdded=true;
  551. return gameServer;
  552. }
  553. else
  554. {
  555. // Update the existing server
  556. UpdateServer(gameServerList.serverList[searchIndex], gameServer, deleteSingleRules);
  557. delete gameServer;
  558. *newServerAdded=false;
  559. return gameServerList.serverList[searchIndex];
  560. }
  561. }
  562. void MasterCommon::OnAttach(RakPeerInterface *peer)
  563. {
  564. rakPeer=peer;
  565. }
粤ICP备19079148号