Server.cpp 35 KB

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