Server.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "Connection.h"
  25. #include "File.h"
  26. #include "Log.h"
  27. #include "Network.h"
  28. #include "NetworkEvents.h"
  29. #include "PackageFile.h"
  30. #include "Profiler.h"
  31. #include "Protocol.h"
  32. #include "ProtocolEvents.h"
  33. #include "Scene.h"
  34. #include "Server.h"
  35. #include "StringUtils.h"
  36. #include <set>
  37. #include "DebugNew.h"
  38. // Timeout for closing transferred package files, in milliseconds
  39. static const int FILE_TIMEOUT = 15 * 1000;
  40. OBJECTTYPESTATIC(Server);
  41. Server::Server(Context* context) :
  42. Object(context),
  43. netFps_(30),
  44. timeAcc_(0),
  45. frameNumber_(1),
  46. maxSceneRevisions_(100),
  47. stayRelevantTime_(30)
  48. {
  49. SubscribeToEvent(E_PEERCONNECTED, HANDLER(Server, HandlePeerConnected));
  50. SubscribeToEvent(E_PEERDISCONNECTED, HANDLER(Server, HandlePeerDisconnected));
  51. }
  52. Server::~Server()
  53. {
  54. }
  55. void Server::SetNetFps(int fps)
  56. {
  57. netFps_ = max(fps, 1);
  58. }
  59. void Server::SetMaxSceneRevisions(int revisions)
  60. {
  61. maxSceneRevisions_ = max(revisions, 3);
  62. }
  63. void Server::SetStayRelevantTime(int time)
  64. {
  65. stayRelevantTime_ = max(time, 1);
  66. }
  67. void Server::AddScene(Scene* scene)
  68. {
  69. if (!scene)
  70. return;
  71. if (HasScene(scene))
  72. {
  73. LOGWARNING("Scene " + scene->GetName() + " already added to server");
  74. return;
  75. }
  76. scene->SetNetworkMode(NM_SERVER);
  77. scenes_.push_back(SharedPtr<Scene>(scene));
  78. }
  79. void Server::RemoveScene(Scene* scene)
  80. {
  81. if (!scene)
  82. return;
  83. for (unsigned i = 0; i < scenes_.size(); ++i)
  84. {
  85. if (scenes_[i] == scene)
  86. {
  87. VectorBuffer packet;
  88. packet.WriteUByte(MSG_JOINREPLY);
  89. packet.WriteBool(false);
  90. packet.WriteString("The scene is shutting down");
  91. // If any clients are connected to this scene, they must leave forcibly
  92. for (unsigned j = 0; j < connections_.size(); ++j)
  93. {
  94. Connection* connection = connections_[j];
  95. if (connection->GetScene() == scene)
  96. {
  97. connection->SendReliable(packet);
  98. connection->LeftScene();
  99. }
  100. }
  101. // Remove the network mode
  102. scene->SetNetworkMode(NM_NONETWORK);
  103. scenes_.erase(scenes_.begin() + i);
  104. return;
  105. }
  106. }
  107. LOGWARNING("Scene " + scene->GetName() + " not found on server");
  108. }
  109. bool Server::Start(unsigned short port)
  110. {
  111. timeAcc_ = 0.0f;
  112. frameNumber_ = 1;
  113. return GetSubsystem<Network>()->StartServer(port);
  114. }
  115. void Server::Stop()
  116. {
  117. GetSubsystem<Network>()->StopServer();
  118. }
  119. void Server::Update(float timeStep)
  120. {
  121. PROFILE(UpdateServer);
  122. // Process incoming packets from connections (assume that Engine has updated Network, so we do not do that here)
  123. for (unsigned i = 0; i < connections_.size(); ++i)
  124. HandlePackets(connections_[i]);
  125. // Update scenes / send update if enough time passed
  126. float netPeriod = 1.0f / netFps_;
  127. timeAcc_ += timeStep;
  128. if (timeAcc_ >= netPeriod)
  129. {
  130. // Update simulation of scene(s)
  131. for (unsigned i = 0; i < scenes_.size(); ++i)
  132. scenes_[i]->Update(netPeriod);
  133. // If multiple updates have accumulated because of a slow frame, send just one
  134. while (timeAcc_ >= netPeriod)
  135. timeAcc_ -= netPeriod;
  136. ++frameNumber_;
  137. // We have a policy that framenumber 0 means "frame never received", so loop back to 1
  138. if (!frameNumber_)
  139. ++frameNumber_;
  140. // Send update for each connection
  141. for (unsigned i = 0; i < connections_.size(); ++i)
  142. SendServerUpdate(connections_[i]);
  143. }
  144. // Remove disconnected clients
  145. for (std::vector<SharedPtr<Connection> >::iterator i = connections_.begin(); i != connections_.end();)
  146. {
  147. if (!(*i)->IsConnected())
  148. i = connections_.erase(i);
  149. else
  150. ++i;
  151. }
  152. // Close file transfers that have been unused for some time
  153. for (std::map<StringHash, ServerFileTransfer>::iterator i = fileTransfers_.begin(); i != fileTransfers_.end();)
  154. {
  155. std::map<StringHash, ServerFileTransfer>::iterator current = i++;
  156. if (current->second.closeTimer_.GetMSec(false) > FILE_TIMEOUT)
  157. fileTransfers_.erase(current);
  158. }
  159. }
  160. bool Server::SetClientScene(Connection* connection, Scene* scene)
  161. {
  162. // Check that the scene is under server control
  163. if (!HasScene(scene))
  164. return false;
  165. connection->SetScene(scene);
  166. SendSceneInfo(connection);
  167. return true;
  168. }
  169. bool Server::IsRunning() const
  170. {
  171. return GetSubsystem<Network>()->IsServer();
  172. }
  173. bool Server::HasScene(Scene* scene) const
  174. {
  175. for (unsigned i = 0; i < scenes_.size(); ++i)
  176. {
  177. if (scenes_[i] == scene)
  178. return true;
  179. }
  180. return false;
  181. }
  182. unsigned Server::GetNumUsersInScene(Scene* scene) const
  183. {
  184. unsigned users = 0;
  185. for (unsigned i = 0; i < connections_.size(); ++i)
  186. {
  187. if (connections_[i]->GetScene() == scene)
  188. ++users;
  189. }
  190. return users;
  191. }
  192. void Server::HandlePackets(Connection* connection)
  193. {
  194. VectorBuffer packet;
  195. // Process reliable packets first, then unreliable
  196. while (connection->ReceiveReliable(packet))
  197. {
  198. if (!HandleReliablePacket(connection, packet))
  199. return;
  200. }
  201. while (connection->ReceiveUnreliable(packet))
  202. {
  203. if (!HandleClientUpdate(connection, packet))
  204. return;
  205. }
  206. }
  207. void Server::HandlePeerConnected(StringHash eventType, VariantMap& eventData)
  208. {
  209. using namespace PeerConnected;
  210. Peer* peer = static_cast<Peer*>(eventData[P_PEER].GetPtr());
  211. if (peer->GetPeerType() != PEER_CLIENT)
  212. return;
  213. // Create a new connection, assign a challenge, then send the challenge message
  214. SharedPtr<Connection> connection(new Connection(context_, peer));
  215. connections_.push_back(connection);
  216. unsigned challenge = GenerateChallenge();
  217. connection->SetChallenge(challenge);
  218. VectorBuffer packet;
  219. packet.WriteUByte(MSG_CHALLENGE);
  220. packet.WriteUInt(challenge);
  221. connection->SendReliable(packet);
  222. }
  223. void Server::HandlePeerDisconnected(StringHash eventType, VariantMap& eventData)
  224. {
  225. using namespace PeerDisconnected;
  226. Peer* peerPtr = static_cast<Peer*>(eventData[P_PEER].GetPtr());
  227. if (peerPtr->GetPeerType() != PEER_CLIENT)
  228. return;
  229. for (unsigned i = 0; i < connections_.size(); ++i)
  230. {
  231. Connection* connection = connections_[i];
  232. if (connection->GetPeer() == peerPtr)
  233. {
  234. // Remove if was in a scene
  235. connection->LeftScene();
  236. return;
  237. }
  238. }
  239. }
  240. bool Server::HandleReliablePacket(Connection* connection, VectorBuffer& packet)
  241. {
  242. unsigned char msgID = 0;
  243. msgID = packet.ReadUByte();
  244. switch (msgID)
  245. {
  246. case MSG_LOGIN:
  247. if (!HandleLogin(connection, packet))
  248. return false;
  249. else
  250. break;
  251. case MSG_REQUESTFILE:
  252. HandleRequestFile(connection, packet);
  253. break;
  254. case MSG_JOINSCENE:
  255. HandleJoinScene(connection, packet);
  256. break;
  257. case MSG_FULLUPDATEACK:
  258. HandleFullUpdateAck(connection, packet);
  259. break;
  260. default:
  261. Disconnect(connection, false, "Unauthorized message ID " + ToString((int)msgID) + ", disconnecting client");
  262. return false;
  263. }
  264. return true;
  265. }
  266. bool Server::HandleLogin(Connection* connection, VectorBuffer& packet)
  267. {
  268. connection->SetLoginData(packet.ReadVariantMap());
  269. // Send login event and check if any event handler denies access
  270. using namespace ClientLogin;
  271. // Initialize eventdata with the logindata received
  272. VariantMap eventData = connection->GetLoginData();
  273. eventData[P_CONNECTION] = (void*)connection;
  274. eventData[P_AUTHORIZE] = true;
  275. SendEvent(E_CLIENTLOGIN, eventData);
  276. if (!eventData[P_AUTHORIZE].GetBool())
  277. {
  278. Disconnect(connection, false, "Disconnecting unauthorized client");
  279. return false;
  280. }
  281. return true;
  282. }
  283. void Server::HandleRequestFile(Connection* connection, VectorBuffer& packet)
  284. {
  285. StringHash nameHash = packet.ReadStringHash();
  286. int fragmentStart = packet.ReadVLE();
  287. int fragmentCount = packet.ReadVLE();
  288. // The only files we are willing to transmit are packages associated with scene(s)
  289. PackageFile* package = 0;
  290. for (unsigned i = 0; i < scenes_.size(); ++i)
  291. {
  292. const std::vector<SharedPtr<PackageFile> >& packages = scenes_[i]->GetRequiredPackageFiles();
  293. for (unsigned j = 0; j < packages.size(); ++j)
  294. {
  295. if (packages[j]->GetNameHash() == nameHash)
  296. {
  297. package = packages[j];
  298. break;
  299. }
  300. }
  301. }
  302. if (!package)
  303. {
  304. LOGWARNING("Client " + connection->GetIdentity() + " requested unknown file " + ToString(nameHash));
  305. VectorBuffer replyPacket;
  306. replyPacket.WriteUByte(MSG_TRANSFERFAILED);
  307. replyPacket.WriteStringHash(nameHash);
  308. replyPacket.WriteString("File not found");
  309. connection->SendReliable(replyPacket);
  310. return;
  311. }
  312. // Open file if not already open
  313. File* file = fileTransfers_[nameHash].file_;
  314. if (!file)
  315. {
  316. file = fileTransfers_[nameHash].file_ = new File(context_, package->GetName());
  317. if (!file->IsOpen())
  318. {
  319. LOGERROR("Failed to open package file " + package->GetName() + " for file transfer");
  320. VectorBuffer replyPacket;
  321. replyPacket.WriteUByte(MSG_TRANSFERFAILED);
  322. replyPacket.WriteStringHash(nameHash);
  323. replyPacket.WriteString("Could not open file");
  324. connection->SendReliable(replyPacket);
  325. return;
  326. }
  327. }
  328. fileTransfers_[nameHash].closeTimer_.Reset();
  329. // Check that fragment range is valid
  330. unsigned fileSize = file->GetSize();
  331. int maxFragments = (fileSize - 1) / FILE_FRAGMENT_SIZE + 1;
  332. if (fragmentStart + fragmentCount > maxFragments)
  333. fragmentCount = maxFragments - fragmentStart;
  334. if (fragmentCount <= 0)
  335. return;
  336. if (!fragmentStart)
  337. LOGINFO("Client " + connection->GetIdentity() + " requested file " + ToString(nameHash));
  338. // Send the fragments
  339. unsigned fragmentOffset = fragmentStart * FILE_FRAGMENT_SIZE;
  340. file->Seek(fragmentOffset);
  341. for (int i = fragmentStart; i < fragmentStart + fragmentCount; ++i)
  342. {
  343. fragmentOffset = i * FILE_FRAGMENT_SIZE;
  344. unsigned fragmentSize = fileSize - fragmentOffset;
  345. if (fragmentSize > FILE_FRAGMENT_SIZE)
  346. fragmentSize = FILE_FRAGMENT_SIZE;
  347. VectorBuffer fragmentPacket;
  348. fragmentPacket.Seek(0);
  349. fragmentPacket.WriteUByte(MSG_TRANSFERDATA);
  350. fragmentPacket.WriteStringHash(nameHash);
  351. fragmentPacket.WriteVLE(i);
  352. fragmentPacket.Resize(fragmentPacket.GetPosition() + fragmentSize);
  353. file->Read(fragmentPacket.GetModifiableData() + fragmentPacket.GetPosition(), fragmentSize);
  354. connection->SendReliable(fragmentPacket);
  355. }
  356. }
  357. void Server::HandleJoinScene(Connection* connection, VectorBuffer& packet)
  358. {
  359. unsigned checksum = packet.ReadUInt();
  360. Scene* scene = connection->GetScene();
  361. VectorBuffer replyPacket;
  362. replyPacket.WriteUByte(MSG_JOINREPLY);
  363. if (!scene)
  364. {
  365. replyPacket.WriteBool(false);
  366. replyPacket.WriteString("No scene");
  367. LOGINFO("Client " + connection->GetIdentity() + " attempted to join without an assigned scene");
  368. }
  369. else if (checksum != scene->GetChecksum())
  370. {
  371. replyPacket.WriteBool(false);
  372. replyPacket.WriteString("Scene checksum mismatch");
  373. LOGINFO("Client " + connection->GetIdentity() + " checksum mismatch for scene " + scene->GetName());
  374. }
  375. else
  376. {
  377. replyPacket.WriteBool(true);
  378. connection->JoinedScene();
  379. }
  380. connection->SendReliable(replyPacket);
  381. }
  382. void Server::HandleFullUpdateAck(Connection* connection, VectorBuffer& packet)
  383. {
  384. if (connection->GetJoinState() == JS_WAITFORACK)
  385. {
  386. unsigned short lastFrameNumber = packet.ReadUShort();
  387. unsigned short lastFrameAck = packet.ReadUShort();
  388. connection->SetFrameNumbers(lastFrameNumber, lastFrameAck);
  389. connection->UpdateRoundTripTime(netFps_, frameNumber_);
  390. connection->SetJoinState(JS_SENDDELTAS);
  391. }
  392. else
  393. LOGWARNING("Received unexpected full update ack from client " + connection->GetIdentity());
  394. }
  395. bool Server::HandleClientUpdate(Connection* connection, VectorBuffer& packet)
  396. {
  397. // Disregard unreliable client updates while waiting for the initial scene ack
  398. if (connection->GetJoinState() != JS_SENDDELTAS)
  399. return true;
  400. unsigned short lastFrameNumber = packet.ReadUShort();
  401. unsigned short lastFrameAck = packet.ReadUShort();
  402. // Check that this packet is not older than the last received (overlap may occur when we transition
  403. // between a reliable full update and unreliable delta updates)
  404. if (!CheckFrameNumber(lastFrameNumber, connection->GetFrameNumber()))
  405. return true;
  406. connection->SetFrameNumbers(lastFrameNumber, lastFrameAck);
  407. connection->UpdateRoundTripTime(netFps_, frameNumber_);
  408. unsigned short previousEventFrameNumber = connection->GetEventFrameNumber();
  409. while (!packet.IsEof())
  410. {
  411. unsigned char msgID = packet.ReadUByte();
  412. // The client is only allowed to send a few specific messages in the client update
  413. switch (msgID)
  414. {
  415. case MSG_REMOTEEVENT:
  416. {
  417. RemoteEvent newEvent;
  418. newEvent.Read(packet, false);
  419. if (connection->CheckRemoteEventFrame(newEvent, previousEventFrameNumber))
  420. newEvent.Dispatch(connection, connection->GetScene());
  421. }
  422. break;
  423. case MSG_REMOTENODEEVENT:
  424. {
  425. RemoteEvent newEvent;
  426. newEvent.Read(packet, true);
  427. if (connection->CheckRemoteEventFrame(newEvent, previousEventFrameNumber))
  428. newEvent.Dispatch(connection, connection->GetScene());
  429. }
  430. break;
  431. case MSG_CONTROLS:
  432. {
  433. Controls newControls;
  434. newControls.buttons_ = packet.ReadUInt();
  435. newControls.yaw_ = packet.ReadFloat();
  436. newControls.pitch_ = packet.ReadFloat();
  437. newControls.extraData_ = packet.ReadVariantMap();
  438. connection->SetControls(newControls);
  439. connection->SetPosition(packet.ReadVector3());
  440. using namespace ClientControls;
  441. // Initialize event parameters with possible extra controls
  442. VariantMap eventData = newControls.extraData_;
  443. eventData[P_CONNECTION] = (void*)connection;
  444. eventData[P_FRAMENUMBER] = connection->GetFrameNumber();
  445. eventData[P_BUTTONS] = newControls.buttons_;
  446. eventData[P_YAW] = newControls.yaw_;
  447. eventData[P_PITCH] = newControls.pitch_;
  448. SendEvent(E_CLIENTCONTROLS, eventData);
  449. break;
  450. }
  451. default:
  452. Disconnect(connection, false, "Unauthorized message ID " + ToString((int)msgID) + ", disconnecting client");
  453. return false;
  454. }
  455. }
  456. return true;
  457. }
  458. void Server::SendSceneInfo(Connection* connection)
  459. {
  460. Scene* scene = connection->GetScene();
  461. if (!scene)
  462. return;
  463. VectorBuffer packet;
  464. packet.WriteUByte(MSG_SCENEINFO);
  465. // Write scene name, number of users and update rate
  466. packet.WriteString(scene->GetName());
  467. packet.WriteVLE(GetNumUsersInScene(scene));
  468. packet.WriteInt(netFps_);
  469. // Write source file name & required packages
  470. const std::vector<SharedPtr<PackageFile> >& requiredPackages = scene->GetRequiredPackageFiles();
  471. packet.WriteString(scene->GetFileName());
  472. packet.WriteVLE(requiredPackages.size());
  473. for (unsigned i = 0; i < requiredPackages.size(); ++i)
  474. {
  475. PackageFile* package = requiredPackages[i];
  476. packet.WriteString(package->GetName());
  477. packet.WriteUInt(package->GetTotalSize());
  478. packet.WriteUInt(package->GetChecksum());
  479. }
  480. connection->SendReliable(packet);
  481. }
  482. void Server::SendFullUpdate(Connection* connection)
  483. {
  484. PROFILE(SendFullUpdate);
  485. Scene* scene = connection->GetScene();
  486. if (!scene)
  487. return;
  488. // Clear all scene revision data so that we write a full update
  489. connection->ClearSceneState();
  490. VectorBuffer packet;
  491. packet.WriteUByte(MSG_FULLUPDATE);
  492. WriteNetUpdate(connection, packet);
  493. connection->SendReliable(packet);
  494. // All unacked remote events were sent reliably, so clear them
  495. connection->ClearRemoteEvents();
  496. connection->SetJoinState(JS_WAITFORACK);
  497. LOGDEBUG("Initial scene: " + ToString(packet.GetSize()) + " bytes");
  498. }
  499. void Server::SendServerUpdate(Connection* connection)
  500. {
  501. PROFILE(SendServerUpdate);
  502. Scene* scene = connection->GetScene();
  503. JoinState state = connection->GetJoinState();
  504. if ((!scene) || (state < JS_SENDFULLUPDATE) || (state == JS_WAITFORACK))
  505. return;
  506. // Purge states and events which are older than last acked, and expired remote events
  507. connection->PurgeAckedSceneState();
  508. connection->PurgeAckedRemoteEvents(frameNumber_);
  509. // If already have too many revisions stored, fall back to the initial scene sending (reliable)
  510. if (connection->GetSceneState().GetRevisionCount() >= maxSceneRevisions_)
  511. {
  512. LOGWARNING("Too many scene revisions for client " + connection->GetIdentity() + ", falling back to initial scene send");
  513. state = JS_SENDFULLUPDATE;
  514. }
  515. // Send initial scene as reliable
  516. if (state == JS_SENDFULLUPDATE)
  517. {
  518. SendFullUpdate(connection);
  519. return;
  520. }
  521. VectorBuffer packet;
  522. WriteNetUpdate(connection, packet);
  523. connection->SendUnreliable(packet);
  524. //LOGDEBUG("Delta: " + ToString(packet.GetSize()) + " Revisions: " +
  525. // ToString(connection->GetSceneState().GetRevisionCount()) + " Events: " +
  526. // ToString(connection->GetUnackedRemoteEvents().size()));
  527. }
  528. unsigned Server::GenerateChallenge() const
  529. {
  530. return (rand() & 32767) | ((rand() & 32767) << 15) | ((rand() & 32767) << 30);
  531. }
  532. void Server::Disconnect(Connection* connection, bool forced, const std::string& logMessage)
  533. {
  534. LOGERROR(logMessage + " " + connection->GetIdentity());
  535. if (forced)
  536. connection->forceDisconnect();
  537. else
  538. connection->Disconnect();
  539. // Send event
  540. using namespace ClientDisconnected;
  541. VariantMap eventData;
  542. eventData[P_CONNECTION] = (void*)connection;
  543. SendEvent(E_CLIENTDISCONNECTED, eventData);
  544. }
  545. void Server::WriteNetUpdate(Connection* connection, Serializer& dest)
  546. {
  547. PROFILE(WriteNetUpdate);
  548. Scene* scene = connection->GetScene();
  549. SceneReplicationState& sceneState = connection->GetSceneState();
  550. // Write frame numbers
  551. dest.WriteUShort(frameNumber_);
  552. dest.WriteUShort(connection->GetFrameNumber());
  553. VectorBuffer emptyBaseRevision;
  554. VectorBuffer propertyBuffer;
  555. VectorBuffer newBuffer;
  556. VectorBuffer removeBuffer;
  557. VectorBuffer updateBuffer;
  558. VectorBuffer newRevision;
  559. /*
  560. // Find relevant nodes for this client
  561. std::set<unsigned> relevantNodes;
  562. GetRelevantNodes(connection, relevantNodes);
  563. {
  564. // Go through the scene and see which nodes are new and which have been removed
  565. const std::map<unsigned, SharedPtr<Node> >& nodes = scene->GetAllNodes();
  566. std::set<unsigned> processedNodes;
  567. for (std::map<unsigned, SharedPtr<Node> >::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
  568. {
  569. // If we reach the local node ID's, break
  570. if (i->first >= FIRST_LOCAL_ID)
  571. break;
  572. processedNodes.insert(i->first);
  573. bool relevant = relevantNodes.find(i->first) != relevantNodes.end();
  574. Node* node = i->second;
  575. NodeReplicationState* nodeState = sceneState.findNode(i->first);
  576. if (!nodeState)
  577. {
  578. // If client does not have this node and it is not relevant, skip
  579. if (!relevant)
  580. continue;
  581. nodeState = &sceneState.nodes_[i->first];
  582. nodeState->Created(frameNumber_);
  583. nodeState->stayRelevantTime_ = stayRelevantTime_;
  584. }
  585. else
  586. {
  587. // If nodestate exists, check relevancy timer and refresh it if necessary
  588. if (relevant)
  589. nodeState->stayRelevantTime_ = stayRelevantTime_;
  590. else if (nodeState->stayRelevantTime_ > 0)
  591. {
  592. --nodeState->stayRelevantTime_;
  593. relevant = true;
  594. }
  595. else
  596. // If node is not relevant, and relevancy timer has expired, do not check for changes
  597. continue;
  598. if (!nodeState->exists_)
  599. nodeState->Created(frameNumber_);
  600. }
  601. // Check components of this node
  602. const std::vector<SharedPtr<Component> >& components = node->GetComponents();
  603. std::set<ShortStringHash> processedComponents;
  604. for (std::vector<SharedPtr<Component> >::const_iterator j = components.begin(); j != components.end(); ++j)
  605. {
  606. Component* component = *j;
  607. if (!component->checkSync(connection))
  608. continue;
  609. ShortStringHash combinedHash = component->GetCombinedHash();
  610. ComponentReplicationState* componentState = nodeState->findComponent(combinedHash);
  611. if (!componentState)
  612. {
  613. componentState = &nodeState->components_[combinedHash];
  614. componentState->Created(frameNumber_);
  615. }
  616. else if (!componentState->exists_)
  617. componentState->Created(frameNumber_);
  618. processedComponents.insert(combinedHash);
  619. }
  620. // Check components that have been removed
  621. for (std::map<ShortStringHash, ComponentReplicationState>::iterator j = nodeState->components_.begin();
  622. j != nodeState->components_.end(); ++j)
  623. {
  624. if (j->second.exists_)
  625. {
  626. if (processedComponents.find(j->first) == processedComponents.end())
  627. j->second.Removed(frameNumber_);
  628. }
  629. }
  630. }
  631. // Check nodes that have been removed
  632. for (std::map<unsigned, NodeReplicationState>::iterator i = sceneState.nodes_.begin();
  633. i != sceneState.nodes_.end(); ++i)
  634. {
  635. if (i->second.exists_)
  636. {
  637. if (processedNodes.find(i->first) == processedNodes.end())
  638. i->second.Removed(frameNumber_);
  639. }
  640. }
  641. }
  642. {
  643. // Now go through the replication state again and build commands
  644. for (std::map<unsigned, NodeReplicationState>::iterator i = sceneState.nodes_.begin();
  645. i != sceneState.nodes_.end(); ++i)
  646. {
  647. Node* node = scene->GetNode(i->first);
  648. NodeReplicationState& nodeState = i->second;
  649. // Create
  650. if ((nodeState.createdFrame_) && (node))
  651. {
  652. dest.WriteUByte(MSG_CREATEENTITY);
  653. dest.WriteUShort(node->GetID());
  654. dest.WriteString(node->GetName());
  655. dest.WriteUByte(GetClientNetFlags(connection, node, node->GetNetFlags()));
  656. dest.WriteVLE(node->GetGroupFlags());
  657. // Write a full update of node properties
  658. newRevision.Seek(0);
  659. if (node->WriteNetUpdate(dest, newRevision, emptyBaseRevision, info))
  660. nodeState.revisions_.Commit(frameNumber_, newRevision);
  661. // Write a full update of all components that should be synced
  662. const std::vector<SharedPtr<Component> >& components = node->GetComponents();
  663. unsigned newComponents = 0;
  664. newBuffer.Seek(0);
  665. for (std::vector<SharedPtr<Component> >::const_iterator j = components.begin(); j != components.end(); ++j)
  666. {
  667. Component* component = *j;
  668. if (!component->checkSync(connection))
  669. continue;
  670. ComponentReplicationState& componentState = nodeState.components_[component->GetCombinedHash()];
  671. newBuffer.WriteShortStringHash(component->GetType());
  672. newBuffer.WriteString(component->GetName());
  673. newBuffer.WriteUByte(GetClientNetFlags(connection, node, component->GetNetFlags()));
  674. newRevision.Seek(0);
  675. component->WriteNetUpdate(newBuffer, newRevision, emptyBaseRevision, info);
  676. componentState.revisions_.Commit(frameNumber_, newRevision);
  677. ++newComponents;
  678. }
  679. dest.WriteVLE(newComponents);
  680. // Check if any components were actually written
  681. if (newComponents)
  682. dest.Write(newBuffer.GetData(), newBuffer.GetPosition());
  683. }
  684. // Remove
  685. else if (nodeState.removedFrame_)
  686. {
  687. dest.WriteUByte(MSG_REMOVEENTITY);
  688. dest.WriteUShort(i->first);
  689. }
  690. // Update
  691. else if (node)
  692. {
  693. // If node's update timer has expired (it is not relevant), do not write updates
  694. if (nodeState.stayRelevantTime_ <= 0)
  695. {
  696. // However, we must be careful to see what to do when the node becomes relevant again
  697. // If node has unacked property or component revisions, must forget all of them
  698. if (nodeState.HasUnAcked(connection->GetFrameAck()))
  699. {
  700. nodeState.revisions_.clear();
  701. for (std::map<ShortStringHash, ComponentReplicationState>::iterator j = nodeState.components_.begin();
  702. j != nodeState.components_.end(); ++j)
  703. j->second.revisions_.clear();
  704. }
  705. continue;
  706. }
  707. // Divide update types into separate buffers, then see which of them got data
  708. // (if there are no updates, then this node does not need to write anything into the final stream)
  709. unsigned newComponents = 0;
  710. unsigned removedComponents = 0;
  711. unsigned updatedComponents = 0;
  712. propertyBuffer.Seek(0);
  713. newBuffer.Seek(0);
  714. removeBuffer.Seek(0);
  715. updateBuffer.Seek(0);
  716. unsigned char msgID = MSG_UPDATEENTITY;
  717. // Property update
  718. Deserializer& baseRevision = nodeState.revisions_.GetBase();
  719. newRevision.Seek(0);
  720. if (node->WriteNetUpdate(propertyBuffer, newRevision, baseRevision, info))
  721. {
  722. nodeState.revisions_.Commit(frameNumber_, newRevision);
  723. msgID |= UPD_PROPERTIES;
  724. }
  725. // Component create/remove/update
  726. for (std::map<ShortStringHash, ComponentReplicationState>::iterator j = nodeState.components_.begin();
  727. j != nodeState.components_.end(); ++j)
  728. {
  729. Component* component = node->GetComponent(j->first.mData);
  730. ComponentReplicationState& componentState = j->second;
  731. // Create
  732. if ((componentState.createdFrame_) && (component))
  733. {
  734. newBuffer.WriteShortStringHash(component->GetType());
  735. newBuffer.WriteString(component->GetName());
  736. newBuffer.WriteUByte(GetClientNetFlags(connection, node, component->GetNetFlags()));
  737. newRevision.Seek(0);
  738. component->WriteNetUpdate(newBuffer, newRevision, emptyBaseRevision, info);
  739. componentState.revisions_.Commit(frameNumber_, newRevision);
  740. msgID |= UPD_NEWCOMPONENTS;
  741. ++newComponents;
  742. }
  743. // Remove
  744. else if (componentState.removedFrame_)
  745. {
  746. msgID |= UPD_REMOVECOMPONENTS;
  747. ++removedComponents;
  748. removeBuffer.WriteShortStringHash(j->first);
  749. }
  750. // Update
  751. else if (component)
  752. {
  753. // Prepare to rewind buffer in case component writes nothing meaningful
  754. unsigned oldPos = updateBuffer.GetPosition();
  755. updateBuffer.WriteShortStringHash(component->GetCombinedHash());
  756. newRevision.Seek(0);
  757. Deserializer& baseRevision = componentState.revisions_.GetBase();
  758. if (component->WriteNetUpdate(updateBuffer, newRevision, baseRevision, info))
  759. {
  760. componentState.revisions_.Commit(frameNumber_, newRevision);
  761. msgID |= UPD_UPDATECOMPONENTS;
  762. ++updatedComponents;
  763. }
  764. else
  765. updateBuffer.Seek(oldPos);
  766. }
  767. }
  768. // Now write each buffer if there was some data
  769. if (msgID != MSG_UPDATEENTITY)
  770. {
  771. dest.WriteUByte(msgID);
  772. dest.WriteUShort(node->GetID());
  773. if (msgID & UPD_PROPERTIES)
  774. dest.Write(propertyBuffer.GetData(), propertyBuffer.GetPosition());
  775. if (msgID & UPD_NEWCOMPONENTS)
  776. {
  777. dest.WriteVLE(newComponents);
  778. dest.Write(newBuffer.GetData(), newBuffer.GetPosition());
  779. }
  780. if (msgID & UPD_REMOVECOMPONENTS)
  781. {
  782. dest.WriteVLE(removedComponents);
  783. dest.Write(removeBuffer.GetData(), removeBuffer.GetPosition());
  784. }
  785. if (msgID & UPD_UPDATECOMPONENTS)
  786. {
  787. dest.WriteVLE(updatedComponents);
  788. dest.Write(updateBuffer.GetData(), updateBuffer.GetPosition());
  789. }
  790. }
  791. }
  792. }
  793. }
  794. */
  795. // Append unacked remote events
  796. const std::vector<RemoteEvent>& unackedEvents = connection->GetUnackedRemoteEvents();
  797. for (std::vector<RemoteEvent>::const_iterator i = unackedEvents.begin(); i != unackedEvents.end(); ++i)
  798. {
  799. dest.WriteUByte(i->nodeID_ ? MSG_REMOTENODEEVENT : MSG_REMOTEEVENT);
  800. i->Write(dest);
  801. }
  802. }
  803. void Server::GetRelevantNodes(Connection* connection, std::set<unsigned>& dest) const
  804. {
  805. // Generate just the raw set of relevant nodes based on their owner, distance and references. A node might need
  806. // to stay relevant because it has unacked changes, or has time left in its relevancy timer, but that is checked in
  807. // WriteNetUpdate()
  808. PROFILE(GetRelevantNodes);
  809. dest.clear();
  810. Scene* scene = connection->GetScene();
  811. const std::map<unsigned, Node*>& nodes = scene->GetAllNodes();
  812. const Vector3& clientPos = connection->GetPosition();
  813. for (std::map<unsigned, Node*>::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
  814. {
  815. // Stop when local node ID range reached
  816. if (i->first >= FIRST_LOCAL_ID)
  817. break;
  818. Node* node = i->second;
  819. // If node is not owned by client and max. update distance has been defined, check it
  820. if (node->GetOwner() != connection)
  821. {
  822. //float maxDistance = node->GetNetUpdateDistance();
  823. float maxDistance = 100.0f; /// \todo Add max. update distance to Node
  824. if (maxDistance > 0.0f)
  825. {
  826. if ((node->GetWorldPosition() - clientPos).GetLengthSquared() > maxDistance * maxDistance)
  827. continue;
  828. }
  829. }
  830. // Node is relevant. Now also find its dependencies
  831. dest.insert(i->first);
  832. /// \todo Implement getting the dependencies from a node
  833. //GetNodeDependencies(connection, node, dest);
  834. }
  835. }