2
0

Network.cpp 16 KB

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