Server.cpp 35 KB

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