Network.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  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 "Context.h"
  25. #include "CoreEvents.h"
  26. #include "File.h"
  27. #include "FileSystem.h"
  28. #include "Log.h"
  29. #include "MemoryBuffer.h"
  30. #include "Network.h"
  31. #include "NetworkEvents.h"
  32. #include "Profiler.h"
  33. #include "Protocol.h"
  34. #include "Scene.h"
  35. #include "SceneEvents.h"
  36. #include "StringUtils.h"
  37. #include <kNet.h>
  38. #include "DebugNew.h"
  39. static const int DEFAULT_UPDATE_FPS = 25;
  40. static const unsigned CONTROLS_CONTENT_ID = 1;
  41. OBJECTTYPESTATIC(Network);
  42. Network::Network(Context* context) :
  43. Object(context),
  44. updateFps_(DEFAULT_UPDATE_FPS),
  45. updateInterval_(1.0f / (float)DEFAULT_UPDATE_FPS),
  46. updateAcc_(0.0f)
  47. {
  48. network_ = new kNet::Network();
  49. SubscribeToEvent(E_BEGINFRAME, HANDLER(Network, HandleBeginFrame));
  50. SubscribeToEvent(E_ASYNCLOADFINISHED, HANDLER(Network, HandleAsyncLoadFinished));
  51. }
  52. Network::~Network()
  53. {
  54. // If server connection exists, disconnect, but do not send an event because we are shutting down
  55. Disconnect(100);
  56. serverConnection_.Reset();
  57. clientConnections_.Clear();
  58. delete network_;
  59. network_ = 0;
  60. }
  61. void Network::HandleMessage(kNet::MessageConnection* source, kNet::message_id_t id, const char* data, size_t numBytes)
  62. {
  63. PROFILE(HandleMessage);
  64. // Only process messages from known sources
  65. Connection* connection = GetConnection(source);
  66. if (connection)
  67. {
  68. MemoryBuffer msg(data, numBytes);
  69. bool handled = false;
  70. if (connection->IsClient())
  71. handled = OnClientMessage(connection, id, msg);
  72. else
  73. handled = OnServerMessage(connection, id, msg);
  74. // If message was not handled internally, forward as an event
  75. if (!handled)
  76. {
  77. using namespace NetworkMessage;
  78. VariantMap eventData;
  79. eventData[P_CONNECTION] = (void*)connection;
  80. eventData[P_MESSAGEID] = (int)id;
  81. eventData[P_DATA].SetBuffer(msg.GetData(), msg.GetSize());
  82. connection->SendEvent(E_NETWORKMESSAGE, eventData);
  83. }
  84. }
  85. else
  86. LOGWARNING("Discarding message from unknown MessageConnection " + ToString((void*)source));
  87. }
  88. u32 Network::ComputeContentID(kNet::message_id_t id, const char* data, size_t numBytes)
  89. {
  90. switch (id)
  91. {
  92. case MSG_CONTROLSUPDATE:
  93. // Return fixed content ID for controls
  94. return CONTROLS_CONTENT_ID;
  95. case MSG_NODELATESTDATA:
  96. case MSG_COMPONENTLATESTDATA:
  97. {
  98. // Return the node or component ID, which is first in the message
  99. MemoryBuffer msg(data, numBytes);
  100. return msg.ReadVLE();
  101. }
  102. default:
  103. // By default return no content ID
  104. return 0;
  105. }
  106. }
  107. void Network::NewConnectionEstablished(kNet::MessageConnection* connection)
  108. {
  109. connection->RegisterInboundMessageHandler(this);
  110. // Create a new client connection corresponding to this MessageConnection
  111. Connection* newConnection = new Connection(context_, true, kNet::SharedPtr<kNet::MessageConnection>(connection));
  112. clientConnections_[connection] = newConnection;
  113. LOGINFO("Client " + newConnection->ToString() + " connected");
  114. using namespace ClientConnected;
  115. VariantMap eventData;
  116. eventData[P_CONNECTION] = (void*)newConnection;
  117. SendEvent(E_CLIENTCONNECTED, eventData);
  118. }
  119. void Network::ClientDisconnected(kNet::MessageConnection* connection)
  120. {
  121. connection->Disconnect(0);
  122. // Remove the client connection that corresponds to this MessageConnection
  123. Map<kNet::MessageConnection*, SharedPtr<Connection> >::Iterator i = clientConnections_.Find(connection);
  124. if (i != clientConnections_.End())
  125. {
  126. LOGINFO("Client " + i->second_->ToString() + " disconnected");
  127. using namespace ClientDisconnected;
  128. VariantMap eventData;
  129. eventData[P_CONNECTION] = (void*)i->second_;
  130. SendEvent(E_CLIENTDISCONNECTED, eventData);
  131. clientConnections_.Erase(i);
  132. }
  133. }
  134. bool Network::Connect(const String& address, unsigned short port, Scene* scene, const VariantMap& identity)
  135. {
  136. PROFILE(Connect);
  137. // If a previous connection already exists, disconnect it and wait for some time for the connection to terminate
  138. if (serverConnection_)
  139. {
  140. serverConnection_->Disconnect(100);
  141. OnServerDisconnected();
  142. }
  143. kNet::SharedPtr<kNet::MessageConnection> connection = network_->Connect(address.CString(), port, kNet::SocketOverUDP, this);
  144. if (connection)
  145. {
  146. LOGINFO("Connecting to server " + address + ":" + String(port));
  147. serverConnection_ = new Connection(context_, false, connection);
  148. serverConnection_->SetScene(scene);
  149. serverConnection_->SetIdentity(identity);
  150. serverConnection_->SetConnectPending(true);
  151. return true;
  152. }
  153. else
  154. {
  155. LOGERROR("Failed to connect to server " + address + ":" + String(port));
  156. SendEvent(E_CONNECTFAILED);
  157. return false;
  158. }
  159. }
  160. void Network::Disconnect(int waitMSec)
  161. {
  162. if (!serverConnection_)
  163. return;
  164. PROFILE(Disconnect);
  165. serverConnection_->Disconnect(waitMSec);
  166. }
  167. bool Network::StartServer(unsigned short port)
  168. {
  169. if (IsServerRunning())
  170. return true;
  171. PROFILE(StartServer);
  172. /// \todo Investigate why server fails to restart after stopping when false is specified for reuse
  173. if (network_->StartServer(port, kNet::SocketOverUDP, this, true) != 0)
  174. {
  175. LOGINFO("Started server on port " + String(port));
  176. return true;
  177. }
  178. else
  179. {
  180. LOGERROR("Failed to start server on port " + String(port));
  181. return false;
  182. }
  183. }
  184. void Network::StopServer()
  185. {
  186. if (!IsServerRunning())
  187. return;
  188. PROFILE(StopServer);
  189. clientConnections_.Clear();
  190. network_->StopServer();
  191. LOGINFO("Stopped server");
  192. }
  193. void Network::BroadcastMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg)
  194. {
  195. BroadcastMessage(msgID, reliable, inOrder, msg.GetData(), msg.GetSize());
  196. }
  197. void Network::BroadcastMessage(int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes)
  198. {
  199. // Make sure not to use kNet internal message ID's
  200. if (msgID <= 0x4 || msgID >= 0x3ffffffe)
  201. {
  202. LOGERROR("Can not send message with reserved ID");
  203. return;
  204. }
  205. kNet::NetworkServer* server = network_->GetServer();
  206. if (server)
  207. server->BroadcastMessage(msgID, reliable, inOrder, 0, 0, (const char*)data, numBytes);
  208. else
  209. LOGERROR("Server not running, can not broadcast messages");
  210. }
  211. void Network::BroadcastMessage(int msgID, unsigned contentID, bool reliable, bool inOrder, const VectorBuffer& msg)
  212. {
  213. BroadcastMessage(msgID, contentID, reliable, inOrder, msg.GetData(), msg.GetSize());
  214. }
  215. void Network::BroadcastMessage(int msgID, unsigned contentID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes)
  216. {
  217. // Make sure not to use kNet internal message ID's
  218. if (msgID <= 0x4 || msgID >= 0x3ffffffe)
  219. {
  220. LOGERROR("Can not send message with reserved ID");
  221. return;
  222. }
  223. kNet::NetworkServer* server = network_->GetServer();
  224. if (server)
  225. server->BroadcastMessage(msgID, reliable, inOrder, 0, contentID, (const char*)data, numBytes);
  226. else
  227. LOGERROR("Server not running, can not broadcast messages");
  228. }
  229. void Network::BroadcastRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData)
  230. {
  231. for (Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Begin();
  232. i != clientConnections_.End(); ++i)
  233. i->second_->SendRemoteEvent(eventType, inOrder, eventData);
  234. }
  235. void Network::BroadcastRemoteEvent(Scene* scene, StringHash eventType, bool inOrder, const VariantMap& eventData)
  236. {
  237. for (Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Begin();
  238. i != clientConnections_.End(); ++i)
  239. {
  240. if (i->second_->GetScene() == scene)
  241. i->second_->SendRemoteEvent(eventType, inOrder, eventData);
  242. }
  243. }
  244. void Network::BroadcastRemoteEvent(Node* receiver, StringHash eventType, bool inOrder, const VariantMap& eventData)
  245. {
  246. if (!receiver)
  247. {
  248. LOGERROR("Null node for remote node event");
  249. return;
  250. }
  251. if (receiver->GetID() >= FIRST_LOCAL_ID)
  252. {
  253. LOGERROR("Node has a local ID, can not send remote node event");
  254. return;
  255. }
  256. Scene* scene = receiver->GetScene();
  257. for (Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Begin();
  258. i != clientConnections_.End(); ++i)
  259. {
  260. if (i->second_->GetScene() == scene)
  261. i->second_->SendRemoteEvent(receiver, eventType, inOrder, eventData);
  262. }
  263. }
  264. void Network::SetUpdateFps(int fps)
  265. {
  266. updateFps_ = Max(fps, 1);
  267. updateInterval_ = 1.0f / (float)updateFps_;
  268. updateAcc_ = 0.0f;
  269. }
  270. void Network::Update(float timeStep)
  271. {
  272. PROFILE(UpdateNetwork);
  273. // Check if periodic update should be made now
  274. updateAcc_ += timeStep;
  275. bool updateNow = updateAcc_ >= updateInterval_;
  276. if (updateNow)
  277. {
  278. // Notify of the impending update to allow for example updated client controls to be set
  279. SendEvent(E_NETWORKUPDATE);
  280. updateAcc_ = fmodf(updateAcc_, updateInterval_);
  281. }
  282. // Process server connection if it exists
  283. if (serverConnection_)
  284. {
  285. kNet::MessageConnection* connection = serverConnection_->GetMessageConnection();
  286. connection->Process();
  287. // Check for state transitions
  288. kNet::ConnectionState state = connection->GetConnectionState();
  289. if (serverConnection_->IsConnectPending() && state == kNet::ConnectionOK)
  290. OnServerConnected();
  291. else if (state == kNet::ConnectionPeerClosed)
  292. serverConnection_->Disconnect();
  293. else if (state == kNet::ConnectionClosed)
  294. OnServerDisconnected();
  295. // If scene has been assigned and loaded, send the controls packet on update
  296. if (updateNow && serverConnection_->GetScene() && serverConnection_->IsSceneLoaded())
  297. {
  298. const Controls& controls = serverConnection_->GetControls();
  299. VectorBuffer msg;
  300. msg.WriteUInt(controls.buttons_);
  301. msg.WriteFloat(controls.yaw_);
  302. msg.WriteFloat(controls.pitch_);
  303. msg.WriteVariantMap(controls.extraData_);
  304. serverConnection_->SendMessage(MSG_CONTROLSUPDATE, CONTROLS_CONTENT_ID, false, false, msg);
  305. }
  306. }
  307. // Process client connections if the server has been started
  308. kNet::SharedPtr<kNet::NetworkServer> server = network_->GetServer();
  309. if (server)
  310. {
  311. server->Process();
  312. if (updateNow)
  313. {
  314. // Process scene replication for each client connection
  315. for (Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Begin();
  316. i != clientConnections_.End(); ++i)
  317. i->second_->ProcessReplication();
  318. }
  319. }
  320. }
  321. Connection* Network::GetConnection(kNet::MessageConnection* connection) const
  322. {
  323. Map<kNet::MessageConnection*, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Find(connection);
  324. if (i != clientConnections_.End())
  325. return i->second_;
  326. else if (serverConnection_ && serverConnection_->GetMessageConnection() == connection)
  327. return serverConnection_;
  328. else
  329. return 0;
  330. }
  331. Connection* Network::GetServerConnection() const
  332. {
  333. return serverConnection_;
  334. }
  335. bool Network::IsServerRunning() const
  336. {
  337. return network_->GetServer();
  338. }
  339. void Network::OnServerConnected()
  340. {
  341. serverConnection_->SetConnectPending(false);
  342. LOGINFO("Connected to server");
  343. // Send the identity map now
  344. VectorBuffer msg;
  345. msg.WriteVariantMap(serverConnection_->GetIdentity());
  346. serverConnection_->SendMessage(MSG_IDENTITY, true, true, msg);
  347. SendEvent(E_SERVERCONNECTED);
  348. }
  349. void Network::OnServerDisconnected()
  350. {
  351. // Differentiate between failed connection, and disconnection
  352. bool failedConnect = serverConnection_ && serverConnection_->IsConnectPending();
  353. if (!failedConnect)
  354. {
  355. LOGINFO("Disconnected from server");
  356. SendEvent(E_SERVERDISCONNECTED);
  357. }
  358. else
  359. {
  360. LOGERROR("Failed to connect to server");
  361. SendEvent(E_CONNECTFAILED);
  362. }
  363. serverConnection_.Reset();
  364. }
  365. bool Network::OnServerMessage(Connection* connection, int msgID, MemoryBuffer& msg)
  366. {
  367. switch (msgID)
  368. {
  369. case MSG_LOADSCENE:
  370. {
  371. String fileName = msg.ReadString();
  372. Scene* scene = connection->GetScene();
  373. if (scene)
  374. {
  375. if (fileName.Empty())
  376. scene->Clear();
  377. else
  378. {
  379. String extension = GetExtension(fileName);
  380. SharedPtr<File> file(new File(context_, fileName));
  381. bool success;
  382. if (extension == ".xml")
  383. success = scene->LoadAsyncXML(file);
  384. else
  385. success = scene->LoadAsync(file);
  386. if (!success)
  387. {
  388. using namespace NetworkSceneLoadFailed;
  389. VariantMap eventData;
  390. eventData[P_CONNECTION] = (void*)connection;
  391. connection->SendEvent(E_NETWORKSCENELOADFAILED, eventData);
  392. }
  393. }
  394. }
  395. else
  396. LOGERROR("Received a LoadScene message without an assigned scene");
  397. }
  398. return true;
  399. case MSG_SCENECHECKSUMERROR:
  400. {
  401. using namespace NetworkSceneLoadFailed;
  402. VariantMap eventData;
  403. eventData[P_CONNECTION] = (void*)connection;
  404. connection->SendEvent(E_NETWORKSCENELOADFAILED, eventData);
  405. }
  406. return true;
  407. case MSG_REMOTEEVENT:
  408. case MSG_REMOTENODEEVENT:
  409. OnRemoteEvent(connection, msgID, msg);
  410. return true;
  411. }
  412. return false;
  413. }
  414. bool Network::OnClientMessage(Connection* connection, int msgID, MemoryBuffer& msg)
  415. {
  416. switch (msgID)
  417. {
  418. case MSG_IDENTITY:
  419. {
  420. connection->SetIdentity(msg.ReadVariantMap());
  421. using namespace ClientIdentity;
  422. VariantMap eventData = connection->GetIdentity();
  423. eventData[P_CONNECTION] = (void*)connection;
  424. eventData[P_ALLOW] = true;
  425. connection->SendEvent(E_CLIENTIDENTITY, eventData);
  426. // If connection was denied as a response to the event, disconnect the client now
  427. if (!eventData[P_ALLOW].GetBool())
  428. connection->Disconnect();
  429. }
  430. return true;
  431. case MSG_CONTROLSUPDATE:
  432. {
  433. Controls newControls;
  434. newControls.buttons_ = msg.ReadUInt();
  435. newControls.yaw_ = msg.ReadFloat();
  436. newControls.pitch_ = msg.ReadFloat();
  437. newControls.extraData_ = msg.ReadVariantMap();
  438. connection->SetControls(newControls);
  439. }
  440. return true;
  441. case MSG_SCENELOADED:
  442. {
  443. unsigned checksum = msg.ReadUInt();
  444. Scene* scene = connection->GetScene();
  445. if (scene)
  446. {
  447. if (checksum != scene->GetChecksum())
  448. {
  449. VectorBuffer replyMsg;
  450. connection->SendMessage(MSG_SCENECHECKSUMERROR, true, true, replyMsg);
  451. using namespace NetworkSceneLoadFailed;
  452. VariantMap eventData;
  453. eventData[P_CONNECTION] = (void*)connection;
  454. connection->SendEvent(E_NETWORKSCENELOADFAILED, eventData);
  455. }
  456. else
  457. {
  458. connection->SetSceneLoaded(true);
  459. using namespace ClientSceneLoaded;
  460. VariantMap eventData;
  461. eventData[P_CONNECTION] = (void*)connection;
  462. connection->SendEvent(E_CLIENTSCENELOADED, eventData);
  463. }
  464. }
  465. else
  466. LOGWARNING("Client sent a SceneLoaded message without an assigned scene");
  467. }
  468. return true;
  469. case MSG_REMOTEEVENT:
  470. case MSG_REMOTENODEEVENT:
  471. OnRemoteEvent(connection, msgID, msg);
  472. return true;
  473. }
  474. return false;
  475. }
  476. void Network::OnRemoteEvent(Connection* connection, int msgID, MemoryBuffer& msg)
  477. {
  478. /// \todo Check whether the remote event is allowed based on a black- or whitelist
  479. if (msgID == MSG_REMOTEEVENT)
  480. {
  481. StringHash eventType = msg.ReadStringHash();
  482. VariantMap eventData = msg.ReadVariantMap();
  483. connection->SendEvent(eventType, eventData);
  484. }
  485. else
  486. {
  487. Scene* scene = connection->GetScene();
  488. if (!scene)
  489. {
  490. LOGERROR("Connection has null scene, can not receive remote node event");
  491. return;
  492. }
  493. unsigned nodeID = msg.ReadVLE();
  494. StringHash eventType = msg.ReadStringHash();
  495. VariantMap eventData = msg.ReadVariantMap();
  496. Node* receiver = scene->GetNodeByID(nodeID);
  497. if (!receiver)
  498. {
  499. LOGWARNING("Remote node event's receiver not found, discarding event");
  500. return;
  501. }
  502. connection->SendEvent(receiver, eventType, eventData);
  503. }
  504. }
  505. void Network::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
  506. {
  507. using namespace BeginFrame;
  508. Update(eventData[P_TIMESTEP].GetFloat());
  509. }
  510. void Network::HandleAsyncLoadFinished(StringHash eventType, VariantMap& eventData)
  511. {
  512. if (!serverConnection_)
  513. return;
  514. Scene* scene = serverConnection_->GetScene();
  515. using namespace AsyncLoadFinished;
  516. if ((void*)scene == eventData[P_SCENE].GetPtr())
  517. {
  518. VectorBuffer msg;
  519. msg.WriteUInt(scene->GetChecksum());
  520. serverConnection_->SendMessage(MSG_SCENELOADED, true, true, msg);
  521. }
  522. }