Connection.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Precompiled.h"
  23. #include "../Core/Profiler.h"
  24. #include "../IO/File.h"
  25. #include "../IO/FileSystem.h"
  26. #include "../IO/Log.h"
  27. #include "../IO/MemoryBuffer.h"
  28. #include "../IO/PackageFile.h"
  29. #include "../Network/Connection.h"
  30. #include "../Network/Network.h"
  31. #include "../Network/NetworkEvents.h"
  32. #include "../Network/NetworkPriority.h"
  33. #include "../Network/Protocol.h"
  34. #include "../Resource/ResourceCache.h"
  35. #include "../Scene/Scene.h"
  36. #include "../Scene/SceneEvents.h"
  37. #include "../Scene/SmoothedTransform.h"
  38. #include <kNet/kNet.h>
  39. #include "../DebugNew.h"
  40. namespace Urho3D
  41. {
  42. static const int STATS_INTERVAL_MSEC = 2000;
  43. PackageDownload::PackageDownload() :
  44. totalFragments_(0),
  45. checksum_(0),
  46. initiated_(false)
  47. {
  48. }
  49. PackageUpload::PackageUpload() :
  50. fragment_(0),
  51. totalFragments_(0)
  52. {
  53. }
  54. Connection::Connection(Context* context, bool isClient, kNet::SharedPtr<kNet::MessageConnection> connection) :
  55. Object(context),
  56. timeStamp_(0),
  57. connection_(connection),
  58. sendMode_(OPSM_NONE),
  59. isClient_(isClient),
  60. connectPending_(false),
  61. sceneLoaded_(false),
  62. logStatistics_(false)
  63. {
  64. sceneState_.connection_ = this;
  65. // Store address and port now for accurate logging (kNet may already have destroyed the socket on disconnection,
  66. // in which case we would log a zero address:port on disconnect)
  67. kNet::EndPoint endPoint = connection_->RemoteEndPoint();
  68. ///\todo Not IPv6-capable.
  69. address_ = Urho3D::ToString("%d.%d.%d.%d", endPoint.ip[0], endPoint.ip[1], endPoint.ip[2], endPoint.ip[3]);
  70. port_ = endPoint.port;
  71. }
  72. Connection::~Connection()
  73. {
  74. // Reset scene (remove possible owner references), as this connection is about to be destroyed
  75. SetScene(0);
  76. }
  77. void Connection::SendMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID)
  78. {
  79. SendMessage(msgID, reliable, inOrder, msg.GetData(), msg.GetSize(), contentID);
  80. }
  81. void Connection::SendMessage(int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes,
  82. unsigned contentID)
  83. {
  84. // Make sure not to use kNet internal message ID's
  85. if (msgID <= 0x4 || msgID >= 0x3ffffffe)
  86. {
  87. LOGERROR("Can not send message with reserved ID");
  88. return;
  89. }
  90. if (numBytes && !data)
  91. {
  92. LOGERROR("Null pointer supplied for network message data");
  93. return;
  94. }
  95. kNet::NetworkMessage* msg = connection_->StartNewMessage((unsigned long)msgID, numBytes);
  96. if (!msg)
  97. {
  98. LOGERROR("Can not start new network message");
  99. return;
  100. }
  101. msg->reliable = reliable;
  102. msg->inOrder = inOrder;
  103. msg->priority = 0;
  104. msg->contentID = contentID;
  105. if (numBytes)
  106. memcpy(msg->data, data, numBytes);
  107. connection_->EndAndQueueMessage(msg);
  108. }
  109. void Connection::SendRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData)
  110. {
  111. RemoteEvent queuedEvent;
  112. queuedEvent.senderID_ = 0;
  113. queuedEvent.eventType_ = eventType;
  114. queuedEvent.eventData_ = eventData;
  115. queuedEvent.inOrder_ = inOrder;
  116. remoteEvents_.Push(queuedEvent);
  117. }
  118. void Connection::SendRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData)
  119. {
  120. if (!node)
  121. {
  122. LOGERROR("Null sender node for remote node event");
  123. return;
  124. }
  125. if (node->GetScene() != scene_)
  126. {
  127. LOGERROR("Sender node is not in the connection's scene, can not send remote node event");
  128. return;
  129. }
  130. if (node->GetID() >= FIRST_LOCAL_ID)
  131. {
  132. LOGERROR("Sender node has a local ID, can not send remote node event");
  133. return;
  134. }
  135. RemoteEvent queuedEvent;
  136. queuedEvent.senderID_ = node->GetID();
  137. queuedEvent.eventType_ = eventType;
  138. queuedEvent.eventData_ = eventData;
  139. queuedEvent.inOrder_ = inOrder;
  140. remoteEvents_.Push(queuedEvent);
  141. }
  142. void Connection::SetScene(Scene* newScene)
  143. {
  144. if (scene_)
  145. {
  146. // Remove replication states and owner references from the previous scene
  147. scene_->CleanupConnection(this);
  148. }
  149. scene_ = newScene;
  150. sceneLoaded_ = false;
  151. UnsubscribeFromEvent(E_ASYNCLOADFINISHED);
  152. if (!scene_)
  153. return;
  154. if (isClient_)
  155. {
  156. sceneState_.Clear();
  157. // When scene is assigned on the server, instruct the client to load it. This may require downloading packages
  158. const Vector<SharedPtr<PackageFile> >& packages = scene_->GetRequiredPackageFiles();
  159. unsigned numPackages = packages.Size();
  160. msg_.Clear();
  161. msg_.WriteString(scene_->GetFileName());
  162. msg_.WriteVLE(numPackages);
  163. for (unsigned i = 0; i < numPackages; ++i)
  164. {
  165. PackageFile* package = packages[i];
  166. msg_.WriteString(GetFileNameAndExtension(package->GetName()));
  167. msg_.WriteUInt(package->GetTotalSize());
  168. msg_.WriteUInt(package->GetChecksum());
  169. }
  170. SendMessage(MSG_LOADSCENE, true, true, msg_);
  171. }
  172. else
  173. {
  174. // Make sure there is no existing async loading
  175. scene_->StopAsyncLoading();
  176. SubscribeToEvent(scene_, E_ASYNCLOADFINISHED, URHO3D_HANDLER(Connection, HandleAsyncLoadFinished));
  177. }
  178. }
  179. void Connection::SetIdentity(const VariantMap& identity)
  180. {
  181. identity_ = identity;
  182. }
  183. void Connection::SetControls(const Controls& newControls)
  184. {
  185. controls_ = newControls;
  186. }
  187. void Connection::SetPosition(const Vector3& position)
  188. {
  189. position_ = position;
  190. if (sendMode_ == OPSM_NONE)
  191. sendMode_ = OPSM_POSITION;
  192. }
  193. void Connection::SetRotation(const Quaternion& rotation)
  194. {
  195. rotation_ = rotation;
  196. if (sendMode_ != OPSM_POSITION_ROTATION)
  197. sendMode_ = OPSM_POSITION_ROTATION;
  198. }
  199. void Connection::SetConnectPending(bool connectPending)
  200. {
  201. connectPending_ = connectPending;
  202. }
  203. void Connection::SetLogStatistics(bool enable)
  204. {
  205. logStatistics_ = enable;
  206. }
  207. void Connection::Disconnect(int waitMSec)
  208. {
  209. connection_->Disconnect(waitMSec);
  210. }
  211. void Connection::SendServerUpdate()
  212. {
  213. if (!scene_ || !sceneLoaded_)
  214. return;
  215. // Always check the root node (scene) first so that the scene-wide components get sent first,
  216. // and all other replicated nodes get added to the dirty set for sending the initial state
  217. unsigned sceneID = scene_->GetID();
  218. nodesToProcess_.Insert(sceneID);
  219. ProcessNode(sceneID);
  220. // Then go through all dirtied nodes
  221. nodesToProcess_.Insert(sceneState_.dirtyNodes_);
  222. nodesToProcess_.Erase(sceneID); // Do not process the root node twice
  223. while (nodesToProcess_.Size())
  224. {
  225. unsigned nodeID = nodesToProcess_.Front();
  226. ProcessNode(nodeID);
  227. }
  228. }
  229. void Connection::SendClientUpdate()
  230. {
  231. if (!scene_ || !sceneLoaded_)
  232. return;
  233. msg_.Clear();
  234. msg_.WriteUInt(controls_.buttons_);
  235. msg_.WriteFloat(controls_.yaw_);
  236. msg_.WriteFloat(controls_.pitch_);
  237. msg_.WriteVariantMap(controls_.extraData_);
  238. msg_.WriteUByte(timeStamp_);
  239. if (sendMode_ >= OPSM_POSITION)
  240. msg_.WriteVector3(position_);
  241. if (sendMode_ >= OPSM_POSITION_ROTATION)
  242. msg_.WritePackedQuaternion(rotation_);
  243. SendMessage(MSG_CONTROLS, false, false, msg_, CONTROLS_CONTENT_ID);
  244. ++timeStamp_;
  245. }
  246. void Connection::SendRemoteEvents()
  247. {
  248. #ifdef URHO3D_LOGGING
  249. if (logStatistics_ && statsTimer_.GetMSec(false) > STATS_INTERVAL_MSEC)
  250. {
  251. statsTimer_.Reset();
  252. char statsBuffer[256];
  253. sprintf(statsBuffer, "RTT %.3f ms Pkt in %d Pkt out %d Data in %.3f KB/s Data out %.3f KB/s", connection_->RoundTripTime(),
  254. (int)connection_->PacketsInPerSec(),
  255. (int)connection_->PacketsOutPerSec(), connection_->BytesInPerSec() / 1000.0f, connection_->BytesOutPerSec() / 1000.0f);
  256. LOGINFO(statsBuffer);
  257. }
  258. #endif
  259. if (remoteEvents_.Empty())
  260. return;
  261. PROFILE(SendRemoteEvents);
  262. for (Vector<RemoteEvent>::ConstIterator i = remoteEvents_.Begin(); i != remoteEvents_.End(); ++i)
  263. {
  264. msg_.Clear();
  265. if (!i->senderID_)
  266. {
  267. msg_.WriteStringHash(i->eventType_);
  268. msg_.WriteVariantMap(i->eventData_);
  269. SendMessage(MSG_REMOTEEVENT, true, i->inOrder_, msg_);
  270. }
  271. else
  272. {
  273. msg_.WriteNetID(i->senderID_);
  274. msg_.WriteStringHash(i->eventType_);
  275. msg_.WriteVariantMap(i->eventData_);
  276. SendMessage(MSG_REMOTENODEEVENT, true, i->inOrder_, msg_);
  277. }
  278. }
  279. remoteEvents_.Clear();
  280. }
  281. void Connection::SendPackages()
  282. {
  283. while (!uploads_.Empty() && connection_->NumOutboundMessagesPending() < 1000)
  284. {
  285. unsigned char buffer[PACKAGE_FRAGMENT_SIZE];
  286. for (HashMap<StringHash, PackageUpload>::Iterator i = uploads_.Begin(); i != uploads_.End();)
  287. {
  288. HashMap<StringHash, PackageUpload>::Iterator current = i++;
  289. PackageUpload& upload = current->second_;
  290. unsigned fragmentSize =
  291. (unsigned)Min((int)(upload.file_->GetSize() - upload.file_->GetPosition()), (int)PACKAGE_FRAGMENT_SIZE);
  292. upload.file_->Read(buffer, fragmentSize);
  293. msg_.Clear();
  294. msg_.WriteStringHash(current->first_);
  295. msg_.WriteUInt(upload.fragment_++);
  296. msg_.Write(buffer, fragmentSize);
  297. SendMessage(MSG_PACKAGEDATA, true, false, msg_);
  298. // Check if upload finished
  299. if (upload.fragment_ == upload.totalFragments_)
  300. uploads_.Erase(current);
  301. }
  302. }
  303. }
  304. void Connection::ProcessPendingLatestData()
  305. {
  306. if (!scene_ || !sceneLoaded_)
  307. return;
  308. // Iterate through pending node data and see if we can find the nodes now
  309. for (HashMap<unsigned, PODVector<unsigned char> >::Iterator i = nodeLatestData_.Begin(); i != nodeLatestData_.End();)
  310. {
  311. HashMap<unsigned, PODVector<unsigned char> >::Iterator current = i++;
  312. Node* node = scene_->GetNode(current->first_);
  313. if (node)
  314. {
  315. MemoryBuffer msg(current->second_);
  316. msg.ReadNetID(); // Skip the node ID
  317. node->ReadLatestDataUpdate(msg);
  318. // ApplyAttributes() is deliberately skipped, as Node has no attributes that require late applying.
  319. // Furthermore it would propagate to components and child nodes, which is not desired in this case
  320. nodeLatestData_.Erase(current);
  321. }
  322. }
  323. // Iterate through pending component data and see if we can find the components now
  324. for (HashMap<unsigned, PODVector<unsigned char> >::Iterator i = componentLatestData_.Begin(); i != componentLatestData_.End();)
  325. {
  326. HashMap<unsigned, PODVector<unsigned char> >::Iterator current = i++;
  327. Component* component = scene_->GetComponent(current->first_);
  328. if (component)
  329. {
  330. MemoryBuffer msg(current->second_);
  331. msg.ReadNetID(); // Skip the component ID
  332. if (component->ReadLatestDataUpdate(msg))
  333. component->ApplyAttributes();
  334. componentLatestData_.Erase(current);
  335. }
  336. }
  337. }
  338. bool Connection::ProcessMessage(int msgID, MemoryBuffer& msg)
  339. {
  340. bool processed = true;
  341. switch (msgID)
  342. {
  343. case MSG_IDENTITY:
  344. ProcessIdentity(msgID, msg);
  345. break;
  346. case MSG_CONTROLS:
  347. ProcessControls(msgID, msg);
  348. break;
  349. case MSG_SCENELOADED:
  350. ProcessSceneLoaded(msgID, msg);
  351. break;
  352. case MSG_REQUESTPACKAGE:
  353. case MSG_PACKAGEDATA:
  354. ProcessPackageDownload(msgID, msg);
  355. break;
  356. case MSG_LOADSCENE:
  357. ProcessLoadScene(msgID, msg);
  358. break;
  359. case MSG_SCENECHECKSUMERROR:
  360. ProcessSceneChecksumError(msgID, msg);
  361. break;
  362. case MSG_CREATENODE:
  363. case MSG_NODEDELTAUPDATE:
  364. case MSG_NODELATESTDATA:
  365. case MSG_REMOVENODE:
  366. case MSG_CREATECOMPONENT:
  367. case MSG_COMPONENTDELTAUPDATE:
  368. case MSG_COMPONENTLATESTDATA:
  369. case MSG_REMOVECOMPONENT:
  370. ProcessSceneUpdate(msgID, msg);
  371. break;
  372. case MSG_REMOTEEVENT:
  373. case MSG_REMOTENODEEVENT:
  374. ProcessRemoteEvent(msgID, msg);
  375. break;
  376. case MSG_PACKAGEINFO:
  377. ProcessPackageInfo(msgID, msg);
  378. break;
  379. default:
  380. processed = false;
  381. break;
  382. }
  383. return processed;
  384. }
  385. void Connection::ProcessLoadScene(int msgID, MemoryBuffer& msg)
  386. {
  387. if (IsClient())
  388. {
  389. LOGWARNING("Received unexpected LoadScene message from client " + ToString());
  390. return;
  391. }
  392. if (!scene_)
  393. {
  394. LOGERROR("Can not handle LoadScene message without an assigned scene");
  395. return;
  396. }
  397. // Store the scene file name we need to eventually load
  398. sceneFileName_ = msg.ReadString();
  399. // Clear previous pending latest data and package downloads if any
  400. nodeLatestData_.Clear();
  401. componentLatestData_.Clear();
  402. downloads_.Clear();
  403. // In case we have joined other scenes in this session, remove first all downloaded package files from the resource system
  404. // to prevent resource conflicts
  405. ResourceCache* cache = GetSubsystem<ResourceCache>();
  406. const String& packageCacheDir = GetSubsystem<Network>()->GetPackageCacheDir();
  407. Vector<SharedPtr<PackageFile> > packages = cache->GetPackageFiles();
  408. for (unsigned i = 0; i < packages.Size(); ++i)
  409. {
  410. PackageFile* package = packages[i];
  411. if (!package->GetName().Find(packageCacheDir))
  412. cache->RemovePackageFile(package, true);
  413. }
  414. // Now check which packages we have in the resource cache or in the download cache, and which we need to download
  415. unsigned numPackages = msg.ReadVLE();
  416. if (!RequestNeededPackages(numPackages, msg))
  417. {
  418. OnSceneLoadFailed();
  419. return;
  420. }
  421. // If no downloads were queued, can load the scene directly
  422. if (downloads_.Empty())
  423. OnPackagesReady();
  424. }
  425. void Connection::ProcessSceneChecksumError(int msgID, MemoryBuffer& msg)
  426. {
  427. if (IsClient())
  428. {
  429. LOGWARNING("Received unexpected SceneChecksumError message from client " + ToString());
  430. return;
  431. }
  432. LOGERROR("Scene checksum error");
  433. OnSceneLoadFailed();
  434. }
  435. void Connection::ProcessSceneUpdate(int msgID, MemoryBuffer& msg)
  436. {
  437. /// \todo On mobile devices processing this message may potentially cause a crash if it attempts to load new GPU resources
  438. /// while the application is minimized
  439. if (IsClient())
  440. {
  441. LOGWARNING("Received unexpected SceneUpdate message from client " + ToString());
  442. return;
  443. }
  444. if (!scene_)
  445. return;
  446. switch (msgID)
  447. {
  448. case MSG_CREATENODE:
  449. {
  450. unsigned nodeID = msg.ReadNetID();
  451. // In case of the root node (scene), it should already exist. Do not create in that case
  452. Node* node = scene_->GetNode(nodeID);
  453. if (!node)
  454. {
  455. // Add initially to the root level. May be moved as we receive the parent attribute
  456. node = scene_->CreateChild(nodeID, REPLICATED);
  457. // Create smoothed transform component
  458. node->CreateComponent<SmoothedTransform>(LOCAL);
  459. }
  460. // Read initial attributes, then snap the motion smoothing immediately to the end
  461. node->ReadDeltaUpdate(msg);
  462. SmoothedTransform* transform = node->GetComponent<SmoothedTransform>();
  463. if (transform)
  464. transform->Update(1.0f, 0.0f);
  465. // Read initial user variables
  466. unsigned numVars = msg.ReadVLE();
  467. while (numVars)
  468. {
  469. StringHash key = msg.ReadStringHash();
  470. node->SetVar(key, msg.ReadVariant());
  471. --numVars;
  472. }
  473. // Read components
  474. unsigned numComponents = msg.ReadVLE();
  475. while (numComponents)
  476. {
  477. --numComponents;
  478. StringHash type = msg.ReadStringHash();
  479. unsigned componentID = msg.ReadNetID();
  480. // Check if the component by this ID and type already exists in this node
  481. Component* component = scene_->GetComponent(componentID);
  482. if (!component || component->GetType() != type || component->GetNode() != node)
  483. {
  484. if (component)
  485. component->Remove();
  486. component = node->CreateComponent(type, REPLICATED, componentID);
  487. }
  488. // If was unable to create the component, would desync the message and therefore have to abort
  489. if (!component)
  490. {
  491. LOGERROR("CreateNode message parsing aborted due to unknown component");
  492. return;
  493. }
  494. // Read initial attributes and apply
  495. component->ReadDeltaUpdate(msg);
  496. component->ApplyAttributes();
  497. }
  498. }
  499. break;
  500. case MSG_NODEDELTAUPDATE:
  501. {
  502. unsigned nodeID = msg.ReadNetID();
  503. Node* node = scene_->GetNode(nodeID);
  504. if (node)
  505. {
  506. node->ReadDeltaUpdate(msg);
  507. // ApplyAttributes() is deliberately skipped, as Node has no attributes that require late applying.
  508. // Furthermore it would propagate to components and child nodes, which is not desired in this case
  509. unsigned changedVars = msg.ReadVLE();
  510. while (changedVars)
  511. {
  512. StringHash key = msg.ReadStringHash();
  513. node->SetVar(key, msg.ReadVariant());
  514. --changedVars;
  515. }
  516. }
  517. else
  518. LOGWARNING("NodeDeltaUpdate message received for missing node " + String(nodeID));
  519. }
  520. break;
  521. case MSG_NODELATESTDATA:
  522. {
  523. unsigned nodeID = msg.ReadNetID();
  524. Node* node = scene_->GetNode(nodeID);
  525. if (node)
  526. {
  527. node->ReadLatestDataUpdate(msg);
  528. // ApplyAttributes() is deliberately skipped, as Node has no attributes that require late applying.
  529. // Furthermore it would propagate to components and child nodes, which is not desired in this case
  530. }
  531. else
  532. {
  533. // Latest data messages may be received out-of-order relative to node creation, so cache if necessary
  534. PODVector<unsigned char>& data = nodeLatestData_[nodeID];
  535. data.Resize(msg.GetSize());
  536. memcpy(&data[0], msg.GetData(), msg.GetSize());
  537. }
  538. }
  539. break;
  540. case MSG_REMOVENODE:
  541. {
  542. unsigned nodeID = msg.ReadNetID();
  543. Node* node = scene_->GetNode(nodeID);
  544. if (node)
  545. node->Remove();
  546. nodeLatestData_.Erase(nodeID);
  547. }
  548. break;
  549. case MSG_CREATECOMPONENT:
  550. {
  551. unsigned nodeID = msg.ReadNetID();
  552. Node* node = scene_->GetNode(nodeID);
  553. if (node)
  554. {
  555. StringHash type = msg.ReadStringHash();
  556. unsigned componentID = msg.ReadNetID();
  557. // Check if the component by this ID and type already exists in this node
  558. Component* component = scene_->GetComponent(componentID);
  559. if (!component || component->GetType() != type || component->GetNode() != node)
  560. {
  561. if (component)
  562. component->Remove();
  563. component = node->CreateComponent(type, REPLICATED, componentID);
  564. }
  565. // If was unable to create the component, would desync the message and therefore have to abort
  566. if (!component)
  567. {
  568. LOGERROR("CreateComponent message parsing aborted due to unknown component");
  569. return;
  570. }
  571. // Read initial attributes and apply
  572. component->ReadDeltaUpdate(msg);
  573. component->ApplyAttributes();
  574. }
  575. else
  576. LOGWARNING("CreateComponent message received for missing node " + String(nodeID));
  577. }
  578. break;
  579. case MSG_COMPONENTDELTAUPDATE:
  580. {
  581. unsigned componentID = msg.ReadNetID();
  582. Component* component = scene_->GetComponent(componentID);
  583. if (component)
  584. {
  585. component->ReadDeltaUpdate(msg);
  586. component->ApplyAttributes();
  587. }
  588. else
  589. LOGWARNING("ComponentDeltaUpdate message received for missing component " + String(componentID));
  590. }
  591. break;
  592. case MSG_COMPONENTLATESTDATA:
  593. {
  594. unsigned componentID = msg.ReadNetID();
  595. Component* component = scene_->GetComponent(componentID);
  596. if (component)
  597. {
  598. if (component->ReadLatestDataUpdate(msg))
  599. component->ApplyAttributes();
  600. }
  601. else
  602. {
  603. // Latest data messages may be received out-of-order relative to component creation, so cache if necessary
  604. PODVector<unsigned char>& data = componentLatestData_[componentID];
  605. data.Resize(msg.GetSize());
  606. memcpy(&data[0], msg.GetData(), msg.GetSize());
  607. }
  608. }
  609. break;
  610. case MSG_REMOVECOMPONENT:
  611. {
  612. unsigned componentID = msg.ReadNetID();
  613. Component* component = scene_->GetComponent(componentID);
  614. if (component)
  615. component->Remove();
  616. componentLatestData_.Erase(componentID);
  617. }
  618. break;
  619. default: break;
  620. }
  621. }
  622. void Connection::ProcessPackageDownload(int msgID, MemoryBuffer& msg)
  623. {
  624. switch (msgID)
  625. {
  626. case MSG_REQUESTPACKAGE:
  627. if (!IsClient())
  628. {
  629. LOGWARNING("Received unexpected RequestPackage message from server");
  630. return;
  631. }
  632. else
  633. {
  634. String name = msg.ReadString();
  635. if (!scene_)
  636. {
  637. LOGWARNING("Received a RequestPackage message without an assigned scene from client " + ToString());
  638. return;
  639. }
  640. // The package must be one of those required by the scene
  641. const Vector<SharedPtr<PackageFile> >& packages = scene_->GetRequiredPackageFiles();
  642. for (unsigned i = 0; i < packages.Size(); ++i)
  643. {
  644. PackageFile* package = packages[i];
  645. String packageFullName = package->GetName();
  646. if (!GetFileNameAndExtension(packageFullName).Compare(name, false))
  647. {
  648. StringHash nameHash(name);
  649. // Do not restart upload if already exists
  650. if (uploads_.Contains(nameHash))
  651. {
  652. LOGWARNING("Received a request for package " + name + " already in transfer");
  653. return;
  654. }
  655. // Try to open the file now
  656. SharedPtr<File> file(new File(context_, packageFullName));
  657. if (!file->IsOpen())
  658. {
  659. LOGERROR("Failed to transmit package file " + name);
  660. SendPackageError(name);
  661. return;
  662. }
  663. LOGINFO("Transmitting package file " + name + " to client " + ToString());
  664. uploads_[nameHash].file_ = file;
  665. uploads_[nameHash].fragment_ = 0;
  666. uploads_[nameHash].totalFragments_ = (file->GetSize() + PACKAGE_FRAGMENT_SIZE - 1) / PACKAGE_FRAGMENT_SIZE;
  667. return;
  668. }
  669. }
  670. LOGERROR("Client requested an unexpected package file " + name);
  671. // Send the name hash only to indicate a failed download
  672. SendPackageError(name);
  673. return;
  674. }
  675. break;
  676. case MSG_PACKAGEDATA:
  677. if (IsClient())
  678. {
  679. LOGWARNING("Received unexpected PackageData message from client");
  680. return;
  681. }
  682. else
  683. {
  684. StringHash nameHash = msg.ReadStringHash();
  685. HashMap<StringHash, PackageDownload>::Iterator i = downloads_.Find(nameHash);
  686. // In case of being unable to create the package file into the cache, we will still receive all data from the server.
  687. // Simply disregard it
  688. if (i == downloads_.End())
  689. return;
  690. PackageDownload& download = i->second_;
  691. // If no further data, this is an error reply
  692. if (msg.IsEof())
  693. {
  694. OnPackageDownloadFailed(download.name_);
  695. return;
  696. }
  697. // If file has not yet been opened, try to open now. Prepend the checksum to the filename to allow multiple versions
  698. if (!download.file_)
  699. {
  700. download.file_ = new File(context_,
  701. GetSubsystem<Network>()->GetPackageCacheDir() + ToStringHex(download.checksum_) + "_" + download.name_,
  702. FILE_WRITE);
  703. if (!download.file_->IsOpen())
  704. {
  705. OnPackageDownloadFailed(download.name_);
  706. return;
  707. }
  708. }
  709. // Write the fragment data to the proper index
  710. unsigned char buffer[PACKAGE_FRAGMENT_SIZE];
  711. unsigned index = msg.ReadUInt();
  712. unsigned fragmentSize = msg.GetSize() - msg.GetPosition();
  713. msg.Read(buffer, fragmentSize);
  714. download.file_->Seek(index * PACKAGE_FRAGMENT_SIZE);
  715. download.file_->Write(buffer, fragmentSize);
  716. download.receivedFragments_.Insert(index);
  717. // Check if all fragments received
  718. if (download.receivedFragments_.Size() == download.totalFragments_)
  719. {
  720. LOGINFO("Package " + download.name_ + " downloaded successfully");
  721. // Instantiate the package and add to the resource system, as we will need it to load the scene
  722. download.file_->Close();
  723. GetSubsystem<ResourceCache>()->AddPackageFile(download.file_->GetName(), 0);
  724. // Then start the next download if there are more
  725. downloads_.Erase(i);
  726. if (downloads_.Empty())
  727. OnPackagesReady();
  728. else
  729. {
  730. PackageDownload& nextDownload = downloads_.Begin()->second_;
  731. LOGINFO("Requesting package " + nextDownload.name_ + " from server");
  732. msg_.Clear();
  733. msg_.WriteString(nextDownload.name_);
  734. SendMessage(MSG_REQUESTPACKAGE, true, true, msg_);
  735. nextDownload.initiated_ = true;
  736. }
  737. }
  738. }
  739. break;
  740. default: break;
  741. }
  742. }
  743. void Connection::ProcessIdentity(int msgID, MemoryBuffer& msg)
  744. {
  745. if (!IsClient())
  746. {
  747. LOGWARNING("Received unexpected Identity message from server");
  748. return;
  749. }
  750. identity_ = msg.ReadVariantMap();
  751. using namespace ClientIdentity;
  752. VariantMap eventData = identity_;
  753. eventData[P_CONNECTION] = this;
  754. eventData[P_ALLOW] = true;
  755. SendEvent(E_CLIENTIDENTITY, eventData);
  756. // If connection was denied as a response to the identity event, disconnect now
  757. if (!eventData[P_ALLOW].GetBool())
  758. Disconnect();
  759. }
  760. void Connection::ProcessControls(int msgID, MemoryBuffer& msg)
  761. {
  762. if (!IsClient())
  763. {
  764. LOGWARNING("Received unexpected Controls message from server");
  765. return;
  766. }
  767. Controls newControls;
  768. newControls.buttons_ = msg.ReadUInt();
  769. newControls.yaw_ = msg.ReadFloat();
  770. newControls.pitch_ = msg.ReadFloat();
  771. newControls.extraData_ = msg.ReadVariantMap();
  772. SetControls(newControls);
  773. timeStamp_ = msg.ReadUByte();
  774. // Client may or may not send observer position & rotation for interest management
  775. if (!msg.IsEof())
  776. position_ = msg.ReadVector3();
  777. if (!msg.IsEof())
  778. rotation_ = msg.ReadPackedQuaternion();
  779. }
  780. void Connection::ProcessSceneLoaded(int msgID, MemoryBuffer& msg)
  781. {
  782. if (!IsClient())
  783. {
  784. LOGWARNING("Received unexpected SceneLoaded message from server");
  785. return;
  786. }
  787. if (!scene_)
  788. {
  789. LOGWARNING("Received a SceneLoaded message without an assigned scene from client " + ToString());
  790. return;
  791. }
  792. unsigned checksum = msg.ReadUInt();
  793. if (checksum != scene_->GetChecksum())
  794. {
  795. LOGINFO("Scene checksum error from client " + ToString());
  796. msg_.Clear();
  797. SendMessage(MSG_SCENECHECKSUMERROR, true, true, msg_);
  798. OnSceneLoadFailed();
  799. }
  800. else
  801. {
  802. sceneLoaded_ = true;
  803. using namespace ClientSceneLoaded;
  804. VariantMap& eventData = GetEventDataMap();
  805. eventData[P_CONNECTION] = this;
  806. SendEvent(E_CLIENTSCENELOADED, eventData);
  807. }
  808. }
  809. void Connection::ProcessRemoteEvent(int msgID, MemoryBuffer& msg)
  810. {
  811. using namespace RemoteEventData;
  812. if (msgID == MSG_REMOTEEVENT)
  813. {
  814. StringHash eventType = msg.ReadStringHash();
  815. if (!GetSubsystem<Network>()->CheckRemoteEvent(eventType))
  816. {
  817. LOGWARNING("Discarding not allowed remote event " + eventType.ToString());
  818. return;
  819. }
  820. VariantMap eventData = msg.ReadVariantMap();
  821. eventData[P_CONNECTION] = this;
  822. SendEvent(eventType, eventData);
  823. }
  824. else
  825. {
  826. if (!scene_)
  827. {
  828. LOGERROR("Can not receive remote node event without an assigned scene");
  829. return;
  830. }
  831. unsigned nodeID = msg.ReadNetID();
  832. StringHash eventType = msg.ReadStringHash();
  833. if (!GetSubsystem<Network>()->CheckRemoteEvent(eventType))
  834. {
  835. LOGWARNING("Discarding not allowed remote event " + eventType.ToString());
  836. return;
  837. }
  838. VariantMap eventData = msg.ReadVariantMap();
  839. Node* sender = scene_->GetNode(nodeID);
  840. if (!sender)
  841. {
  842. LOGWARNING("Missing sender for remote node event, discarding");
  843. return;
  844. }
  845. eventData[P_CONNECTION] = this;
  846. sender->SendEvent(eventType, eventData);
  847. }
  848. }
  849. kNet::MessageConnection* Connection::GetMessageConnection() const
  850. {
  851. return const_cast<kNet::MessageConnection*>(connection_.ptr());
  852. }
  853. Scene* Connection::GetScene() const
  854. {
  855. return scene_;
  856. }
  857. bool Connection::IsConnected() const
  858. {
  859. return connection_->GetConnectionState() == kNet::ConnectionOK;
  860. }
  861. float Connection::GetRoundTripTime() const
  862. {
  863. return connection_->RoundTripTime();
  864. }
  865. float Connection::GetLastHeardTime() const
  866. {
  867. return connection_->LastHeardTime();
  868. }
  869. float Connection::GetBytesInPerSec() const
  870. {
  871. return connection_->BytesInPerSec();
  872. }
  873. float Connection::GetBytesOutPerSec() const
  874. {
  875. return connection_->BytesOutPerSec();
  876. }
  877. float Connection::GetPacketsInPerSec() const
  878. {
  879. return connection_->PacketsInPerSec();
  880. }
  881. float Connection::GetPacketsOutPerSec() const
  882. {
  883. return connection_->PacketsOutPerSec();
  884. }
  885. String Connection::ToString() const
  886. {
  887. return GetAddress() + ":" + String(GetPort());
  888. }
  889. unsigned Connection::GetNumDownloads() const
  890. {
  891. return downloads_.Size();
  892. }
  893. const String& Connection::GetDownloadName() const
  894. {
  895. for (HashMap<StringHash, PackageDownload>::ConstIterator i = downloads_.Begin(); i != downloads_.End(); ++i)
  896. {
  897. if (i->second_.initiated_)
  898. return i->second_.name_;
  899. }
  900. return String::EMPTY;
  901. }
  902. float Connection::GetDownloadProgress() const
  903. {
  904. for (HashMap<StringHash, PackageDownload>::ConstIterator i = downloads_.Begin(); i != downloads_.End(); ++i)
  905. {
  906. if (i->second_.initiated_)
  907. return (float)i->second_.receivedFragments_.Size() / (float)i->second_.totalFragments_;
  908. }
  909. return 1.0f;
  910. }
  911. void Connection::SendPackageToClient(PackageFile* package)
  912. {
  913. if (!scene_)
  914. return;
  915. if (!IsClient())
  916. {
  917. LOGERROR("SendPackageToClient can be called on the server only");
  918. return;
  919. }
  920. if (!package)
  921. {
  922. LOGERROR("Null package specified for SendPackageToClient");
  923. return;
  924. }
  925. msg_.Clear();
  926. String filename = GetFileNameAndExtension(package->GetName());
  927. msg_.WriteString(filename);
  928. msg_.WriteUInt(package->GetTotalSize());
  929. msg_.WriteUInt(package->GetChecksum());
  930. SendMessage(MSG_PACKAGEINFO, true, true, msg_);
  931. }
  932. void Connection::ConfigureNetworkSimulator(int latencyMs, float packetLoss)
  933. {
  934. if (connection_)
  935. {
  936. kNet::NetworkSimulator& simulator = connection_->NetworkSendSimulator();
  937. simulator.enabled = latencyMs > 0 || packetLoss > 0.0f;
  938. simulator.constantPacketSendDelay = (float)latencyMs;
  939. simulator.packetLossRate = packetLoss;
  940. }
  941. }
  942. void Connection::HandleAsyncLoadFinished(StringHash eventType, VariantMap& eventData)
  943. {
  944. sceneLoaded_ = true;
  945. msg_.Clear();
  946. msg_.WriteUInt(scene_->GetChecksum());
  947. SendMessage(MSG_SCENELOADED, true, true, msg_);
  948. }
  949. void Connection::ProcessNode(unsigned nodeID)
  950. {
  951. // Check that we have not already processed this due to dependency recursion
  952. if (!nodesToProcess_.Erase(nodeID))
  953. return;
  954. // Find replication state for the node
  955. HashMap<unsigned, NodeReplicationState>::Iterator i = sceneState_.nodeStates_.Find(nodeID);
  956. if (i != sceneState_.nodeStates_.End())
  957. {
  958. // Replication state found: the node is either be existing or removed
  959. Node* node = i->second_.node_;
  960. if (!node)
  961. {
  962. msg_.Clear();
  963. msg_.WriteNetID(nodeID);
  964. // Note: we will send MSG_REMOVENODE redundantly for each node in the hierarchy, even if removing the root node
  965. // would be enough. However, this may be better due to the client not possibly having updated parenting
  966. // information at the time of receiving this message
  967. SendMessage(MSG_REMOVENODE, true, true, msg_);
  968. sceneState_.nodeStates_.Erase(nodeID);
  969. }
  970. else
  971. ProcessExistingNode(node, i->second_);
  972. }
  973. else
  974. {
  975. // Replication state not found: this is a new node
  976. Node* node = scene_->GetNode(nodeID);
  977. if (node)
  978. ProcessNewNode(node);
  979. else
  980. {
  981. // Did not find the new node (may have been created, then removed immediately): erase from dirty set.
  982. sceneState_.dirtyNodes_.Erase(nodeID);
  983. }
  984. }
  985. }
  986. void Connection::ProcessNewNode(Node* node)
  987. {
  988. // Process depended upon nodes first, if they are dirty
  989. const PODVector<Node*>& dependencyNodes = node->GetDependencyNodes();
  990. for (PODVector<Node*>::ConstIterator i = dependencyNodes.Begin(); i != dependencyNodes.End(); ++i)
  991. {
  992. unsigned nodeID = (*i)->GetID();
  993. if (sceneState_.dirtyNodes_.Contains(nodeID))
  994. ProcessNode(nodeID);
  995. }
  996. msg_.Clear();
  997. msg_.WriteNetID(node->GetID());
  998. NodeReplicationState& nodeState = sceneState_.nodeStates_[node->GetID()];
  999. nodeState.connection_ = this;
  1000. nodeState.sceneState_ = &sceneState_;
  1001. nodeState.node_ = node;
  1002. node->AddReplicationState(&nodeState);
  1003. // Write node's attributes
  1004. node->WriteInitialDeltaUpdate(msg_, timeStamp_);
  1005. // Write node's user variables
  1006. const VariantMap& vars = node->GetVars();
  1007. msg_.WriteVLE(vars.Size());
  1008. for (VariantMap::ConstIterator i = vars.Begin(); i != vars.End(); ++i)
  1009. {
  1010. msg_.WriteStringHash(i->first_);
  1011. msg_.WriteVariant(i->second_);
  1012. }
  1013. // Write node's components
  1014. msg_.WriteVLE(node->GetNumNetworkComponents());
  1015. const Vector<SharedPtr<Component> >& components = node->GetComponents();
  1016. for (unsigned i = 0; i < components.Size(); ++i)
  1017. {
  1018. Component* component = components[i];
  1019. // Check if component is not to be replicated
  1020. if (component->GetID() >= FIRST_LOCAL_ID)
  1021. continue;
  1022. ComponentReplicationState& componentState = nodeState.componentStates_[component->GetID()];
  1023. componentState.connection_ = this;
  1024. componentState.nodeState_ = &nodeState;
  1025. componentState.component_ = component;
  1026. component->AddReplicationState(&componentState);
  1027. msg_.WriteStringHash(component->GetType());
  1028. msg_.WriteNetID(component->GetID());
  1029. component->WriteInitialDeltaUpdate(msg_, timeStamp_);
  1030. }
  1031. SendMessage(MSG_CREATENODE, true, true, msg_);
  1032. nodeState.markedDirty_ = false;
  1033. sceneState_.dirtyNodes_.Erase(node->GetID());
  1034. }
  1035. void Connection::ProcessExistingNode(Node* node, NodeReplicationState& nodeState)
  1036. {
  1037. // Process depended upon nodes first, if they are dirty
  1038. const PODVector<Node*>& dependencyNodes = node->GetDependencyNodes();
  1039. for (PODVector<Node*>::ConstIterator i = dependencyNodes.Begin(); i != dependencyNodes.End(); ++i)
  1040. {
  1041. unsigned nodeID = (*i)->GetID();
  1042. if (sceneState_.dirtyNodes_.Contains(nodeID))
  1043. ProcessNode(nodeID);
  1044. }
  1045. // Check from the interest management component, if exists, whether should update
  1046. /// \todo Searching for the component is a potential CPU hotspot. It should be cached
  1047. NetworkPriority* priority = node->GetComponent<NetworkPriority>();
  1048. if (priority && (!priority->GetAlwaysUpdateOwner() || node->GetOwner() != this))
  1049. {
  1050. float distance = (node->GetWorldPosition() - position_).Length();
  1051. if (!priority->CheckUpdate(distance, nodeState.priorityAcc_))
  1052. return;
  1053. }
  1054. // Check if attributes have changed
  1055. if (nodeState.dirtyAttributes_.Count() || nodeState.dirtyVars_.Size())
  1056. {
  1057. const Vector<AttributeInfo>* attributes = node->GetNetworkAttributes();
  1058. unsigned numAttributes = attributes->Size();
  1059. bool hasLatestData = false;
  1060. for (unsigned i = 0; i < numAttributes; ++i)
  1061. {
  1062. if (nodeState.dirtyAttributes_.IsSet(i) && (attributes->At(i).mode_ & AM_LATESTDATA))
  1063. {
  1064. hasLatestData = true;
  1065. nodeState.dirtyAttributes_.Clear(i);
  1066. }
  1067. }
  1068. // Send latestdata message if necessary
  1069. if (hasLatestData)
  1070. {
  1071. msg_.Clear();
  1072. msg_.WriteNetID(node->GetID());
  1073. node->WriteLatestDataUpdate(msg_, timeStamp_);
  1074. SendMessage(MSG_NODELATESTDATA, true, false, msg_, node->GetID());
  1075. }
  1076. // Send deltaupdate if remaining dirty bits, or vars have changed
  1077. if (nodeState.dirtyAttributes_.Count() || nodeState.dirtyVars_.Size())
  1078. {
  1079. msg_.Clear();
  1080. msg_.WriteNetID(node->GetID());
  1081. node->WriteDeltaUpdate(msg_, nodeState.dirtyAttributes_, timeStamp_);
  1082. // Write changed variables
  1083. msg_.WriteVLE(nodeState.dirtyVars_.Size());
  1084. const VariantMap& vars = node->GetVars();
  1085. for (HashSet<StringHash>::ConstIterator i = nodeState.dirtyVars_.Begin(); i != nodeState.dirtyVars_.End(); ++i)
  1086. {
  1087. VariantMap::ConstIterator j = vars.Find(*i);
  1088. if (j != vars.End())
  1089. {
  1090. msg_.WriteStringHash(j->first_);
  1091. msg_.WriteVariant(j->second_);
  1092. }
  1093. else
  1094. {
  1095. // Variable has been marked dirty, but is removed (which is unsupported): send a dummy variable in place
  1096. LOGWARNING("Sending dummy user variable as original value was removed");
  1097. msg_.WriteStringHash(StringHash());
  1098. msg_.WriteVariant(Variant::EMPTY);
  1099. }
  1100. }
  1101. SendMessage(MSG_NODEDELTAUPDATE, true, true, msg_);
  1102. nodeState.dirtyAttributes_.ClearAll();
  1103. nodeState.dirtyVars_.Clear();
  1104. }
  1105. }
  1106. // Check for removed or changed components
  1107. for (HashMap<unsigned, ComponentReplicationState>::Iterator i = nodeState.componentStates_.Begin();
  1108. i != nodeState.componentStates_.End();)
  1109. {
  1110. HashMap<unsigned, ComponentReplicationState>::Iterator current = i++;
  1111. ComponentReplicationState& componentState = current->second_;
  1112. Component* component = componentState.component_;
  1113. if (!component)
  1114. {
  1115. // Removed component
  1116. msg_.Clear();
  1117. msg_.WriteNetID(current->first_);
  1118. SendMessage(MSG_REMOVECOMPONENT, true, true, msg_);
  1119. nodeState.componentStates_.Erase(current);
  1120. }
  1121. else
  1122. {
  1123. // Existing component. Check if attributes have changed
  1124. if (componentState.dirtyAttributes_.Count())
  1125. {
  1126. const Vector<AttributeInfo>* attributes = component->GetNetworkAttributes();
  1127. unsigned numAttributes = attributes->Size();
  1128. bool hasLatestData = false;
  1129. for (unsigned i = 0; i < numAttributes; ++i)
  1130. {
  1131. if (componentState.dirtyAttributes_.IsSet(i) && (attributes->At(i).mode_ & AM_LATESTDATA))
  1132. {
  1133. hasLatestData = true;
  1134. componentState.dirtyAttributes_.Clear(i);
  1135. }
  1136. }
  1137. // Send latestdata message if necessary
  1138. if (hasLatestData)
  1139. {
  1140. msg_.Clear();
  1141. msg_.WriteNetID(component->GetID());
  1142. component->WriteLatestDataUpdate(msg_, timeStamp_);
  1143. SendMessage(MSG_COMPONENTLATESTDATA, true, false, msg_, component->GetID());
  1144. }
  1145. // Send deltaupdate if remaining dirty bits
  1146. if (componentState.dirtyAttributes_.Count())
  1147. {
  1148. msg_.Clear();
  1149. msg_.WriteNetID(component->GetID());
  1150. component->WriteDeltaUpdate(msg_, componentState.dirtyAttributes_, timeStamp_);
  1151. SendMessage(MSG_COMPONENTDELTAUPDATE, true, true, msg_);
  1152. componentState.dirtyAttributes_.ClearAll();
  1153. }
  1154. }
  1155. }
  1156. }
  1157. // Check for new components
  1158. if (nodeState.componentStates_.Size() != node->GetNumNetworkComponents())
  1159. {
  1160. const Vector<SharedPtr<Component> >& components = node->GetComponents();
  1161. for (unsigned i = 0; i < components.Size(); ++i)
  1162. {
  1163. Component* component = components[i];
  1164. // Check if component is not to be replicated
  1165. if (component->GetID() >= FIRST_LOCAL_ID)
  1166. continue;
  1167. HashMap<unsigned, ComponentReplicationState>::Iterator j = nodeState.componentStates_.Find(component->GetID());
  1168. if (j == nodeState.componentStates_.End())
  1169. {
  1170. // New component
  1171. ComponentReplicationState& componentState = nodeState.componentStates_[component->GetID()];
  1172. componentState.connection_ = this;
  1173. componentState.nodeState_ = &nodeState;
  1174. componentState.component_ = component;
  1175. component->AddReplicationState(&componentState);
  1176. msg_.Clear();
  1177. msg_.WriteNetID(node->GetID());
  1178. msg_.WriteStringHash(component->GetType());
  1179. msg_.WriteNetID(component->GetID());
  1180. component->WriteInitialDeltaUpdate(msg_, timeStamp_);
  1181. SendMessage(MSG_CREATECOMPONENT, true, true, msg_);
  1182. }
  1183. }
  1184. }
  1185. nodeState.markedDirty_ = false;
  1186. sceneState_.dirtyNodes_.Erase(node->GetID());
  1187. }
  1188. bool Connection::RequestNeededPackages(unsigned numPackages, MemoryBuffer& msg)
  1189. {
  1190. ResourceCache* cache = GetSubsystem<ResourceCache>();
  1191. const String& packageCacheDir = GetSubsystem<Network>()->GetPackageCacheDir();
  1192. Vector<SharedPtr<PackageFile> > packages = cache->GetPackageFiles();
  1193. Vector<String> downloadedPackages;
  1194. bool packagesScanned = false;
  1195. for (unsigned i = 0; i < numPackages; ++i)
  1196. {
  1197. String name = msg.ReadString();
  1198. unsigned fileSize = msg.ReadUInt();
  1199. unsigned checksum = msg.ReadUInt();
  1200. String checksumString = ToStringHex(checksum);
  1201. bool found = false;
  1202. // Check first the resource cache
  1203. for (unsigned j = 0; j < packages.Size(); ++j)
  1204. {
  1205. PackageFile* package = packages[j];
  1206. if (!GetFileNameAndExtension(package->GetName()).Compare(name, false) && package->GetTotalSize() == fileSize &&
  1207. package->GetChecksum() == checksum)
  1208. {
  1209. found = true;
  1210. break;
  1211. }
  1212. }
  1213. if (found)
  1214. continue;
  1215. if (!packagesScanned)
  1216. {
  1217. if (packageCacheDir.Empty())
  1218. {
  1219. LOGERROR("Can not check/download required packages, as package cache directory is not set");
  1220. return false;
  1221. }
  1222. GetSubsystem<FileSystem>()->ScanDir(downloadedPackages, packageCacheDir, "*.*", SCAN_FILES, false);
  1223. packagesScanned = true;
  1224. }
  1225. // Then the download cache
  1226. for (unsigned j = 0; j < downloadedPackages.Size(); ++j)
  1227. {
  1228. const String& fileName = downloadedPackages[j];
  1229. // In download cache, package file name format is checksum_packagename
  1230. if (!fileName.Find(checksumString) && !fileName.Substring(9).Compare(name, false))
  1231. {
  1232. // Name matches. Check file size and actual checksum to be sure
  1233. SharedPtr<PackageFile> newPackage(new PackageFile(context_, packageCacheDir + fileName));
  1234. if (newPackage->GetTotalSize() == fileSize && newPackage->GetChecksum() == checksum)
  1235. {
  1236. // Add the package to the resource system now, as we will need it to load the scene
  1237. cache->AddPackageFile(newPackage, 0);
  1238. found = true;
  1239. break;
  1240. }
  1241. }
  1242. }
  1243. // Package not found, need to request a download
  1244. if (!found)
  1245. RequestPackage(name, fileSize, checksum);
  1246. }
  1247. return true;
  1248. }
  1249. void Connection::RequestPackage(const String& name, unsigned fileSize, unsigned checksum)
  1250. {
  1251. StringHash nameHash(name);
  1252. if (downloads_.Contains(nameHash))
  1253. return; // Download already exists
  1254. PackageDownload& download = downloads_[nameHash];
  1255. download.name_ = name;
  1256. download.totalFragments_ = (fileSize + PACKAGE_FRAGMENT_SIZE - 1) / PACKAGE_FRAGMENT_SIZE;
  1257. download.checksum_ = checksum;
  1258. // Start download now only if no existing downloads, else wait for the existing ones to finish
  1259. if (downloads_.Size() == 1)
  1260. {
  1261. LOGINFO("Requesting package " + name + " from server");
  1262. msg_.Clear();
  1263. msg_.WriteString(name);
  1264. SendMessage(MSG_REQUESTPACKAGE, true, true, msg_);
  1265. download.initiated_ = true;
  1266. }
  1267. }
  1268. void Connection::SendPackageError(const String& name)
  1269. {
  1270. msg_.Clear();
  1271. msg_.WriteStringHash(name);
  1272. SendMessage(MSG_PACKAGEDATA, true, false, msg_);
  1273. }
  1274. void Connection::OnSceneLoadFailed()
  1275. {
  1276. sceneLoaded_ = false;
  1277. using namespace NetworkSceneLoadFailed;
  1278. VariantMap& eventData = GetEventDataMap();
  1279. eventData[P_CONNECTION] = this;
  1280. SendEvent(E_NETWORKSCENELOADFAILED, eventData);
  1281. }
  1282. void Connection::OnPackageDownloadFailed(const String& name)
  1283. {
  1284. LOGERROR("Download of package " + name + " failed");
  1285. // As one package failed, we can not join the scene in any case. Clear the downloads
  1286. downloads_.Clear();
  1287. OnSceneLoadFailed();
  1288. }
  1289. void Connection::OnPackagesReady()
  1290. {
  1291. if (!scene_)
  1292. return;
  1293. // If sceneLoaded_ is true, we may have received additional package downloads while already joined in a scene.
  1294. // In that case the scene should not be loaded.
  1295. if (sceneLoaded_)
  1296. return;
  1297. if (sceneFileName_.Empty())
  1298. {
  1299. // If the scene filename is empty, just clear the scene of all existing replicated content, and send the loaded reply
  1300. scene_->Clear(true, false);
  1301. sceneLoaded_ = true;
  1302. msg_.Clear();
  1303. msg_.WriteUInt(scene_->GetChecksum());
  1304. SendMessage(MSG_SCENELOADED, true, true, msg_);
  1305. }
  1306. else
  1307. {
  1308. // Otherwise start the async loading process
  1309. String extension = GetExtension(sceneFileName_);
  1310. SharedPtr<File> file = GetSubsystem<ResourceCache>()->GetFile(sceneFileName_);
  1311. bool success;
  1312. if (extension == ".xml")
  1313. success = scene_->LoadAsyncXML(file);
  1314. else
  1315. success = scene_->LoadAsync(file);
  1316. if (!success)
  1317. OnSceneLoadFailed();
  1318. }
  1319. }
  1320. void Connection::ProcessPackageInfo(int msgID, MemoryBuffer& msg)
  1321. {
  1322. if (!scene_)
  1323. return;
  1324. if (IsClient())
  1325. {
  1326. LOGWARNING("Received unexpected packages info message from client");
  1327. return;
  1328. }
  1329. RequestNeededPackages(1, msg);
  1330. }
  1331. }