Client.cpp 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100
  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 "Client.h"
  25. #include "Connection.h"
  26. #include "Engine.h"
  27. #include "Log.h"
  28. #include "Network.h"
  29. #include "NetworkEvents.h"
  30. #include "Octree.h"
  31. #include "PackageFile.h"
  32. #include "PhysicsWorld.h"
  33. #include "ProcessUtils.h"
  34. #include "Profiler.h"
  35. #include "Protocol.h"
  36. #include "ProtocolEvents.h"
  37. #include "ReplicationUtils.h"
  38. #include "ResourceCache.h"
  39. #include "Scene.h"
  40. #include "SceneEvents.h"
  41. #include "StringUtils.h"
  42. #include "DebugNew.h"
  43. static const Controls noControls;
  44. static const int MIN_FILE_FRAGMENT_COUNT = 16;
  45. static const int MAX_FILE_FRAGMENT_COUNT = 1024;
  46. static const int FILE_FRAGMENT_COUNT_DELTA = 8;
  47. Client::Client(Network* network, ResourceCache* cache, const std::string& downloadDirectory) :
  48. mNetwork(network),
  49. mCache(cache),
  50. mNetFps(30),
  51. mTimeAcc(0.0f),
  52. mMaxPredictionTime(0.25f), // 250 ms
  53. mFrameNumber(1),
  54. mDownloadDirectory(fixPath(downloadDirectory))
  55. {
  56. if (!mNetwork)
  57. EXCEPTION("Null network for Client");
  58. if (!mCache)
  59. EXCEPTION("Null resource cache for Client");
  60. LOGINFO("Client created");
  61. subscribeToEvent(EVENT_PEERDISCONNECTED, EVENT_HANDLER(Client, handlePeerDisconnected));
  62. subscribeToEvent(EVENT_FILETRANSFERCOMPLETED, EVENT_HANDLER(Client, handleFileTransferCompleted));
  63. subscribeToEvent(EVENT_FILETRANSFERFAILED, EVENT_HANDLER(Client, handleFileTransferFailed));
  64. subscribeToEvent(EVENT_ASYNCLOADFINISHED, EVENT_HANDLER(Client, handleAsyncLoadFinished));
  65. }
  66. Client::~Client()
  67. {
  68. LOGINFO("Client shut down");
  69. }
  70. void Client::setScene(Scene* scene)
  71. {
  72. mScene = scene;
  73. }
  74. void Client::setMaxPredictionTime(float time)
  75. {
  76. mMaxPredictionTime = max(time, 0.0f);
  77. }
  78. bool Client::connect(const std::string& address, unsigned short port, const std::string& userName, const VariantMap& loginData)
  79. {
  80. if (!mScene)
  81. return false;
  82. // Make sure any previous async loading is stopped
  83. mScene->stopAsyncLoading();
  84. disconnect();
  85. Peer* peer = mNetwork->connect(address, port);
  86. if (!peer)
  87. return false;
  88. mServerConnection = new Connection(peer);
  89. mFrameNumber = 1;
  90. mPendingUserName = userName;
  91. mPendingLoginData = loginData;
  92. return true;
  93. }
  94. void Client::disconnect()
  95. {
  96. if (mServerConnection)
  97. {
  98. mServerConnection->disconnect();
  99. mServerConnection.reset();
  100. }
  101. // Stop async loading if was in progress
  102. if (!mScene)
  103. mScene->stopAsyncLoading();
  104. mPendingDownloads.clear();
  105. mFileTransfers.clear();
  106. mSceneInfo = SceneInfo();
  107. }
  108. void Client::setControls(const Controls& controls)
  109. {
  110. if (mServerConnection)
  111. mServerConnection->setControls(controls);
  112. }
  113. void Client::setPosition(const Vector3& position)
  114. {
  115. if (mServerConnection)
  116. mServerConnection->setPosition(position);
  117. }
  118. void Client::update(float timeStep)
  119. {
  120. PROFILE(Client_Update);
  121. // Process connection (assume that Engine has updated Network, so we do not do that here)
  122. if (mServerConnection)
  123. {
  124. static VectorBuffer packet;
  125. // Process reliable packets first, then unreliable
  126. while (mServerConnection->receiveReliable(packet))
  127. handleReliablePacket(packet);
  128. while (mServerConnection->receiveUnreliable(packet))
  129. handleServerUpdate(packet);
  130. // Update own simulation of scene if connected
  131. if (mServerConnection->getScene() == mScene)
  132. mScene->update(timeStep);
  133. }
  134. // Send update if enough time passed
  135. float netPeriod = 1.0f / mNetFps;
  136. mTimeAcc += timeStep;
  137. if (mTimeAcc >= netPeriod)
  138. {
  139. // If multiple updates have accumulated because of a slow frame, send just one
  140. while (mTimeAcc >= netPeriod)
  141. mTimeAcc -= netPeriod;
  142. ++mFrameNumber;
  143. // We have a policy that framenumber 0 means "frame never received", so loop back to 1
  144. if (!mFrameNumber)
  145. ++mFrameNumber;
  146. sendClientUpdate();
  147. }
  148. }
  149. bool Client::isConnected() const
  150. {
  151. return (mServerConnection) && (mServerConnection->isConnected()) && (mServerConnection->hasChallenge());
  152. }
  153. bool Client::isJoinPending() const
  154. {
  155. return ((isConnected()) && (mServerConnection->getJoinState() == JS_PREPARESCENE));
  156. }
  157. bool Client::isJoined() const
  158. {
  159. return ((isConnected()) && (mServerConnection->getJoinState() > JS_PREPARESCENE));
  160. }
  161. const Controls& Client::getControls() const
  162. {
  163. if (!mServerConnection)
  164. return noControls;
  165. return mServerConnection->getControls();
  166. }
  167. const Vector3& Client::getPosition() const
  168. {
  169. if (!mServerConnection)
  170. return Vector3::sZero;
  171. return mServerConnection->getPosition();
  172. }
  173. std::string Client::getFileTransferStatus() const
  174. {
  175. std::string ret;
  176. for (std::map<StringHash, FileTransfer>::const_iterator i = mFileTransfers.begin(); i != mFileTransfers.end(); ++i)
  177. {
  178. std::string line = i->second.mFileName + " " + toString(i->second.mBytesReceived) + "/" + toString(i->second.mSize)
  179. + " (" + toString((int)(((float)i->second.mBytesReceived / (float)i->second.mSize) * 100.0f + 0.5f)) + "%)\n";
  180. ret += line;
  181. }
  182. return ret;
  183. }
  184. void Client::handlePeerDisconnected(StringHash eventType, VariantMap& eventData)
  185. {
  186. using namespace PeerDisconnected;
  187. Peer* peerPtr = static_cast<Peer*>(eventData[P_PEER].getPtr());
  188. if (peerPtr->getType() != PEER_SERVER)
  189. return;
  190. if (mServerConnection)
  191. {
  192. if (mServerConnection->getPeer() == peerPtr)
  193. {
  194. mServerConnection->leftScene();
  195. mServerConnection.reset();
  196. mPendingDownloads.clear();
  197. mFileTransfers.clear();
  198. mSceneInfo = SceneInfo();
  199. }
  200. }
  201. }
  202. void Client::handleFileTransferCompleted(StringHash eventType, VariantMap& eventData)
  203. {
  204. using namespace FileTransferCompleted;
  205. std::string fileName = eventData[P_FILENAME].getString();
  206. if (mPendingDownloads.find(fileName) != mPendingDownloads.end())
  207. {
  208. mPendingDownloads.erase(fileName);
  209. // Add the package to the resource cache
  210. try
  211. {
  212. SharedPtr<PackageFile> package(new PackageFile(eventData[P_FULLPATH].getString()));
  213. // Add the package as first in case it overrides something in the default files
  214. mCache->addPackageFile(package, true);
  215. }
  216. catch (...)
  217. {
  218. joinFailed("Could not open downloaded package file " + fileName);
  219. return;
  220. }
  221. // If this was the last required download, can now join scene
  222. if ((mPendingDownloads.empty()) && (isJoinPending()))
  223. setupScene();
  224. }
  225. }
  226. void Client::handleFileTransferFailed(StringHash eventType, VariantMap& eventData)
  227. {
  228. using namespace FileTransferFailed;
  229. std::string fileName = eventData[P_FILENAME].getString();
  230. if (mPendingDownloads.find(fileName) != mPendingDownloads.end())
  231. joinFailed("Failed to transfer file " + fileName);
  232. }
  233. void Client::handleAsyncLoadFinished(StringHash eventType, VariantMap& eventData)
  234. {
  235. if ((!mScene) || (!mServerConnection))
  236. return;
  237. using namespace AsyncLoadFinished;
  238. // If it is the scene used for networking, send join packet now
  239. if ((eventData[P_SCENE].getPtr() == (void*)mScene) && (mServerConnection->getJoinState() == JS_LOADSCENE))
  240. sendJoinScene();
  241. }
  242. void Client::handleReliablePacket(VectorBuffer& packet)
  243. {
  244. unsigned char msgID = 0;
  245. try
  246. {
  247. msgID = packet.readUByte();
  248. switch (msgID)
  249. {
  250. case MSG_CHALLENGE:
  251. handleChallenge(packet);
  252. break;
  253. case MSG_SCENEINFO:
  254. handleSceneInfo(packet);
  255. break;
  256. case MSG_TRANSFERDATA:
  257. handleTransferData(packet);
  258. break;
  259. case MSG_TRANSFERFAILED:
  260. handleTransferFailed(packet);
  261. break;
  262. case MSG_JOINREPLY:
  263. handleJoinReply(packet);
  264. break;
  265. case MSG_FULLUPDATE:
  266. handleFullUpdate(packet);
  267. break;
  268. default:
  269. LOGERROR("Unknown message ID " + toString((int)msgID) + " received from server");
  270. break;
  271. }
  272. }
  273. catch (...)
  274. {
  275. LOGERROR("Exception while handling message ID " + toString((int)msgID));
  276. }
  277. }
  278. void Client::handleChallenge(VectorBuffer& packet)
  279. {
  280. mServerConnection->setChallenge(packet.readUInt() ^ Connection::sHashInit.mData);
  281. // Send identity packet as a response
  282. VectorBuffer replyPacket;
  283. replyPacket.writeUByte(MSG_IDENTITY);
  284. replyPacket.writeUInt(mServerConnection->getResponse());
  285. replyPacket.writeString(mPendingUserName);
  286. replyPacket.writeVariantMap(mPendingLoginData);
  287. mServerConnection->sendReliable(replyPacket);
  288. mServerConnection->updateResponse();
  289. }
  290. void Client::handleSceneInfo(VectorBuffer& packet)
  291. {
  292. if (!mScene)
  293. return;
  294. // Stop all previous loading, associate the scene with the connection
  295. mScene->stopAsyncLoading();
  296. mServerConnection->setScene(mScene);
  297. // Read scene name, number of users and update rate
  298. std::string sceneName = packet.readString();
  299. mSceneInfo.mName = sceneName;
  300. mSceneInfo.mNumUsers = packet.readVLE();
  301. mSceneInfo.mNetFps = packet.readInt();
  302. // Read source file name & required packages
  303. mSceneInfo.mFileName = packet.readString();
  304. unsigned numPackages = packet.readVLE();
  305. mSceneInfo.mRequiredPackages.clear();
  306. for (unsigned i = 0; i < numPackages; ++i)
  307. {
  308. PackageInfo package;
  309. package.mName = packet.readString();
  310. package.mSize = packet.readUInt();
  311. package.mChecksum = packet.readUInt();
  312. mSceneInfo.mRequiredPackages.push_back(package);
  313. }
  314. // Read scene properties
  315. unsigned scenePropertiesSize = packet.readVLE();
  316. mSceneInfo.mSceneProperties.setData(packet, scenePropertiesSize);
  317. // Check need for downloads: if none, can join immediately
  318. if (!checkPackages())
  319. setupScene();
  320. }
  321. void Client::handleTransferData(VectorBuffer& packet)
  322. {
  323. StringHash nameHash = packet.readStringHash();
  324. std::map<StringHash, FileTransfer>::iterator i = mFileTransfers.find(nameHash);
  325. if (i == mFileTransfers.end())
  326. {
  327. LOGDEBUG("Received fragment for nonexisting file transfer " + toString(nameHash));
  328. return;
  329. }
  330. FileTransfer& transfer = i->second;
  331. unsigned index = packet.readVLE();
  332. if (transfer.mNumReceived != index)
  333. {
  334. LOGERROR("Received unexpected fragment for file " + toString(nameHash) + ", stopping transfer");
  335. using namespace FileTransferFailed;
  336. VariantMap eventData;
  337. eventData[P_FILENAME] = transfer.mFileName;
  338. eventData[P_REASON] = "Unexpected fragment";
  339. sendEvent(EVENT_FILETRANSFERFAILED, eventData);
  340. mFileTransfers.erase(i);
  341. return;
  342. }
  343. transfer.mNumReceived = index + 1; // We receive fragments in order
  344. unsigned dataSize = packet.getSize() - packet.getPosition();
  345. transfer.mFile->write(packet.getData() + packet.getPosition(), dataSize);
  346. transfer.mBytesReceived += dataSize;
  347. if (transfer.mNumReceived == transfer.mNumFragments)
  348. {
  349. if (transfer.mBytesReceived != transfer.mSize)
  350. {
  351. LOGERROR("Transfer of file " + transfer.mFileName + " finished, expected " + toString(transfer.mSize) +
  352. " bytes but got " + toString(transfer.mBytesReceived));
  353. using namespace FileTransferFailed;
  354. VariantMap eventData;
  355. eventData[P_FILENAME] = transfer.mFileName;
  356. eventData[P_REASON] = "Unexpected file size";
  357. sendEvent(EVENT_FILETRANSFERFAILED, eventData);
  358. }
  359. else
  360. {
  361. float totalTime = transfer.mReceiveTimer.getMSec(true) * 0.001f;
  362. LOGINFO("Transfer of file " + transfer.mFileName + " completed in " +
  363. toString(totalTime) + " seconds, speed " + toString(transfer.mSize / totalTime) + " bytes/sec");
  364. using namespace FileTransferCompleted;
  365. VariantMap eventData;
  366. eventData[P_FILENAME] = transfer.mFileName;
  367. eventData[P_FULLPATH] = transfer.mFile->getName();
  368. // Others might try to use the file as a response to the event, so close it first
  369. transfer.mFile.reset();
  370. sendEvent(EVENT_FILETRANSFERCOMPLETED, eventData);
  371. }
  372. mFileTransfers.erase(i);
  373. return;
  374. }
  375. // If current batch was finished, fire off the next
  376. if (transfer.mNumReceived == transfer.mBatchStart + transfer.mBatchSize)
  377. {
  378. transfer.mBatchStart = transfer.mNumReceived;
  379. float batchTime = transfer.mBatchTimer.getMSec(true) * 0.001f;
  380. float newDataRate = transfer.mBatchSize * FILE_FRAGMENT_SIZE / batchTime;
  381. LOGDEBUG("Received " + toString(transfer.mBatchSize) + " fragments in " + toString(batchTime) + " seconds");
  382. // If this was the first batch, can not yet estimate speed, so go up in batch size
  383. if (!transfer.mLastBatchSize)
  384. {
  385. transfer.mLastBatchSize = transfer.mBatchSize;
  386. transfer.mLastDataRate = newDataRate;
  387. transfer.mBatchSize += FILE_FRAGMENT_COUNT_DELTA;
  388. }
  389. else
  390. {
  391. bool goUp = true;
  392. // Go down in batch size if last batch was smaller and had better data rate
  393. if ((transfer.mLastBatchSize < transfer.mBatchSize) && (transfer.mLastDataRate > newDataRate))
  394. goUp = false;
  395. transfer.mLastBatchSize = transfer.mBatchSize;
  396. transfer.mLastDataRate = newDataRate;
  397. if (goUp)
  398. transfer.mBatchSize += FILE_FRAGMENT_COUNT_DELTA;
  399. else
  400. transfer.mBatchSize -= FILE_FRAGMENT_COUNT_DELTA;
  401. transfer.mBatchSize = clamp((int)transfer.mBatchSize, MIN_FILE_FRAGMENT_COUNT, MAX_FILE_FRAGMENT_COUNT);
  402. }
  403. VectorBuffer packet;
  404. packet.writeUByte(MSG_REQUESTFILE);
  405. packet.writeUInt(mServerConnection->getResponse());
  406. packet.writeStringHash(i->first);
  407. packet.writeVLE(transfer.mBatchStart);
  408. packet.writeVLE(transfer.mBatchSize);
  409. mServerConnection->sendReliable(packet);
  410. mServerConnection->updateResponse();
  411. }
  412. }
  413. void Client::handleTransferFailed(VectorBuffer& packet)
  414. {
  415. StringHash nameHash = packet.readStringHash();
  416. std::string reason = packet.readString();
  417. std::map<StringHash, FileTransfer>::iterator i = mFileTransfers.find(nameHash);
  418. if (i == mFileTransfers.end())
  419. {
  420. LOGDEBUG("Received fail for nonexisting file transfer " + toString(nameHash));
  421. return;
  422. }
  423. std::string errorMsg = "Transfer of file " + toString(nameHash) + " failed: " + reason;
  424. LOGINFO(errorMsg);
  425. using namespace FileTransferFailed;
  426. VariantMap eventData;
  427. eventData[P_FILENAME] = i->second.mFileName;
  428. eventData[P_REASON] = reason;
  429. sendEvent(EVENT_FILETRANSFERFAILED, eventData);
  430. mFileTransfers.erase(i);
  431. }
  432. void Client::handleJoinReply(VectorBuffer& packet)
  433. {
  434. if (!mScene)
  435. return;
  436. bool success = packet.readBool();
  437. if (success)
  438. {
  439. std::string userName = packet.readString(); // Read back (possibly changed) username
  440. mServerConnection->setUserName(userName);
  441. mServerConnection->joinedScene();
  442. LOGINFO("Joined scene " + mScene->getName() + " with username " + userName);
  443. sendEvent(EVENT_JOINEDSCENE);
  444. }
  445. else
  446. {
  447. std::string reason = packet.readString();
  448. mServerConnection->leftScene();
  449. mPendingDownloads.clear();
  450. mFileTransfers.clear();
  451. joinFailed(reason);
  452. }
  453. }
  454. void Client::handleFullUpdate(VectorBuffer& packet)
  455. {
  456. handleServerUpdate(packet, true);
  457. }
  458. void Client::handleServerUpdate(VectorBuffer& packet, bool initial)
  459. {
  460. if (!isJoined())
  461. return;
  462. // Read frame numbers and physics sync information
  463. unsigned short lastFrameNumber = packet.readUShort();
  464. unsigned short lastFrameAck = packet.readUShort();
  465. float physicsTimeAcc = packet.readFloat();
  466. PhysicsWorld* world = mScene->getExtension<PhysicsWorld>();
  467. if (world)
  468. world->setTimeAccumulator(physicsTimeAcc);
  469. if (!initial)
  470. {
  471. // Check that this packet is not older than the last received (overlap may occur when we transition
  472. // between a reliable full update and unreliable delta updates)
  473. if (!checkFrameNumber(lastFrameNumber, mServerConnection->getFrameNumber()))
  474. return;
  475. //LOGINFO("Delta: " + toString(packet.getSize()));
  476. }
  477. else
  478. {
  479. // If initial/full update, remove all old proxy entities
  480. mScene->removeAllEntities(NET_PROXY);
  481. LOGINFO("Initial scene: " + toString(packet.getSize()) + " bytes");
  482. }
  483. mServerConnection->setFrameNumbers(lastFrameNumber, lastFrameAck);
  484. mServerConnection->updateRoundTripTime(mNetFps, mFrameNumber);
  485. unsigned short previousEventFrameNumber = mServerConnection->getEventFrameNumber();
  486. NetUpdateInfo info;
  487. info.mConnection = mServerConnection;
  488. info.mFrameNumber = mFrameNumber;
  489. info.mFrameAck = mServerConnection->getFrameAck();
  490. info.mRemoteFrameNumber = mServerConnection->getFrameNumber();
  491. info.mRoundTripTime = mServerConnection->getRoundTripTime();
  492. std::set<EntityID> updatedEntities;
  493. // Restore predicted entities' state to the last one we got from server
  494. mScene->restorePredictedEntities();
  495. // Read the actual scene update messages
  496. while (!packet.isEof())
  497. {
  498. unsigned char msgID = packet.readUByte();
  499. switch (msgID & 0x0f)
  500. {
  501. case MSG_CREATEENTITY:
  502. case MSG_REMOVEENTITY:
  503. case MSG_UPDATEENTITY:
  504. readNetUpdateBlock(packet, msgID, info, updatedEntities);
  505. break;
  506. case MSG_REMOTEEVENT:
  507. {
  508. RemoteEvent newEvent;
  509. newEvent.read(packet, false);
  510. if (mServerConnection->checkRemoteEventFrame(newEvent, previousEventFrameNumber))
  511. newEvent.dispatch(mServerConnection, mScene);
  512. }
  513. break;
  514. case MSG_REMOTEENTITYEVENT:
  515. {
  516. RemoteEvent newEvent;
  517. newEvent.read(packet, true);
  518. if (mServerConnection->checkRemoteEventFrame(newEvent, previousEventFrameNumber))
  519. newEvent.dispatch(mServerConnection, mScene);
  520. }
  521. break;
  522. default:
  523. LOGWARNING("Unknown message ID " + toString((int)msgID) + " received from server");
  524. packet.seek(packet.getSize()); // Break loop
  525. break;
  526. }
  527. }
  528. // Perform post-update for entities
  529. for (std::set<EntityID>::iterator i = updatedEntities.begin(); i != updatedEntities.end(); ++i)
  530. {
  531. Entity* entity = mScene->getEntity(*i);
  532. if (entity)
  533. entity->postNetUpdate(mCache);
  534. }
  535. // Store predicted entities' state for later recall
  536. mScene->storePredictedEntities();
  537. // If initial update, send back ack
  538. if (initial)
  539. {
  540. VectorBuffer replyPacket;
  541. replyPacket.writeUByte(MSG_FULLUPDATEACK);
  542. replyPacket.writeUInt(mServerConnection->getResponse());
  543. replyPacket.writeUShort(mFrameNumber);
  544. replyPacket.writeUShort(mServerConnection->getFrameNumber());
  545. mServerConnection->sendReliable(replyPacket);
  546. mServerConnection->updateResponse();
  547. mServerConnection->setJoinState(JS_SENDDELTAS);
  548. }
  549. // Remove acked controls
  550. mServerConnection->purgeAckedControls();
  551. // Run scene playback to overcome latency
  552. replayControls();
  553. }
  554. void Client::replayControls()
  555. {
  556. float netPeriod = 1.0f / mNetFps;
  557. float roundTripTime = mServerConnection->getRoundTripTime();
  558. float totalTime = 0.0f;
  559. float maxTime = min(roundTripTime, mMaxPredictionTime);
  560. // If total RTT is less than one client/server frame, do not replay
  561. if (roundTripTime < netPeriod)
  562. return;
  563. PROFILE(Client_ReplayControls);
  564. // Replay old controls to counteract network latency
  565. // Note: index 0 is the last acked client update, so unacked controls start from index 1
  566. std::vector<std::pair<unsigned short, Controls> >& unackedControls = mServerConnection->getUnackedControls();
  567. mScene->setPlayback(true);
  568. for (unsigned i = 0; i < unackedControls.size(); ++i)
  569. {
  570. float timeStep = netPeriod;
  571. // Run all controls for the full time step, except the last for the amount of accumulated time since last client update
  572. if (i == unackedControls.size() - 1)
  573. timeStep = clamp(mTimeAcc, M_EPSILON, netPeriod);
  574. // Check for predicting too much (risk of lag due to CPU usage)
  575. if (totalTime + timeStep > maxTime)
  576. timeStep = max(maxTime - totalTime, 0.0f);
  577. const Controls& controls = unackedControls[i].second;
  578. using namespace ControlsPlayback;
  579. VariantMap eventData;
  580. eventData = controls.mExtraData;
  581. eventData[P_SCENE] = (void*)mScene.getPtr();
  582. eventData[P_TIMESTEP] = timeStep;
  583. eventData[P_BUTTONS] = controls.mButtons;
  584. eventData[P_YAW] = controls.mYaw;
  585. eventData[P_PITCH] = controls.mPitch;
  586. // Send the controls playback event, so that the application can inject the controls into the entity being controlled
  587. sendEvent(EVENT_CONTROLSPLAYBACK, eventData);
  588. // Then run the scene in controls playback mode
  589. if ((i > 0) && (timeStep > 0.0f))
  590. {
  591. mScene->update(timeStep);
  592. totalTime += timeStep;
  593. }
  594. }
  595. mScene->setPlayback(false);
  596. }
  597. unsigned Client::checkPackages()
  598. {
  599. mPendingDownloads.clear();
  600. // To avoid resource version conflicts and to keep the amount of open packages reasonable, remove all existing
  601. // downloaded packages from the resource cache first
  602. std::vector<std::string> downloadedPackages = scanDirectory(mDownloadDirectory, "*.pak", false, false, false);
  603. std::vector<SharedPtr<PackageFile> > registeredPackages = mCache->getPackageFiles();
  604. for (std::vector<SharedPtr<PackageFile> >::iterator i = registeredPackages.begin(); i != registeredPackages.end();)
  605. {
  606. if ((*i)->getName().find(mDownloadDirectory) != std::string::npos)
  607. {
  608. mCache->removePackageFile(*i);
  609. i = registeredPackages.erase(i);
  610. }
  611. else
  612. ++i;
  613. }
  614. for (unsigned i = 0; i < mSceneInfo.mRequiredPackages.size(); ++i)
  615. {
  616. const PackageInfo& required = mSceneInfo.mRequiredPackages[i];
  617. std::string requiredName = getFileName(required.mName);
  618. bool found = false;
  619. // Check both already registered packages, and existing downloads
  620. for (unsigned j = 0; j < registeredPackages.size(); ++j)
  621. {
  622. PackageFile* package = registeredPackages[i];
  623. std::string name = getFileName(package->getName());
  624. if ((name.find(requiredName) != std::string::npos) && (package->getTotalSize() == required.mSize) &&
  625. (package->getChecksum() == required.mChecksum))
  626. {
  627. found = true;
  628. break;
  629. }
  630. }
  631. if (!found)
  632. {
  633. for (unsigned j = 0; j < downloadedPackages.size(); ++j)
  634. {
  635. // Downloaded packages are encoded as filename_checksum.pak, so check if the filename contains the required name
  636. std::string name = getFileName(downloadedPackages[i]);
  637. if (name.find(requiredName) != std::string::npos)
  638. {
  639. try
  640. {
  641. SharedPtr<PackageFile> file(new PackageFile(mDownloadDirectory + downloadedPackages[i]));
  642. if ((file->getTotalSize() == required.mSize) && (file->getChecksum() == required.mChecksum))
  643. {
  644. // Add the package as first in case it overrides something in the default files
  645. mCache->addPackageFile(file, true);
  646. found = true;
  647. break;
  648. }
  649. }
  650. catch (...)
  651. {
  652. }
  653. }
  654. }
  655. }
  656. if (!found)
  657. {
  658. // If not found, initiate the download
  659. if (!requestFile(required.mName, required.mSize, required.mChecksum))
  660. {
  661. joinFailed("Failed to initiate transfer for file " + required.mName);
  662. return M_MAX_UNSIGNED; // Return nonzero to prevent immediate join attempt
  663. }
  664. mPendingDownloads.insert(required.mName);
  665. }
  666. }
  667. return mPendingDownloads.size();
  668. }
  669. bool Client::requestFile(const std::string& fileName, unsigned size, unsigned checksum)
  670. {
  671. // Register hash reverse mapping so that error messages will be intelligible
  672. registerHash(fileName);
  673. StringHash nameHash(fileName);
  674. if (mFileTransfers.find(nameHash) != mFileTransfers.end())
  675. return true; // Already initiated
  676. FileTransfer newTransfer;
  677. try
  678. {
  679. // Append checksum to download name, so that we can have several versions of a package
  680. std::string destName = getFileName(fileName) + "_" + toStringHex(checksum) + getExtension(fileName);
  681. newTransfer.mFile = new File(mDownloadDirectory + destName, FILE_WRITE);
  682. }
  683. catch (...)
  684. {
  685. return false;
  686. }
  687. newTransfer.mFileName = fileName;
  688. newTransfer.mSize = size;
  689. newTransfer.mChecksum = checksum;
  690. newTransfer.mNumFragments = (size - 1) / FILE_FRAGMENT_SIZE + 1;
  691. newTransfer.mBatchTimer.reset();
  692. newTransfer.mReceiveTimer.reset();
  693. newTransfer.mBatchSize = MIN_FILE_FRAGMENT_COUNT;
  694. VectorBuffer packet;
  695. packet.writeUByte(MSG_REQUESTFILE);
  696. packet.writeUInt(mServerConnection->getResponse());
  697. packet.writeStringHash(nameHash);
  698. packet.writeVLE(newTransfer.mBatchStart);
  699. packet.writeVLE(newTransfer.mBatchSize);
  700. mServerConnection->sendReliable(packet);
  701. mServerConnection->updateResponse();
  702. mFileTransfers[nameHash] = newTransfer;
  703. LOGINFO("Started transfer of file " + fileName + ", " + toString(size) + " bytes");
  704. return true;
  705. }
  706. void Client::setupScene()
  707. {
  708. mNetFps = mSceneInfo.mNetFps;
  709. mTimeAcc = 0.0f;
  710. // Remove all previous content
  711. mScene->removeAllEntities();
  712. // Setup the scene according to the received properties
  713. // If no filename, just setup octree/physics/interpolation
  714. if (mSceneInfo.mFileName.empty())
  715. {
  716. mSceneInfo.mSceneProperties.seek(0);
  717. mScene->setName(mSceneInfo.mName);
  718. mScene->removeAllEntities();
  719. mScene->loadProperties(mSceneInfo.mSceneProperties);
  720. sendJoinScene();
  721. }
  722. else
  723. {
  724. try
  725. {
  726. SharedPtr<File> sceneFile = mCache->getFile(mSceneInfo.mFileName);
  727. // Support either binary or XML format scene
  728. if (getExtension(mSceneInfo.mFileName) == ".xml")
  729. mScene->loadAsyncXML(sceneFile);
  730. else
  731. mScene->loadAsync(sceneFile);
  732. mServerConnection->setJoinState(JS_LOADSCENE);
  733. }
  734. catch (...)
  735. {
  736. joinFailed("Failed to load scene " + mSceneInfo.mFileName);
  737. }
  738. }
  739. }
  740. void Client::sendJoinScene()
  741. {
  742. if ((!mScene) || (!mServerConnection))
  743. return;
  744. VectorBuffer packet;
  745. packet.writeUByte(MSG_JOINSCENE);
  746. packet.writeUInt(mServerConnection->getResponse());
  747. packet.writeUInt(mScene->getChecksum());
  748. mServerConnection->sendReliable(packet);
  749. mServerConnection->updateResponse();
  750. }
  751. void Client::joinFailed(const std::string& reason)
  752. {
  753. LOGINFO("Failed to join scene, reason: " + reason);
  754. using namespace JoinSceneFailed;
  755. VariantMap eventData;
  756. eventData[P_REASON] = reason;
  757. sendEvent(EVENT_JOINSCENEFAILED);
  758. }
  759. void Client::sendClientUpdate()
  760. {
  761. if (!isJoined())
  762. {
  763. // If we are not connected but remote events have been queued, clear them
  764. if (mScene)
  765. mScene->clearQueuedRemoteEvents();
  766. return;
  767. }
  768. // Request updated controls from the application
  769. using namespace ControlsUpdate;
  770. VariantMap eventData;
  771. eventData[P_SCENE] = (void*)mScene.getPtr();
  772. sendEvent(EVENT_CONTROLSUPDATE, eventData);
  773. // Purge acked and expired remote events
  774. mServerConnection->purgeAckedRemoteEvents(mFrameNumber);
  775. // Check new outgoing remote events, assign them framenumbers, and put to unacked queue
  776. // (note: as we can only send events to the server, the receiver field in the event is ignored)
  777. std::vector<RemoteEvent>& outEvents = mScene->getQueuedRemoteEvents();
  778. for (std::vector<RemoteEvent>::iterator i = outEvents.begin(); i != outEvents.end();)
  779. {
  780. i->mFrameNumber = mFrameNumber;
  781. mServerConnection->addRemoteEvent(*i);
  782. i = outEvents.erase(i);
  783. }
  784. static VectorBuffer packet;
  785. packet.resize(0);
  786. packet.writeUShort(mFrameNumber);
  787. packet.writeUShort(mServerConnection->getFrameNumber());
  788. // Write controls and position
  789. const Controls& controls = mServerConnection->getControls();
  790. packet.writeUByte(MSG_CONTROLS);
  791. packet.writeUInt(controls.mButtons);
  792. packet.writeFloat(controls.mYaw);
  793. packet.writeFloat(controls.mPitch);
  794. packet.writeVariantMap(controls.mExtraData);
  795. packet.writeVector3(mServerConnection->getPosition());
  796. // Remember the controls for later replay
  797. mServerConnection->addUnackedControls(mFrameNumber, controls);
  798. // Append unacked remote events
  799. const std::vector<RemoteEvent>& unackedEvents = mServerConnection->getUnackedRemoteEvents();
  800. for (std::vector<RemoteEvent>::const_iterator i = unackedEvents.begin(); i != unackedEvents.end(); ++i)
  801. {
  802. packet.writeUByte(i->mEntityID ? MSG_REMOTEENTITYEVENT : MSG_REMOTEEVENT);
  803. i->write(packet);
  804. }
  805. mServerConnection->sendUnreliable(packet);
  806. }
  807. void Client::readNetUpdateBlock(Deserializer& source, unsigned char msgID, const NetUpdateInfo& info, std::set<EntityID>& updatedEntities)
  808. {
  809. EntityID id = source.readUShort();
  810. Entity* entity = mScene->getEntity(id);
  811. switch (msgID & 0x0f)
  812. {
  813. case MSG_CREATEENTITY:
  814. {
  815. // Entity may already exist if server sends the create many times. But data may have changed
  816. std::string name = source.readString();
  817. if (!entity)
  818. entity = mScene->createEntity(id, name);
  819. unsigned char netFlags = source.readUByte();
  820. entity->setNetFlags(netFlags);
  821. if (netFlags & NET_OWNER)
  822. entity->setOwner(mServerConnection);
  823. else
  824. entity->setOwner(0);
  825. entity->setProperties(source.readVariantMap(), true);
  826. static std::set<Component*> extraComponents;
  827. extraComponents.clear();
  828. const std::vector<SharedPtr<Component> >& components = entity->getComponents();
  829. for (std::vector<SharedPtr<Component> >::const_iterator i = components.begin(); i != components.end(); ++i)
  830. extraComponents.insert(*i);
  831. unsigned numComponents = source.readVLE();
  832. for (unsigned i = 0; i < numComponents; ++i)
  833. {
  834. ShortStringHash type = source.readShortStringHash();
  835. std::string name = source.readString();
  836. // We might apply the same update multiple times, so check if the component already exists
  837. Component* component = entity->getComponent(type, name);
  838. bool newComponent = false;
  839. if (!component)
  840. {
  841. component = entity->createComponent(type, name);
  842. newComponent = true;
  843. }
  844. component->setNetFlags(source.readUByte());
  845. component->readNetUpdate(source, mCache, info);
  846. // If component is new, finish interpolation immediately
  847. if (newComponent)
  848. component->interpolate(true);
  849. extraComponents.erase(component);
  850. }
  851. // Now check if the entity has extra components it should not, and remove them
  852. for (std::set<Component*>::iterator i = extraComponents.begin(); i != extraComponents.end(); ++i)
  853. entity->removeComponent(*i);
  854. updatedEntities.insert(id);
  855. }
  856. break;
  857. case MSG_REMOVEENTITY:
  858. if (entity)
  859. mScene->removeEntity(id);
  860. break;
  861. case MSG_UPDATEENTITY:
  862. {
  863. // Entity should exist, but if it does not, create it now to not desync the stream
  864. if (!entity)
  865. {
  866. LOGERROR("Update to nonexisting entity " + toString(id));
  867. entity = mScene->createEntity(id);
  868. }
  869. if (msgID & UPD_PROPERTIES)
  870. {
  871. unsigned numProperties = source.readVLE();
  872. for (unsigned i = 0; i < numProperties; ++i)
  873. {
  874. ShortStringHash key = source.readShortStringHash();
  875. Variant value = source.readVariant();
  876. entity->setProperty(key, value, true);
  877. }
  878. }
  879. if (msgID & UPD_NEWCOMPONENTS)
  880. {
  881. unsigned numComponents = source.readVLE();
  882. for (unsigned i = 0; i < numComponents; ++i)
  883. {
  884. ShortStringHash type = source.readShortStringHash();
  885. std::string name = source.readString();
  886. // We might apply the same update multiple times, so check if the component already exists
  887. Component* component = entity->getComponent(type, name);
  888. bool newComponent = false;
  889. if (!component)
  890. {
  891. component = entity->createComponent(type, name);
  892. newComponent = true;
  893. }
  894. component->setNetFlags(source.readUByte());
  895. component->readNetUpdate(source, mCache, info);
  896. // If component is new, finish interpolation immediately
  897. if (newComponent)
  898. component->interpolate(true);
  899. }
  900. }
  901. if (msgID & UPD_REMOVECOMPONENTS)
  902. {
  903. unsigned numComponents = source.readVLE();
  904. for (unsigned i = 0; i < numComponents; ++i)
  905. {
  906. Component* component = entity->getComponent(source.readShortStringHash().mData);
  907. if (component)
  908. entity->removeComponent(component);
  909. }
  910. }
  911. if (msgID & UPD_UPDATECOMPONENTS)
  912. {
  913. unsigned numComponents = source.readVLE();
  914. for (unsigned i = 0; i < numComponents; ++i)
  915. {
  916. ShortStringHash combinedHash = source.readShortStringHash();
  917. Component* component = entity->getComponent(combinedHash.mData);
  918. if (component)
  919. component->readNetUpdate(source, mCache, info);
  920. else
  921. {
  922. // Component should exist, but if it does not, create it now to not desync the stream
  923. // Note that we only have the combined hash to go on with, and we may guess the type
  924. // wrong, in that case an exception will be thrown
  925. LOGERROR("Update to nonexisting component " + toString(combinedHash) + " in entity " +
  926. entity->getName());
  927. component = entity->createComponent(combinedHash);
  928. component->readNetUpdate(source, mCache, info);
  929. component->interpolate(true);
  930. }
  931. }
  932. }
  933. updatedEntities.insert(id);
  934. }
  935. break;
  936. }
  937. }