Network.cpp 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734
  1. //
  2. // Copyright (c) 2008-2018 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/Context.h"
  24. #include "../Core/CoreEvents.h"
  25. #include "../Core/Profiler.h"
  26. #include "../Engine/EngineEvents.h"
  27. #include "../IO/FileSystem.h"
  28. #include "../Input/InputEvents.h"
  29. #include "../IO/IOEvents.h"
  30. #include "../IO/Log.h"
  31. #include "../IO/MemoryBuffer.h"
  32. #include "../Network/HttpRequest.h"
  33. #include "../Network/Network.h"
  34. #include "../Network/NetworkEvents.h"
  35. #include "../Network/NetworkPriority.h"
  36. #include "../Network/Protocol.h"
  37. #include "../Scene/Scene.h"
  38. #include <SLikeNet/MessageIdentifiers.h>
  39. #include <SLikeNet/NatPunchthroughClient.h>
  40. #include <SLikeNet/peerinterface.h>
  41. #include <SLikeNet/statistics.h>
  42. #include <SLikeNet/FullyConnectedMesh2.h>
  43. #include <SLikeNet/DS_List.h>
  44. #include <SLikeNet/BitStream.h>
  45. #include <SLikeNet/ReadyEvent.h>
  46. #include <SLikeNet/ConnectionGraph2.h>
  47. #ifdef SendMessage
  48. #undef SendMessage
  49. #endif
  50. #include "../DebugNew.h"
  51. namespace Urho3D
  52. {
  53. static const char* RAKNET_MESSAGEID_STRINGS[] = {
  54. "ID_CONNECTED_PING",
  55. "ID_UNCONNECTED_PING",
  56. "ID_UNCONNECTED_PING_OPEN_CONNECTIONS",
  57. "ID_CONNECTED_PONG",
  58. "ID_DETECT_LOST_CONNECTIONS",
  59. "ID_OPEN_CONNECTION_REQUEST_1",
  60. "ID_OPEN_CONNECTION_REPLY_1",
  61. "ID_OPEN_CONNECTION_REQUEST_2",
  62. "ID_OPEN_CONNECTION_REPLY_2",
  63. "ID_CONNECTION_REQUEST",
  64. "ID_REMOTE_SYSTEM_REQUIRES_PUBLIC_KEY",
  65. "ID_OUR_SYSTEM_REQUIRES_SECURITY",
  66. "ID_PUBLIC_KEY_MISMATCH",
  67. "ID_OUT_OF_BAND_INTERNAL",
  68. "ID_SND_RECEIPT_ACKED",
  69. "ID_SND_RECEIPT_LOSS",
  70. "ID_CONNECTION_REQUEST_ACCEPTED",
  71. "ID_CONNECTION_ATTEMPT_FAILED",
  72. "ID_ALREADY_CONNECTED",
  73. "ID_NEW_INCOMING_CONNECTION",
  74. "ID_NO_FREE_INCOMING_CONNECTIONS",
  75. "ID_DISCONNECTION_NOTIFICATION",
  76. "ID_CONNECTION_LOST",
  77. "ID_CONNECTION_BANNED",
  78. "ID_INVALID_PASSWORD",
  79. "ID_INCOMPATIBLE_PROTOCOL_VERSION",
  80. "ID_IP_RECENTLY_CONNECTED",
  81. "ID_TIMESTAMP",
  82. "ID_UNCONNECTED_PONG",
  83. "ID_ADVERTISE_SYSTEM",
  84. "ID_DOWNLOAD_PROGRESS",
  85. "ID_REMOTE_DISCONNECTION_NOTIFICATION",
  86. "ID_REMOTE_CONNECTION_LOST",
  87. "ID_REMOTE_NEW_INCOMING_CONNECTION",
  88. "ID_FILE_LIST_TRANSFER_HEADER",
  89. "ID_FILE_LIST_TRANSFER_FILE",
  90. "ID_FILE_LIST_REFERENCE_PUSH_ACK",
  91. "ID_DDT_DOWNLOAD_REQUEST",
  92. "ID_TRANSPORT_STRING",
  93. "ID_REPLICA_MANAGER_CONSTRUCTION",
  94. "ID_REPLICA_MANAGER_SCOPE_CHANGE",
  95. "ID_REPLICA_MANAGER_SERIALIZE",
  96. "ID_REPLICA_MANAGER_DOWNLOAD_STARTED",
  97. "ID_REPLICA_MANAGER_DOWNLOAD_COMPLETE",
  98. "ID_RAKVOICE_OPEN_CHANNEL_REQUEST",
  99. "ID_RAKVOICE_OPEN_CHANNEL_REPLY",
  100. "ID_RAKVOICE_CLOSE_CHANNEL",
  101. "ID_RAKVOICE_DATA",
  102. "ID_AUTOPATCHER_GET_CHANGELIST_SINCE_DATE",
  103. "ID_AUTOPATCHER_CREATION_LIST",
  104. "ID_AUTOPATCHER_DELETION_LIST",
  105. "ID_AUTOPATCHER_GET_PATCH",
  106. "ID_AUTOPATCHER_PATCH_LIST",
  107. "ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR",
  108. "ID_AUTOPATCHER_CANNOT_DOWNLOAD_ORIGINAL_UNMODIFIED_FILES",
  109. "ID_AUTOPATCHER_FINISHED_INTERNAL",
  110. "ID_AUTOPATCHER_FINISHED",
  111. "ID_AUTOPATCHER_RESTART_APPLICATION",
  112. "ID_NAT_PUNCHTHROUGH_REQUEST",
  113. "ID_NAT_CONNECT_AT_TIME",
  114. "ID_NAT_GET_MOST_RECENT_PORT",
  115. "ID_NAT_CLIENT_READY",
  116. "ID_NAT_TARGET_NOT_CONNECTED",
  117. "ID_NAT_TARGET_UNRESPONSIVE",
  118. "ID_NAT_CONNECTION_TO_TARGET_LOST",
  119. "ID_NAT_ALREADY_IN_PROGRESS",
  120. "ID_NAT_PUNCHTHROUGH_FAILED",
  121. "ID_NAT_PUNCHTHROUGH_SUCCEEDED",
  122. "ID_READY_EVENT_SET",
  123. "ID_READY_EVENT_UNSET",
  124. "ID_READY_EVENT_ALL_SET",
  125. "ID_READY_EVENT_QUERY",
  126. "ID_LOBBY_GENERAL",
  127. "ID_RPC_REMOTE_ERROR",
  128. "ID_RPC_PLUGIN",
  129. "ID_FILE_LIST_REFERENCE_PUSH",
  130. "ID_READY_EVENT_FORCE_ALL_SET",
  131. "ID_ROOMS_EXECUTE_FUNC",
  132. "ID_ROOMS_LOGON_STATUS",
  133. "ID_ROOMS_HANDLE_CHANGE",
  134. "ID_LOBBY2_SEND_MESSAGE",
  135. "ID_LOBBY2_SERVER_ERROR",
  136. "ID_FCM2_NEW_HOST",
  137. "ID_FCM2_REQUEST_FCMGUID",
  138. "ID_FCM2_RESPOND_CONNECTION_COUNT",
  139. "ID_FCM2_INFORM_FCMGUID",
  140. "ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT",
  141. "ID_FCM2_VERIFIED_JOIN_START",
  142. "ID_FCM2_VERIFIED_JOIN_CAPABLE",
  143. "ID_FCM2_VERIFIED_JOIN_FAILED",
  144. "ID_FCM2_VERIFIED_JOIN_ACCEPTED",
  145. "ID_FCM2_VERIFIED_JOIN_REJECTED",
  146. "ID_UDP_PROXY_GENERAL",
  147. "ID_SQLite3_EXEC",
  148. "ID_SQLite3_UNKNOWN_DB",
  149. "ID_SQLLITE_LOGGER",
  150. "ID_NAT_TYPE_DETECTION_REQUEST",
  151. "ID_NAT_TYPE_DETECTION_RESULT",
  152. "ID_ROUTER_2_INTERNAL",
  153. "ID_ROUTER_2_FORWARDING_NO_PATH",
  154. "ID_ROUTER_2_FORWARDING_ESTABLISHED",
  155. "ID_ROUTER_2_REROUTED",
  156. "ID_TEAM_BALANCER_INTERNAL",
  157. "ID_TEAM_BALANCER_REQUESTED_TEAM_FULL",
  158. "ID_TEAM_BALANCER_REQUESTED_TEAM_LOCKED",
  159. "ID_TEAM_BALANCER_TEAM_REQUESTED_CANCELLED",
  160. "ID_TEAM_BALANCER_TEAM_ASSIGNED",
  161. "ID_LIGHTSPEED_INTEGRATION",
  162. "ID_XBOX_LOBBY",
  163. "ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_SUCCESS",
  164. "ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_SUCCESS",
  165. "ID_TWO_WAY_AUTHENTICATION_INCOMING_CHALLENGE_FAILURE",
  166. "ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_FAILURE",
  167. "ID_TWO_WAY_AUTHENTICATION_OUTGOING_CHALLENGE_TIMEOUT",
  168. "ID_TWO_WAY_AUTHENTICATION_NEGOTIATION",
  169. "ID_CLOUD_POST_REQUEST",
  170. "ID_CLOUD_RELEASE_REQUEST",
  171. "ID_CLOUD_GET_REQUEST",
  172. "ID_CLOUD_GET_RESPONSE",
  173. "ID_CLOUD_UNSUBSCRIBE_REQUEST",
  174. "ID_CLOUD_SERVER_TO_SERVER_COMMAND",
  175. "ID_CLOUD_SUBSCRIPTION_NOTIFICATION",
  176. "ID_LIB_VOICE",
  177. "ID_RELAY_PLUGIN",
  178. "ID_NAT_REQUEST_BOUND_ADDRESSES",
  179. "ID_NAT_RESPOND_BOUND_ADDRESSES",
  180. "ID_FCM2_UPDATE_USER_CONTEXT",
  181. "ID_RESERVED_3",
  182. "ID_RESERVED_4",
  183. "ID_RESERVED_5",
  184. "ID_RESERVED_6",
  185. "ID_RESERVED_7",
  186. "ID_RESERVED_8",
  187. "ID_RESERVED_9",
  188. "ID_USER_PACKET_ENUM"
  189. };
  190. static const int DEFAULT_UPDATE_FPS = 30;
  191. static const int SERVER_TIMEOUT_TIME = 5000;
  192. Network::Network(Context* context) :
  193. Object(context),
  194. updateFps_(DEFAULT_UPDATE_FPS),
  195. simulatedLatency_(0),
  196. simulatedPacketLoss_(0.0f),
  197. updateInterval_(1.0f / (float)DEFAULT_UPDATE_FPS),
  198. updateAcc_(0.0f),
  199. isServer_(false),
  200. scene_(nullptr),
  201. natPunchServerAddress_(nullptr),
  202. remoteGUID_(nullptr),
  203. networkMode_(SERVER_CLIENT),
  204. natAutoReconnect_(true),
  205. allowedConnectionCount_(128),
  206. fullyConnectedMesh2_(nullptr),
  207. connectionGraph2_(nullptr),
  208. readyEvent_(nullptr)
  209. {
  210. rakPeer_ = SLNet::RakPeerInterface::GetInstance();
  211. rakPeerClient_ = SLNet::RakPeerInterface::GetInstance();
  212. rakPeer_->SetTimeoutTime(SERVER_TIMEOUT_TIME, SLNet::UNASSIGNED_SYSTEM_ADDRESS);
  213. rakPeerClient_->SetTimeoutTime(SERVER_TIMEOUT_TIME, SLNet::UNASSIGNED_SYSTEM_ADDRESS);
  214. // rakPeer_->AttachPlugin(new PacketLogger());
  215. SetPassword("");
  216. SetDiscoveryBeacon(VariantMap());
  217. natPunchthroughClient_ = new SLNet::NatPunchthroughClient;
  218. natPunchthroughServerClient_ = new SLNet::NatPunchthroughClient;
  219. SetNATServerInfo("127.0.0.1", 61111);
  220. // Register Network library object factories
  221. RegisterNetworkLibrary(context_);
  222. SubscribeToEvent(E_BEGINFRAME, URHO3D_HANDLER(Network, HandleBeginFrame));
  223. SubscribeToEvent(E_RENDERUPDATE, URHO3D_HANDLER(Network, HandleRenderUpdate));
  224. // Blacklist remote events which are not to be allowed to be registered in any case
  225. blacklistedRemoteEvents_.Insert(E_CONSOLECOMMAND);
  226. blacklistedRemoteEvents_.Insert(E_LOGMESSAGE);
  227. blacklistedRemoteEvents_.Insert(E_BEGINFRAME);
  228. blacklistedRemoteEvents_.Insert(E_UPDATE);
  229. blacklistedRemoteEvents_.Insert(E_POSTUPDATE);
  230. blacklistedRemoteEvents_.Insert(E_RENDERUPDATE);
  231. blacklistedRemoteEvents_.Insert(E_ENDFRAME);
  232. blacklistedRemoteEvents_.Insert(E_MOUSEBUTTONDOWN);
  233. blacklistedRemoteEvents_.Insert(E_MOUSEBUTTONUP);
  234. blacklistedRemoteEvents_.Insert(E_MOUSEMOVE);
  235. blacklistedRemoteEvents_.Insert(E_MOUSEWHEEL);
  236. blacklistedRemoteEvents_.Insert(E_KEYDOWN);
  237. blacklistedRemoteEvents_.Insert(E_KEYUP);
  238. blacklistedRemoteEvents_.Insert(E_TEXTINPUT);
  239. blacklistedRemoteEvents_.Insert(E_JOYSTICKCONNECTED);
  240. blacklistedRemoteEvents_.Insert(E_JOYSTICKDISCONNECTED);
  241. blacklistedRemoteEvents_.Insert(E_JOYSTICKBUTTONDOWN);
  242. blacklistedRemoteEvents_.Insert(E_JOYSTICKBUTTONUP);
  243. blacklistedRemoteEvents_.Insert(E_JOYSTICKAXISMOVE);
  244. blacklistedRemoteEvents_.Insert(E_JOYSTICKHATMOVE);
  245. blacklistedRemoteEvents_.Insert(E_TOUCHBEGIN);
  246. blacklistedRemoteEvents_.Insert(E_TOUCHEND);
  247. blacklistedRemoteEvents_.Insert(E_TOUCHMOVE);
  248. blacklistedRemoteEvents_.Insert(E_GESTURERECORDED);
  249. blacklistedRemoteEvents_.Insert(E_GESTUREINPUT);
  250. blacklistedRemoteEvents_.Insert(E_MULTIGESTURE);
  251. blacklistedRemoteEvents_.Insert(E_DROPFILE);
  252. blacklistedRemoteEvents_.Insert(E_INPUTFOCUS);
  253. blacklistedRemoteEvents_.Insert(E_MOUSEVISIBLECHANGED);
  254. blacklistedRemoteEvents_.Insert(E_EXITREQUESTED);
  255. blacklistedRemoteEvents_.Insert(E_SERVERCONNECTED);
  256. blacklistedRemoteEvents_.Insert(E_SERVERDISCONNECTED);
  257. blacklistedRemoteEvents_.Insert(E_CONNECTFAILED);
  258. blacklistedRemoteEvents_.Insert(E_CLIENTCONNECTED);
  259. blacklistedRemoteEvents_.Insert(E_CLIENTDISCONNECTED);
  260. blacklistedRemoteEvents_.Insert(E_CLIENTIDENTITY);
  261. blacklistedRemoteEvents_.Insert(E_CLIENTSCENELOADED);
  262. blacklistedRemoteEvents_.Insert(E_NETWORKMESSAGE);
  263. blacklistedRemoteEvents_.Insert(E_NETWORKUPDATE);
  264. blacklistedRemoteEvents_.Insert(E_NETWORKUPDATESENT);
  265. blacklistedRemoteEvents_.Insert(E_NETWORKSCENELOADFAILED);
  266. blacklistedRemoteEvents_.Insert(E_NATMASTERCONNECTIONSUCCEEDED);
  267. blacklistedRemoteEvents_.Insert(E_NATMASTERCONNECTIONFAILED);
  268. blacklistedRemoteEvents_.Insert(E_NETWORKNATPUNCHTROUGHSUCCEEDED);
  269. blacklistedRemoteEvents_.Insert(E_NETWORKNATPUNCHTROUGHFAILED);
  270. blacklistedRemoteEvents_.Insert(E_P2PJOINREQUESTDENIED);
  271. blacklistedRemoteEvents_.Insert(E_P2PALLREADYCHANGED);
  272. blacklistedRemoteEvents_.Insert(E_NETWORKHOSTDISCOVERED);
  273. blacklistedRemoteEvents_.Insert(E_NETWORKINVALIDPASSWORD);
  274. blacklistedRemoteEvents_.Insert(E_P2PNEWHOST);
  275. blacklistedRemoteEvents_.Insert(E_P2PSESSIONSTARTED);
  276. RegisterRemoteEvent(E_NETWORKBANNED);
  277. }
  278. Network::~Network()
  279. {
  280. // If server connection exists, disconnect, but do not send an event because we are shutting down
  281. Disconnect(1000);
  282. if (fullyConnectedMesh2_)
  283. fullyConnectedMesh2_->ResetHostCalculation();
  284. rakPeer_->DetachPlugin(natPunchthroughServerClient_);
  285. rakPeerClient_->DetachPlugin(natPunchthroughClient_);
  286. SLNet::NatPunchthroughClient::DestroyInstance(natPunchthroughServerClient_);
  287. natPunchthroughServerClient_ = nullptr;
  288. SLNet::NatPunchthroughClient::DestroyInstance(natPunchthroughClient_);
  289. natPunchthroughClient_ = nullptr;
  290. if (fullyConnectedMesh2_) {
  291. rakPeer_->DetachPlugin(fullyConnectedMesh2_);
  292. SLNet::FullyConnectedMesh2::DestroyInstance(fullyConnectedMesh2_);
  293. fullyConnectedMesh2_ = nullptr;
  294. }
  295. if (connectionGraph2_) {
  296. rakPeer_->DetachPlugin(connectionGraph2_);
  297. SLNet::ConnectionGraph2::DestroyInstance(connectionGraph2_);
  298. connectionGraph2_ = nullptr;
  299. }
  300. if (readyEvent_) {
  301. rakPeer_->DetachPlugin(readyEvent_);
  302. SLNet::ReadyEvent::DestroyInstance(readyEvent_);
  303. readyEvent_ = nullptr;
  304. }
  305. serverConnection_.Reset();
  306. clientConnections_.Clear();
  307. delete remoteGUID_;
  308. remoteGUID_ = nullptr;
  309. delete natPunchServerAddress_;
  310. natPunchServerAddress_ = nullptr;
  311. SLNet::RakPeerInterface::DestroyInstance(rakPeer_);
  312. SLNet::RakPeerInterface::DestroyInstance(rakPeerClient_);
  313. rakPeer_ = nullptr;
  314. rakPeerClient_ = nullptr;
  315. }
  316. void Network::HandleMessage(const SLNet::AddressOrGUID& source, int packetID, int msgID, const char* data, size_t numBytes)
  317. {
  318. // Only process messages from known sources
  319. Connection* connection = GetConnection(source);
  320. if (connection)
  321. {
  322. MemoryBuffer msg(data, (unsigned)numBytes);
  323. if (connection->ProcessMessage((int)msgID, msg))
  324. return;
  325. // If message was not handled internally, forward as an event
  326. using namespace NetworkMessage;
  327. VariantMap& eventData = GetEventDataMap();
  328. eventData[P_CONNECTION] = connection;
  329. eventData[P_MESSAGEID] = (int)msgID;
  330. eventData[P_DATA].SetBuffer(msg.GetData(), msg.GetSize());
  331. connection->SendEvent(E_NETWORKMESSAGE, eventData);
  332. }
  333. else {
  334. URHO3D_LOGWARNING("Discarding message from unknown MessageConnection " + String(source.ToString()) + " => " + source.rakNetGuid.ToString());
  335. }
  336. }
  337. void Network::NewConnectionEstablished(const SLNet::AddressOrGUID& connection, const char* address)
  338. {
  339. if (allowedConnectionCount_ == 0 || GetClientConnections().Size() >= allowedConnectionCount_) {
  340. URHO3D_LOGWARNING("Server is full, dropping incoming connection!");
  341. rakPeer_->CloseConnection(connection, true);
  342. return;
  343. }
  344. ReadyStatusChanged();
  345. // It is possible that in P2P mode the incomming connection is already registered
  346. if (networkMode_ == PEER_TO_PEER && clientConnections_[connection]) {
  347. //TODO proper scene state management
  348. clientConnections_[connection]->SetSceneLoaded(true);
  349. SendOutIdentityToPeers();
  350. return;
  351. }
  352. // Create a new client connection corresponding to this MessageConnection
  353. SharedPtr<Connection> newConnection(new Connection(context_, true, connection, rakPeer_));
  354. newConnection->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  355. // All peers should share the same scene
  356. if (networkMode_ == PEER_TO_PEER && serverConnection_) {
  357. newConnection->SetScene(serverConnection_->GetScene());
  358. newConnection->SetSceneLoaded(true);
  359. }
  360. newConnection->SetIP(address);
  361. clientConnections_[connection] = newConnection;
  362. URHO3D_LOGINFO("Client " + newConnection->ToString() + " connected");
  363. using namespace ClientConnected;
  364. VariantMap& eventData = GetEventDataMap();
  365. eventData[P_CONNECTION] = newConnection;
  366. newConnection->SendEvent(E_CLIENTCONNECTED, eventData);
  367. // Let all our peers know who we are
  368. if (networkMode_ == PEER_TO_PEER) {
  369. SendOutIdentityToPeers();
  370. }
  371. }
  372. void Network::SendOutIdentityToPeers()
  373. {
  374. if (serverConnection_) {
  375. // Send our identity to all connected peers
  376. auto clients = GetClientConnections();
  377. for (auto it = clients.Begin(); it != clients.End(); ++it) {
  378. VectorBuffer msg;
  379. msg.WriteVariantMap(serverConnection_->GetIdentity());
  380. (*it)->SendMessage(MSG_IDENTITY, true, true, msg);
  381. }
  382. }
  383. }
  384. void Network::ClientDisconnected(const SLNet::AddressOrGUID& connection)
  385. {
  386. // Remove the client connection that corresponds to this MessageConnection
  387. HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Find(connection);
  388. if (i != clientConnections_.End())
  389. {
  390. Connection* connection = i->second_;
  391. URHO3D_LOGINFO("Client " + connection->ToString() + " disconnected");
  392. using namespace ClientDisconnected;
  393. VariantMap& eventData = GetEventDataMap();
  394. eventData[P_CONNECTION] = connection;
  395. connection->SendEvent(E_CLIENTDISCONNECTED, eventData);
  396. clientConnections_.Erase(i);
  397. }
  398. ReadyStatusChanged();
  399. }
  400. void Network::SetDiscoveryBeacon(const VariantMap& data)
  401. {
  402. VectorBuffer buffer;
  403. buffer.WriteVariantMap(data);
  404. if (buffer.GetSize() > 400)
  405. URHO3D_LOGERROR("Discovery beacon of size: " + String(buffer.GetSize()) + " bytes is too large, modify MAX_OFFLINE_DATA_LENGTH in RakNet or reduce size");
  406. rakPeer_->SetOfflinePingResponse((const char*)buffer.GetData(), buffer.GetSize());
  407. }
  408. void Network::DiscoverHosts(unsigned port)
  409. {
  410. // JSandusky: Contrary to the manual, we actually do have to perform Startup first before we can Ping
  411. if (!rakPeerClient_->IsActive())
  412. {
  413. SLNet::SocketDescriptor socket;
  414. // Startup local connection with max 1 incoming connection(first param) and 1 socket description (third param)
  415. rakPeerClient_->Startup(2, &socket, 1);
  416. rakPeerClient_->SetMaximumIncomingConnections(2);
  417. }
  418. rakPeerClient_->Ping("255.255.255.255", port, false);
  419. }
  420. void Network::SetPassword(const String& password)
  421. {
  422. rakPeer_->SetIncomingPassword(password.CString(), password.Length());
  423. password_ = password;
  424. }
  425. bool Network::Connect(const String& address, unsigned short port, Scene* scene, const VariantMap& identity)
  426. {
  427. URHO3D_PROFILE(Connect);
  428. if (!rakPeerClient_->IsActive())
  429. {
  430. SLNet::SocketDescriptor socket;
  431. // Startup local connection with max 2 incoming connections(first param) and 1 socket description (third param)
  432. rakPeerClient_->Startup(2, &socket, 1);
  433. rakPeerClient_->SetMaximumIncomingConnections(2);
  434. }
  435. //isServer_ = false;
  436. SLNet::ConnectionAttemptResult connectResult = rakPeerClient_->Connect(address.CString(), port, password_.CString(), password_.Length());
  437. if (connectResult != SLNet::CONNECTION_ATTEMPT_STARTED)
  438. {
  439. URHO3D_LOGERROR("Failed to connect to server " + address + ":" + String(port) + ", error code: " + String((int)connectResult));
  440. SendEvent(E_CONNECTFAILED);
  441. return false;
  442. }
  443. else
  444. {
  445. serverConnection_ = new Connection(context_, false, rakPeerClient_->GetMyGUID(), rakPeerClient_);
  446. serverConnection_->SetScene(scene);
  447. serverConnection_->SetIdentity(identity);
  448. serverConnection_->SetConnectPending(true);
  449. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  450. URHO3D_LOGINFO("Connecting to server " + address + ":" + String(port) + ", Client: " + serverConnection_->ToString());
  451. return true;
  452. }
  453. }
  454. bool Network::ConnectNAT(const String& address, unsigned short port)
  455. {
  456. URHO3D_PROFILE(ConnectNAT);
  457. if (!rakPeer_->IsActive())
  458. {
  459. SLNet::SocketDescriptor socket;
  460. // Startup local connection with max 2 incoming connections(first param) and 1 socket description (third param)
  461. rakPeer_->Startup(128, &socket, 1);
  462. rakPeer_->SetMaximumIncomingConnections(allowedConnectionCount_);
  463. rakPeer_->AttachPlugin(natPunchthroughServerClient_);
  464. }
  465. SLNet::ConnectionAttemptResult connectResult = rakPeer_->Connect(address.CString(), port, nullptr, 0);
  466. if (connectResult == SLNet::ALREADY_CONNECTED_TO_ENDPOINT) {
  467. SendEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  468. URHO3D_LOGWARNING("Already connected to server " + address + ":" + String(port) + ", error code: " + String((int)connectResult));
  469. return false;
  470. }
  471. if (connectResult != SLNet::CONNECTION_ATTEMPT_STARTED)
  472. {
  473. URHO3D_LOGERROR("Failed to connect to server " + address + ":" + String(port) + ", error code: " + String((int)connectResult));
  474. SendEvent(E_CONNECTFAILED);
  475. return false;
  476. }
  477. else
  478. {
  479. URHO3D_LOGINFO("Connecting to server " + address + ":" + String(port));
  480. return true;
  481. }
  482. }
  483. void Network::Disconnect(int waitMSec)
  484. {
  485. URHO3D_PROFILE(Disconnect);
  486. if (networkMode_ == PEER_TO_PEER) {
  487. rakPeer_->Shutdown(waitMSec);
  488. clientConnections_.Clear();
  489. }
  490. if (serverConnection_) {
  491. serverConnection_->Disconnect(waitMSec);
  492. serverConnection_.Reset();
  493. }
  494. if (rakPeerClient_->IsActive()) {
  495. rakPeerClient_->Shutdown(1000);
  496. }
  497. natPunchthroughClient_->Clear();
  498. isServer_ = false;
  499. }
  500. bool Network::StartServer(unsigned short port)
  501. {
  502. if (IsServerRunning())
  503. return true;
  504. URHO3D_PROFILE(StartServer);
  505. SLNet::SocketDescriptor socket;//(port, AF_INET);
  506. socket.port = port;
  507. socket.socketFamily = AF_INET;
  508. // Startup local connection with max 128 incoming connection(first param) and 1 socket description (third param)
  509. SLNet::StartupResult startResult = rakPeer_->Startup(128, &socket, 1);
  510. if (startResult == SLNet::RAKNET_STARTED)
  511. {
  512. URHO3D_LOGINFO("Started server on port " + String(port));
  513. rakPeer_->SetMaximumIncomingConnections(allowedConnectionCount_);
  514. isServer_ = true;
  515. rakPeer_->SetOccasionalPing(true);
  516. rakPeer_->SetUnreliableTimeout(1000);
  517. //rakPeer_->SetIncomingPassword("Parole", (int)strlen("Parole"));
  518. return true;
  519. }
  520. else
  521. {
  522. URHO3D_LOGINFO("Failed to start server on port " + String(port) + ", error code: " + String((int)startResult));
  523. return false;
  524. }
  525. }
  526. void Network::StopServer()
  527. {
  528. clientConnections_.Clear();
  529. if (!rakPeer_)
  530. return;
  531. if (!IsServerRunning())
  532. return;
  533. // Provide 300 ms to notify
  534. rakPeer_->Shutdown(300);
  535. URHO3D_PROFILE(StopServer);
  536. URHO3D_LOGINFO("Stopped server");
  537. }
  538. void Network::SetNATServerInfo(const String& address, unsigned short port)
  539. {
  540. if (!natPunchServerAddress_)
  541. natPunchServerAddress_ = new SLNet::SystemAddress;
  542. natPunchServerAddress_->FromStringExplicitPort(address.CString(), port);
  543. }
  544. void Network::StartNATClient()
  545. {
  546. if (!rakPeer_) {
  547. URHO3D_LOGERROR("Unable to start NAT client, client not initialized!");
  548. return;
  549. }
  550. if (natPunchServerAddress_->GetPort() == 0) {
  551. URHO3D_LOGERROR("NAT master server address incorrect!");
  552. return;
  553. }
  554. rakPeer_->AttachPlugin(natPunchthroughServerClient_);
  555. guid_ = String(rakPeer_->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
  556. URHO3D_LOGINFO("GUID: " + guid_);
  557. rakPeer_->Connect(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort(), nullptr, 0);
  558. }
  559. void Network::AttemptNATPunchtrough(const String& guid, Scene* scene, const VariantMap& identity)
  560. {
  561. scene_ = scene;
  562. identity_ = identity;
  563. if (!remoteGUID_)
  564. remoteGUID_ = new SLNet::RakNetGUID;
  565. remoteGUID_->FromString(guid.CString());
  566. if (rakPeerClient_->IsActive()) {
  567. rakPeerClient_->Shutdown(1000);
  568. }
  569. natPunchthroughClient_->Clear();
  570. rakPeerClient_->AttachPlugin(natPunchthroughClient_);
  571. SLNet::SocketDescriptor socket;
  572. // Startup local connection with max 2 incoming connections(first param) and 1 socket description (third param)
  573. rakPeerClient_->Startup(2, &socket, 1);
  574. rakPeerClient_->SetMaximumIncomingConnections(2);
  575. SLNet::ConnectionAttemptResult connectResult = rakPeerClient_->Connect(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort(), nullptr, 0);
  576. URHO3D_LOGINFO("AttemptNATPunchtrough status " + String((int) connectResult));
  577. }
  578. void Network::BroadcastMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID)
  579. {
  580. BroadcastMessage(msgID, reliable, inOrder, msg.GetData(), msg.GetSize(), contentID);
  581. }
  582. void Network::BroadcastMessage(int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes,
  583. unsigned contentID)
  584. {
  585. if (!rakPeer_)
  586. return;
  587. /* Make sure not to use SLikeNet(RakNet) internal message ID's
  588. and since RakNet uses 1 byte message ID's, they cannot exceed 255 limit */
  589. if (msgID < ID_USER_PACKET_ENUM || msgID >= 255)
  590. {
  591. URHO3D_LOGERROR("Can not send message with reserved ID");
  592. return;
  593. }
  594. VectorBuffer msgData;
  595. msgData.WriteUByte((unsigned char)msgID);
  596. msgData.Write(data, numBytes);
  597. if (isServer_ || networkMode_ == PEER_TO_PEER) {
  598. rakPeer_->Send((const char *) msgData.GetData(), (int) msgData.GetSize(), HIGH_PRIORITY, RELIABLE, (char) 0, SLNet::UNASSIGNED_RAKNET_GUID, true);
  599. }
  600. else
  601. URHO3D_LOGERROR("Server not running, can not broadcast messages");
  602. }
  603. void Network::BroadcastRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData)
  604. {
  605. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin(); i != clientConnections_.End(); ++i)
  606. i->second_->SendRemoteEvent(eventType, inOrder, eventData);
  607. }
  608. void Network::BroadcastRemoteEvent(Scene* scene, StringHash eventType, bool inOrder, const VariantMap& eventData)
  609. {
  610. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  611. i != clientConnections_.End(); ++i)
  612. {
  613. if (i->second_->GetScene() == scene)
  614. i->second_->SendRemoteEvent(eventType, inOrder, eventData);
  615. }
  616. }
  617. void Network::BroadcastRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData)
  618. {
  619. if (!node)
  620. {
  621. URHO3D_LOGERROR("Null sender node for remote node event");
  622. return;
  623. }
  624. if (!node->IsReplicated())
  625. {
  626. URHO3D_LOGERROR("Sender node has a local ID, can not send remote node event");
  627. return;
  628. }
  629. Scene* scene = node->GetScene();
  630. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  631. i != clientConnections_.End(); ++i)
  632. {
  633. if (i->second_->GetScene() == scene)
  634. i->second_->SendRemoteEvent(node, eventType, inOrder, eventData);
  635. }
  636. }
  637. void Network::SetUpdateFps(int fps)
  638. {
  639. updateFps_ = Max(fps, 1);
  640. updateInterval_ = 1.0f / (float)updateFps_;
  641. updateAcc_ = 0.0f;
  642. }
  643. void Network::SetSimulatedLatency(int ms)
  644. {
  645. simulatedLatency_ = Max(ms, 0);
  646. ConfigureNetworkSimulator();
  647. }
  648. void Network::SetSimulatedPacketLoss(float probability)
  649. {
  650. simulatedPacketLoss_ = Clamp(probability, 0.0f, 1.0f);
  651. ConfigureNetworkSimulator();
  652. }
  653. void Network::RegisterRemoteEvent(StringHash eventType)
  654. {
  655. if (blacklistedRemoteEvents_.Find(eventType) != blacklistedRemoteEvents_.End())
  656. {
  657. URHO3D_LOGERROR("Attempted to register blacklisted remote event type " + String(eventType));
  658. return;
  659. }
  660. allowedRemoteEvents_.Insert(eventType);
  661. }
  662. void Network::UnregisterRemoteEvent(StringHash eventType)
  663. {
  664. allowedRemoteEvents_.Erase(eventType);
  665. }
  666. void Network::UnregisterAllRemoteEvents()
  667. {
  668. allowedRemoteEvents_.Clear();
  669. }
  670. void Network::SetPackageCacheDir(const String& path)
  671. {
  672. packageCacheDir_ = AddTrailingSlash(path);
  673. }
  674. void Network::SendPackageToClients(Scene* scene, PackageFile* package)
  675. {
  676. if (!scene)
  677. {
  678. URHO3D_LOGERROR("Null scene specified for SendPackageToClients");
  679. return;
  680. }
  681. if (!package)
  682. {
  683. URHO3D_LOGERROR("Null package specified for SendPackageToClients");
  684. return;
  685. }
  686. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  687. i != clientConnections_.End(); ++i)
  688. {
  689. if (i->second_->GetScene() == scene)
  690. i->second_->SendPackageToClient(package);
  691. }
  692. }
  693. SharedPtr<HttpRequest> Network::MakeHttpRequest(const String& url, const String& verb, const Vector<String>& headers,
  694. const String& postData)
  695. {
  696. URHO3D_PROFILE(MakeHttpRequest);
  697. // The initialization of the request will take time, can not know at this point if it has an error or not
  698. SharedPtr<HttpRequest> request(new HttpRequest(url, verb, headers, postData));
  699. return request;
  700. }
  701. void Network::BanAddress(const String& address)
  702. {
  703. URHO3D_LOGWARNING("Banning address: " + address);
  704. rakPeer_->AddToBanList(address.CString(), 0);
  705. }
  706. void Network::BanConnection(Connection* connection, const String& reason)
  707. {
  708. using namespace NetworkBanned;
  709. VariantMap data = GetEventDataMap();
  710. data[P_REASON] = reason;
  711. connection->SendRemoteEvent(E_NETWORKBANNED, false, data);
  712. BanAddress(connection->GetIP());
  713. }
  714. Connection* Network::GetConnection(const SLNet::AddressOrGUID& connection) const
  715. {
  716. if (serverConnection_ && serverConnection_->GetAddressOrGUID() == connection) {
  717. return serverConnection_;
  718. }
  719. else
  720. {
  721. HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Find(connection);
  722. if (i != clientConnections_.End())
  723. return i->second_;
  724. else
  725. return nullptr;
  726. }
  727. }
  728. Connection* Network::GetClientConnection(const SLNet::AddressOrGUID& connection) const
  729. {
  730. HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Find(connection);
  731. if (i != clientConnections_.End())
  732. return i->second_;
  733. return nullptr;
  734. }
  735. Connection* Network::GetServerConnection() const
  736. {
  737. return serverConnection_;
  738. }
  739. Vector<SharedPtr<Connection> > Network::GetClientConnections() const
  740. {
  741. Vector<SharedPtr<Connection> > ret;
  742. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Begin();
  743. i != clientConnections_.End(); ++i)
  744. ret.Push(i->second_);
  745. return ret;
  746. }
  747. bool Network::IsServerRunning() const
  748. {
  749. if (!rakPeer_)
  750. return false;
  751. if (networkMode_ == PEER_TO_PEER && !isServer_) {
  752. return false;
  753. }
  754. return rakPeer_->IsActive() && isServer_;
  755. }
  756. bool Network::CheckRemoteEvent(StringHash eventType) const
  757. {
  758. return allowedRemoteEvents_.Contains(eventType);
  759. }
  760. void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
  761. {
  762. unsigned char packetID = packet->data[0];
  763. if (packetID < ID_USER_PACKET_ENUM) {
  764. URHO3D_LOGERROR(">> " + String((int)packetID) + " HandleIncomingPacket: " + String(RAKNET_MESSAGEID_STRINGS[packetID]));
  765. }
  766. bool packetHandled = false;
  767. // Deal with timestamped backents
  768. unsigned dataStart = sizeof(char);
  769. if (packetID == ID_TIMESTAMP)
  770. {
  771. dataStart += sizeof(SLNet::Time);
  772. packetID = packet->data[dataStart];
  773. dataStart += sizeof(char);
  774. }
  775. if (packetID == ID_NEW_INCOMING_CONNECTION)
  776. {
  777. URHO3D_LOGINFOF("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
  778. if (isServer || networkMode_ == PEER_TO_PEER)
  779. {
  780. NewConnectionEstablished(packet->guid, packet->systemAddress.ToString(false));
  781. }
  782. packetHandled = true;
  783. }
  784. if (packetID == ID_REMOTE_NEW_INCOMING_CONNECTION)
  785. {
  786. URHO3D_LOGINFOF("ID_REMOTE_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
  787. if (networkMode_ == PEER_TO_PEER)
  788. {
  789. unsigned int count;
  790. SLNet::BitStream bsIn(packet->data, packet->length, false);
  791. bsIn.IgnoreBytes(sizeof(SLNet::MessageID));
  792. bsIn.Read(count);
  793. SLNet::SystemAddress remoteAddress;
  794. SLNet::RakNetGUID remoteGuid;
  795. NewConnectionEstablished(packet->guid, packet->systemAddress.ToString(false));
  796. // for (unsigned int i=0; i < count; i++)
  797. // {
  798. // bsIn.Read(remoteAddress);
  799. // bsIn.Read(remoteGuid);
  800. // if (!remoteAddress.EqualsExcludingPort(*natPunchServerAddress_)) {
  801. // URHO3D_LOGINFO("BBBB GUID " + String(remoteGuid.ToString()));
  802. // NewConnectionEstablished(remoteGuid, remoteAddress.ToString(false));
  803. //
  804. // }
  805. // }
  806. }
  807. packetHandled = true;
  808. }
  809. else if (packetID == ID_REMOTE_CONNECTION_LOST || packetID == ID_REMOTE_DISCONNECTION_NOTIFICATION)
  810. {
  811. //TODO find out who's really sending out this message
  812. packetHandled = true;
  813. }
  814. else if (packetID == ID_ALREADY_CONNECTED)
  815. {
  816. if (natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  817. URHO3D_LOGINFO("Already connected to NAT server! ");
  818. SendEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  819. if (!isServer && networkMode_ == SERVER_CLIENT)
  820. {
  821. bool connecting = natPunchthroughClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_);
  822. if (!connecting) {
  823. URHO3D_LOGERROR("Unable to do NAT punchtrough!");
  824. }
  825. }
  826. }
  827. packetHandled = true;
  828. }
  829. else if (packetID == ID_CONNECTION_REQUEST_ACCEPTED) // We're a client, our connection has been accepted
  830. {
  831. if(natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  832. URHO3D_LOGINFO("Succesfully connected to NAT punchtrough server! ");
  833. SendEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  834. if (!isServer && remoteGUID_ && networkMode_ == SERVER_CLIENT)
  835. {
  836. natPunchthroughClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_);
  837. }
  838. } else {
  839. if (networkMode_ == SERVER_CLIENT) {
  840. OnServerConnected(packet->guid);
  841. } else {
  842. URHO3D_LOGINFOF("ID_CONNECTION_REQUEST_ACCEPTED from %s,guid=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  843. // Assume that we're connecting to the P2P host
  844. // serverConnection_->SetAddressOrGUID(packet->guid);
  845. // SLNet::BitStream bsOut;
  846. // bsOut.Write((unsigned char) MSG_P2P_JOIN_REQUEST);
  847. // rakPeer_->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
  848. }
  849. }
  850. packetHandled = true;
  851. }
  852. else if (packetID == ID_NAT_TARGET_NOT_CONNECTED)
  853. {
  854. URHO3D_LOGERROR("Target server not connected to NAT master server!");
  855. packetHandled = true;
  856. }
  857. else if (packetID == ID_CONNECTION_LOST || packetID == ID_DISCONNECTION_NOTIFICATION) // We've lost connectivity with the packet source
  858. {
  859. if(natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  860. URHO3D_LOGERROR("Connection to NAT server lost!");
  861. if (natAutoReconnect_) {
  862. URHO3D_LOGINFO("Reconnecting to NAT server");
  863. if (networkMode_ == PEER_TO_PEER) {
  864. ConnectNAT(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort());
  865. } else {
  866. rakPeer_->Connect(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort(), nullptr, 0);
  867. }
  868. }
  869. } else if (isServer)
  870. {
  871. ClientDisconnected(packet->guid);
  872. }
  873. else
  874. {
  875. if (networkMode_ == SERVER_CLIENT) {
  876. OnServerDisconnected();
  877. } else {
  878. ClientDisconnected(packet->guid);
  879. }
  880. }
  881. packetHandled = true;
  882. }
  883. else if (packetID == ID_CONNECTION_ATTEMPT_FAILED) // We've failed to connect to the server/peer
  884. {
  885. if (natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  886. URHO3D_LOGERROR("Connection to NAT punchtrough server failed!");
  887. SendEvent(E_NATMASTERCONNECTIONFAILED);
  888. } else {
  889. if (!isServer)
  890. {
  891. OnServerDisconnected();
  892. }
  893. }
  894. packetHandled = true;
  895. }
  896. else if (packetID == ID_NAT_PUNCHTHROUGH_SUCCEEDED)
  897. {
  898. SLNet::SystemAddress remotePeer = packet->systemAddress;
  899. URHO3D_LOGINFO("NAT punchtrough succeeded! Remote peer: " + String(remotePeer.ToString()));
  900. if (!isServer && networkMode_ == SERVER_CLIENT)
  901. {
  902. using namespace NetworkNatPunchtroughSucceeded;
  903. VariantMap eventMap;
  904. eventMap[P_ADDRESS] = remotePeer.ToString(false);
  905. eventMap[P_PORT] = remotePeer.GetPort();
  906. SendEvent(E_NETWORKNATPUNCHTROUGHSUCCEEDED, eventMap);
  907. URHO3D_LOGINFO("Connecting to server behind NAT: " + String(remotePeer.ToString()));
  908. Connect(String(remotePeer.ToString(false)), remotePeer.GetPort(), scene_, identity_);
  909. } else if (networkMode_ == PEER_TO_PEER){
  910. SLNet::ConnectionAttemptResult car = rakPeer_->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), password_.CString(), password_.Length());
  911. }
  912. packetHandled = true;
  913. }
  914. else if (packetID == ID_NAT_PUNCHTHROUGH_FAILED || packetID == ID_NAT_TARGET_NOT_CONNECTED || packetID == ID_NAT_TARGET_UNRESPONSIVE || packetID == ID_NAT_CONNECTION_TO_TARGET_LOST)
  915. {
  916. URHO3D_LOGERROR("NAT punchtrough failed!");
  917. SLNet::SystemAddress remotePeer = packet->systemAddress;
  918. using namespace NetworkNatPunchtroughFailed;
  919. VariantMap eventMap;
  920. eventMap[P_ADDRESS] = remotePeer.ToString(false);
  921. eventMap[P_PORT] = remotePeer.GetPort();
  922. SendEvent(E_NETWORKNATPUNCHTROUGHFAILED, eventMap);
  923. packetHandled = true;
  924. }
  925. else if (packetID == ID_CONNECTION_BANNED) // We're a client and we're on the ban list
  926. {
  927. URHO3D_LOGERROR("Connection failed, you're banned!");
  928. SendEvent(E_NETWORKBANNED);
  929. packetHandled = true;
  930. }
  931. else if (packetID == ID_INVALID_PASSWORD) // We're a client, and we gave an invalid password
  932. {
  933. URHO3D_LOGERROR("Invalid password provided for connection!");
  934. SendEvent(E_NETWORKINVALIDPASSWORD);
  935. packetHandled = true;
  936. }
  937. else if (packetID == ID_DOWNLOAD_PROGRESS) // Part of a file transfer
  938. {
  939. //URHO3D_LOGINFO("101010");
  940. }
  941. else if (packetID == ID_UNCONNECTED_PING)
  942. {
  943. packetHandled = true;
  944. }
  945. else if (packetID == ID_READY_EVENT_SET || packetID == ID_READY_EVENT_UNSET || packetID == ID_READY_EVENT_ALL_SET || packetID == ID_READY_EVENT_QUERY || packetID == ID_READY_EVENT_FORCE_ALL_SET)
  946. {
  947. ReadyStatusChanged();
  948. packetHandled = true;
  949. }
  950. else if (packetID == ID_UNCONNECTED_PONG) // Host discovery response
  951. {
  952. if (!isServer)
  953. {
  954. using namespace NetworkHostDiscovered;
  955. dataStart += sizeof(SLNet::TimeMS);
  956. VariantMap& eventMap = context_->GetEventDataMap();
  957. if (packet->length > packet->length - dataStart) {
  958. VectorBuffer buffer(packet->data + dataStart, packet->length - dataStart);
  959. VariantMap srcData = buffer.ReadVariantMap();
  960. eventMap[P_BEACON] = srcData;
  961. }
  962. else {
  963. eventMap[P_BEACON] = VariantMap();
  964. }
  965. eventMap[P_ADDRESS] = String(packet->systemAddress.ToString(false));
  966. eventMap[P_PORT] = (int)packet->systemAddress.GetPort();
  967. SendEvent(E_NETWORKHOSTDISCOVERED, eventMap);
  968. }
  969. packetHandled = true;
  970. }
  971. else if (packetID == ID_FCM2_REQUEST_FCMGUID)
  972. {
  973. if (networkMode_ == SERVER_CLIENT) {
  974. URHO3D_LOGERROR("Network mode mismatch, disconnecting!");
  975. OnServerDisconnected();
  976. SendEvent(E_NETWORKMODEMISMATCH);
  977. packetHandled = true;
  978. }
  979. }
  980. else if (packetID == ID_FCM2_NEW_HOST)
  981. {
  982. SLNet::BitStream bs(packet->data,packet->length,false);
  983. bs.IgnoreBytes(1);
  984. SLNet::RakNetGUID oldHost;
  985. bs.Read(oldHost);
  986. if (serverConnection_) {
  987. serverConnection_->SetAddressOrGUID(packet->guid);
  988. }
  989. hostGuid_ = packet->guid.ToString();
  990. if (packet->guid == rakPeer_->GetMyGUID())
  991. {
  992. isServer_ = true;
  993. if (oldHost != SLNet::UNASSIGNED_RAKNET_GUID)
  994. {
  995. URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: Taking over as host from the old host [%s].", oldHost.ToString());
  996. }
  997. else
  998. {
  999. // Room not hosted if we become host the first time since this was done in CreateRoom() already
  1000. URHO3D_LOGINFO("ID_FCM2_NEW_HOST: We have become host for the first time");
  1001. }
  1002. for (auto it = clientConnections_.Begin(); it != clientConnections_.End(); ++it) {
  1003. URHO3D_LOGINFO("Setting new scene for clients");
  1004. // (*it).second_->SetScene(serverConnection_->GetScene());
  1005. //TODO decide what to do when we take ownership as the host, should the scene needs to be reloaded?
  1006. (*it).second_->SetSceneLoaded(true);
  1007. //(*it).second_->SetScene(serverConnection_->GetScene());
  1008. }
  1009. }
  1010. else
  1011. {
  1012. isServer_ = false;
  1013. if (oldHost != SLNet::UNASSIGNED_RAKNET_GUID) {
  1014. URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: A new system %s has become host, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  1015. }
  1016. else {
  1017. URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: System %s is host, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  1018. }
  1019. // // Send the identity map now to our new host
  1020. VectorBuffer msg;
  1021. msg.WriteVariantMap(serverConnection_->GetIdentity());
  1022. serverConnection_->SendMessage(MSG_IDENTITY, true, true, msg);
  1023. }
  1024. using namespace P2PNewHost;
  1025. VariantMap data = GetEventDataMap();
  1026. data[P_ADDRESS] = packet->systemAddress.ToString(false);
  1027. data[P_PORT] = packet->systemAddress.GetPort();
  1028. data[P_GUID] = packet->guid.ToString();
  1029. SendEvent(E_P2PNEWHOST, data);
  1030. ReadyStatusChanged();
  1031. packetHandled = true;
  1032. }
  1033. else if (packetID == ID_FCM2_VERIFIED_JOIN_START) {
  1034. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_START");
  1035. packetHandled = true;
  1036. }
  1037. else if (packetID == ID_NO_FREE_INCOMING_CONNECTIONS)
  1038. {
  1039. URHO3D_LOGERROR("Server is full!");
  1040. Disconnect(1000);
  1041. SendEvent(E_SERVERFULL);
  1042. packetHandled = true;
  1043. }
  1044. else if (packetID == ID_FCM2_VERIFIED_JOIN_CAPABLE)
  1045. {
  1046. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_CAPABLE");
  1047. // fullyConnectedMesh2_->RespondOnVerifiedJoinCapable(packet, true, nullptr);
  1048. packetHandled = true;
  1049. }
  1050. else if (packetID == ID_FCM2_VERIFIED_JOIN_ACCEPTED)
  1051. {
  1052. // DataStructures::List<SLNet::RakNetGUID> systemsAccepted;
  1053. // bool thisSystemAccepted;
  1054. // fullyConnectedMesh2_->GetVerifiedJoinAcceptedAdditionalData(packet, &thisSystemAccepted, systemsAccepted, nullptr);
  1055. // if (thisSystemAccepted) {
  1056. // URHO3D_LOGINFO("Game join request accepted");
  1057. // }
  1058. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_ACCEPTED");
  1059. packetHandled = true;
  1060. }
  1061. else if (packetID == ID_FCM2_VERIFIED_JOIN_REJECTED)
  1062. {
  1063. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_REJECTED");
  1064. }
  1065. else if (packetID == ID_FCM2_REQUEST_FCMGUID)
  1066. {
  1067. URHO3D_LOGINFO("ID_FCM2_REQUEST_FCMGUID");
  1068. }
  1069. else if (packetID == ID_FCM2_RESPOND_CONNECTION_COUNT)
  1070. {
  1071. URHO3D_LOGINFO("ID_FCM2_RESPOND_CONNECTION_COUNT");
  1072. }
  1073. else if (packetID == ID_FCM2_INFORM_FCMGUID)
  1074. {
  1075. URHO3D_LOGINFO("ID_FCM2_INFORM_FCMGUID");
  1076. }
  1077. else if (packetID == ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT)
  1078. {
  1079. URHO3D_LOGINFO("ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT");
  1080. }
  1081. else if (packetID == ID_FCM2_UPDATE_USER_CONTEXT)
  1082. {
  1083. URHO3D_LOGINFO("ID_FCM2_UPDATE_USER_CONTEXT");
  1084. }
  1085. // Urho3D messages
  1086. if (packetID >= ID_USER_PACKET_ENUM)
  1087. {
  1088. //URHO3D_LOGINFOF("ID_USER_PACKET_ENUM %i", packetID);
  1089. if (packetID == MSG_P2P_JOIN_REQUEST) {
  1090. URHO3D_LOGINFO("MSG_P2P_JOIN_REQUEST");
  1091. // if (allowedConnectionCount_ > 0 && GetClientConnections().Size() < allowedConnectionCount_) {
  1092. //// fullyConnectedMesh2_->StartVerifiedJoin(packet->guid);
  1093. // URHO3D_LOGWARNING("StartVerifiedJoin SUCCESS");
  1094. // } else {
  1095. // VectorBuffer msg;
  1096. // GetConnection(packet->guid)->SendMessage(MSG_P2P_JOIN_REQUEST_DENIED, true, true, msg);
  1097. // ClientDisconnected(packet->guid);
  1098. // URHO3D_LOGWARNING("StartVerifiedJoin FAILED");
  1099. // }
  1100. } else if (networkMode_ == PEER_TO_PEER && IsHostSystem())
  1101. {
  1102. // We are the host in the P2P server, parse the message accordingly
  1103. HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
  1104. }
  1105. else if (networkMode_ == SERVER_CLIENT && isServer_) {
  1106. // We are the server in the server-client connection
  1107. HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
  1108. }
  1109. else {
  1110. // we are client in either P2P or server-client mode
  1111. MemoryBuffer buffer(packet->data + dataStart, packet->length - dataStart);
  1112. if (serverConnection_ && !serverConnection_->ProcessMessage(packetID, buffer))
  1113. {
  1114. HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
  1115. }
  1116. }
  1117. packetHandled = true;
  1118. }
  1119. if (!packetHandled && packetID < sizeof(RAKNET_MESSAGEID_STRINGS))
  1120. URHO3D_LOGERROR("Unhandled network packet: " + String(RAKNET_MESSAGEID_STRINGS[packetID]));
  1121. else if (!packetHandled)
  1122. URHO3D_LOGERRORF("Unhandled network packet: %i", packetID);
  1123. }
  1124. void Network::Update(float timeStep)
  1125. {
  1126. URHO3D_PROFILE(UpdateNetwork);
  1127. //Process all incoming messages for the server
  1128. if (rakPeer_->IsActive())
  1129. {
  1130. while (SLNet::Packet* packet = rakPeer_->Receive())
  1131. {
  1132. if (IsHostSystem() || networkMode_ == SERVER_CLIENT) {
  1133. // Process all messages as server/host
  1134. HandleIncomingPacket(packet, true);
  1135. }
  1136. else {
  1137. // Process messages as a client/peer
  1138. HandleIncomingPacket(packet, false);
  1139. }
  1140. // Check if interface is still active, ban could happen while the message was processing
  1141. if (rakPeer_->IsActive()) {
  1142. rakPeer_->DeallocatePacket(packet);
  1143. }
  1144. }
  1145. }
  1146. // Process all incoming messages for the client, server-client mode only
  1147. if (rakPeerClient_->IsActive())
  1148. {
  1149. while (SLNet::Packet* packet = rakPeerClient_->Receive())
  1150. {
  1151. HandleIncomingPacket(packet, false);
  1152. if (rakPeerClient_->IsActive()) {
  1153. rakPeerClient_->DeallocatePacket(packet);
  1154. }
  1155. }
  1156. }
  1157. }
  1158. void Network::PostUpdate(float timeStep)
  1159. {
  1160. URHO3D_PROFILE(PostUpdateNetwork);
  1161. // Check if periodic update should happen now
  1162. updateAcc_ += timeStep;
  1163. bool updateNow = updateAcc_ >= updateInterval_;
  1164. if (updateNow)
  1165. {
  1166. // Notify of the impending update to allow for example updated client controls to be set
  1167. SendEvent(E_NETWORKUPDATE);
  1168. updateAcc_ = fmodf(updateAcc_, updateInterval_);
  1169. if (IsServerRunning())
  1170. {
  1171. // Collect and prepare all networked scenes
  1172. {
  1173. URHO3D_PROFILE(PrepareServerUpdate);
  1174. networkScenes_.Clear();
  1175. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  1176. i != clientConnections_.End(); ++i)
  1177. {
  1178. Scene* scene = i->second_->GetScene();
  1179. if (scene)
  1180. networkScenes_.Insert(scene);
  1181. }
  1182. for (HashSet<Scene*>::ConstIterator i = networkScenes_.Begin(); i != networkScenes_.End(); ++i)
  1183. (*i)->PrepareNetworkUpdate();
  1184. }
  1185. {
  1186. URHO3D_PROFILE(SendServerUpdate);
  1187. // Then send server updates for each client connection
  1188. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  1189. i != clientConnections_.End(); ++i)
  1190. {
  1191. i->second_->SendServerUpdate();
  1192. i->second_->SendRemoteEvents();
  1193. i->second_->SendPackages();
  1194. }
  1195. }
  1196. }
  1197. if (serverConnection_)
  1198. {
  1199. // No need to send out updates if we're the host system
  1200. if (networkMode_ == PEER_TO_PEER && !IsHostSystem()) {
  1201. // Send the client update
  1202. serverConnection_->SendClientUpdate();
  1203. serverConnection_->SendRemoteEvents();
  1204. } else if (networkMode_ == SERVER_CLIENT) {
  1205. // Send the client update
  1206. serverConnection_->SendClientUpdate();
  1207. serverConnection_->SendRemoteEvents();
  1208. }
  1209. }
  1210. // Notify that the update was sent
  1211. SendEvent(E_NETWORKUPDATESENT);
  1212. }
  1213. }
  1214. void Network::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
  1215. {
  1216. using namespace BeginFrame;
  1217. Update(eventData[P_TIMESTEP].GetFloat());
  1218. }
  1219. void Network::HandleRenderUpdate(StringHash eventType, VariantMap& eventData)
  1220. {
  1221. using namespace RenderUpdate;
  1222. PostUpdate(eventData[P_TIMESTEP].GetFloat());
  1223. }
  1224. void Network::OnServerConnected(const SLNet::AddressOrGUID& address)
  1225. {
  1226. serverConnection_->SetConnectPending(false);
  1227. serverConnection_->SetAddressOrGUID(address);
  1228. URHO3D_LOGINFO("Connected to server!");
  1229. // Send the identity map now
  1230. VectorBuffer msg;
  1231. msg.WriteVariantMap(serverConnection_->GetIdentity());
  1232. serverConnection_->SendMessage(MSG_IDENTITY, true, true, msg);
  1233. SendEvent(E_SERVERCONNECTED);
  1234. }
  1235. void Network::OnServerDisconnected()
  1236. {
  1237. if (networkMode_ == PEER_TO_PEER) {
  1238. return;
  1239. }
  1240. if (!serverConnection_) {
  1241. return;
  1242. }
  1243. // Differentiate between failed connection, and disconnection
  1244. bool failedConnect = serverConnection_ && serverConnection_->IsConnectPending();
  1245. serverConnection_.Reset();
  1246. if (!failedConnect)
  1247. {
  1248. URHO3D_LOGINFO("Disconnected from server");
  1249. SendEvent(E_SERVERDISCONNECTED);
  1250. }
  1251. else
  1252. {
  1253. URHO3D_LOGERROR("Failed to connect to server");
  1254. SendEvent(E_CONNECTFAILED);
  1255. }
  1256. // if (rakPeerClient_->IsActive()) {
  1257. rakPeerClient_->Shutdown(0);
  1258. // }
  1259. natPunchthroughClient_->Clear();
  1260. }
  1261. void Network::ConfigureNetworkSimulator()
  1262. {
  1263. if (serverConnection_)
  1264. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1265. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  1266. i != clientConnections_.End(); ++i)
  1267. i->second_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1268. }
  1269. bool Network::StartSession(Scene* scene, const VariantMap& identity)
  1270. {
  1271. if (networkMode_ == SERVER_CLIENT) {
  1272. URHO3D_LOGERROR("P2P sessions are not available for SERVER_CLIENT mode!");
  1273. return false;
  1274. }
  1275. if (!natPunchServerAddress_) {
  1276. URHO3D_LOGERROR("Set the NAT server info first!");
  1277. return false;
  1278. }
  1279. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1280. SubscribeToEvent(E_NATMASTERCONNECTIONSUCCEEDED, URHO3D_HANDLER(Network, HandleNATStartSession));
  1281. scene_ = scene;
  1282. identity_ = identity;
  1283. ConnectNAT(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort());
  1284. guid_ = String(rakPeer_->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
  1285. return true;
  1286. }
  1287. void Network::HandleNATStartSession(StringHash eventType, VariantMap& eventData)
  1288. {
  1289. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1290. if (serverConnection_) {
  1291. serverConnection_.Reset();
  1292. }
  1293. serverConnection_ = new Connection(context_, false, rakPeer_->GetMyGUID(), rakPeer_);
  1294. serverConnection_->SetScene(scene_);
  1295. serverConnection_->SetSceneLoaded(true);
  1296. serverConnection_->SetIdentity(identity_);
  1297. serverConnection_->SetConnectPending(true);
  1298. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1299. rakPeer_->SetOccasionalPing(true);
  1300. fullyConnectedMesh2_->Clear();
  1301. fullyConnectedMesh2_->ResetHostCalculation();
  1302. hostGuid_ = GetGUID();
  1303. isServer_ = true;
  1304. SetReady(false);
  1305. SendEvent(E_P2PSESSIONSTARTED);
  1306. }
  1307. void Network::JoinSession(const String& guid, Scene* scene, const VariantMap& identity)
  1308. {
  1309. if (networkMode_ == SERVER_CLIENT) {
  1310. URHO3D_LOGERROR("P2P sessions are not available for SERVER_CLIENT mode!");
  1311. return;
  1312. }
  1313. if (!natPunchServerAddress_) {
  1314. URHO3D_LOGERROR("Set the NAT server info first!");
  1315. return;
  1316. }
  1317. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1318. SubscribeToEvent(E_NATMASTERCONNECTIONSUCCEEDED, URHO3D_HANDLER(Network, HandleNATJoinSession));
  1319. if (remoteGUID_) {
  1320. delete remoteGUID_;
  1321. remoteGUID_ = nullptr;
  1322. }
  1323. remoteGUID_ = new SLNet::RakNetGUID;
  1324. remoteGUID_->FromString(guid.CString());
  1325. hostGuid_ = guid;
  1326. scene_ = scene;
  1327. identity_ = identity;
  1328. ConnectNAT(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort());
  1329. guid_ = String(rakPeer_->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
  1330. }
  1331. void Network::HandleNATJoinSession(StringHash eventType, VariantMap& eventData)
  1332. {
  1333. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1334. SetReady(false);
  1335. if (serverConnection_) {
  1336. serverConnection_.Reset();
  1337. }
  1338. serverConnection_ = new Connection(context_, false, rakPeer_->GetMyBoundAddress(), rakPeer_);
  1339. serverConnection_->SetScene(scene_);
  1340. serverConnection_->SetSceneLoaded(true);
  1341. serverConnection_->SetIdentity(identity_);
  1342. serverConnection_->SetConnectPending(true);
  1343. serverConnection_->SetAddressOrGUID(*remoteGUID_);
  1344. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1345. rakPeer_->SetOccasionalPing(true);
  1346. fullyConnectedMesh2_->ResetHostCalculation();
  1347. fullyConnectedMesh2_->Clear();
  1348. if (natPunchthroughServerClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_)) {
  1349. SendEvent(E_P2PSESSIONJOINED);
  1350. } else {
  1351. URHO3D_LOGERROR("P2P join attempt failed!");
  1352. SendEvent(E_P2PSESSIONJOINFAILED);
  1353. }
  1354. ReadyStatusChanged();
  1355. }
  1356. int Network::GetParticipantCount()
  1357. {
  1358. if (networkMode_ == SERVER_CLIENT) {
  1359. return GetClientConnections().Size();
  1360. }
  1361. if (fullyConnectedMesh2_) {
  1362. return fullyConnectedMesh2_->GetParticipantCount();
  1363. }
  1364. return 0;
  1365. }
  1366. bool Network::IsConnectedHost()
  1367. {
  1368. if (networkMode_ == SERVER_CLIENT) {
  1369. return false;
  1370. }
  1371. return fullyConnectedMesh2_->IsConnectedHost();
  1372. }
  1373. bool Network::IsHostSystem()
  1374. {
  1375. if (networkMode_ == SERVER_CLIENT) {
  1376. return IsServerRunning();
  1377. }
  1378. return fullyConnectedMesh2_->IsHostSystem();
  1379. }
  1380. const String Network::GetHostAddress()
  1381. {
  1382. if (networkMode_ == SERVER_CLIENT) {
  1383. return rakPeer_->GetMyGUID().ToString();
  1384. }
  1385. return hostGuid_;
  1386. }
  1387. void Network::SetReady(bool value)
  1388. {
  1389. if (networkMode_ == SERVER_CLIENT) {
  1390. return;
  1391. }
  1392. readyEvent_->SetEvent(0, value);
  1393. ReadyStatusChanged();
  1394. }
  1395. bool Network::GetReady()
  1396. {
  1397. if (networkMode_ == SERVER_CLIENT) {
  1398. return false;
  1399. }
  1400. return readyEvent_->IsEventSet(0);
  1401. }
  1402. void Network::ReadyStatusChanged()
  1403. {
  1404. if (networkMode_ == SERVER_CLIENT) {
  1405. return;
  1406. }
  1407. DataStructures::List<SLNet::RakNetGUID> participantList;
  1408. fullyConnectedMesh2_->GetParticipantList(participantList);
  1409. for (unsigned int i = 0; i < participantList.Size(); i++) {
  1410. if (participantList[i] != rakPeerClient_->GetMyGUID()) {
  1411. readyEvent_->AddToWaitList(0, participantList[i]);
  1412. }
  1413. }
  1414. fullyConnectedMesh2_->GetParticipantList(participantList);
  1415. bool allReady = true;
  1416. for (unsigned int i = 0; i < participantList.Size(); i++) {
  1417. if (participantList[i] != rakPeer_->GetMyGUID()) {
  1418. int ready = readyEvent_->GetReadyStatus(0, participantList[i]);
  1419. Connection* connection = GetClientConnection(participantList[i]);
  1420. if (connection) {
  1421. if (ready != SLNet::RES_ALL_READY && ready != SLNet::RES_READY) {
  1422. if (connection) {
  1423. connection->SetReady(false);
  1424. }
  1425. allReady = false;
  1426. } else {
  1427. if (connection) {
  1428. connection->SetReady(true);
  1429. }
  1430. }
  1431. }
  1432. }
  1433. }
  1434. VariantMap data = GetEventDataMap();
  1435. if (serverConnection_) {
  1436. if (readyEvent_->IsEventSet(0)) {
  1437. serverConnection_->SetReady(true);
  1438. }
  1439. else {
  1440. serverConnection_->SetReady(false);
  1441. }
  1442. }
  1443. if (allReady && readyEvent_->IsEventSet(0)) {
  1444. data[P2PAllReadyChanged::P_READY] = true;
  1445. } else {
  1446. data[P2PAllReadyChanged::P_READY] = false;
  1447. }
  1448. SendEvent(E_P2PALLREADYCHANGED, data);
  1449. }
  1450. void Network::ResetHost()
  1451. {
  1452. if (networkMode_ == SERVER_CLIENT) {
  1453. return;
  1454. }
  1455. fullyConnectedMesh2_->ResetHostCalculation();
  1456. }
  1457. void Network::SetMode(NetworkMode mode, bool force)
  1458. {
  1459. if (rakPeer_->IsActive() || rakPeerClient_->IsActive()) {
  1460. URHO3D_LOGERROR("Failed to change network mode! Shutdown networking system first or use forced mode changing!");
  1461. return;
  1462. }
  1463. if (force) {
  1464. if (rakPeer_->IsActive()) {
  1465. rakPeer_->Shutdown(100);
  1466. }
  1467. if (rakPeerClient_->IsActive()) {
  1468. rakPeerClient_->Shutdown(100);
  1469. }
  1470. clientConnections_.Clear();
  1471. serverConnection_.Reset();
  1472. }
  1473. networkMode_ = mode;
  1474. if (networkMode_ == PEER_TO_PEER) {
  1475. if (fullyConnectedMesh2_) {
  1476. rakPeer_->DetachPlugin(fullyConnectedMesh2_);
  1477. SLNet::FullyConnectedMesh2::DestroyInstance(fullyConnectedMesh2_);
  1478. }
  1479. fullyConnectedMesh2_ = SLNet::FullyConnectedMesh2::GetInstance();
  1480. rakPeer_->AttachPlugin(fullyConnectedMesh2_);
  1481. fullyConnectedMesh2_->SetAutoparticipateConnections(true);
  1482. if (readyEvent_) {
  1483. rakPeer_->DetachPlugin(readyEvent_);
  1484. SLNet::ReadyEvent::DestroyInstance(readyEvent_);
  1485. }
  1486. readyEvent_ = SLNet::ReadyEvent::GetInstance();
  1487. rakPeer_->AttachPlugin(readyEvent_);
  1488. if (connectionGraph2_) {
  1489. rakPeer_->DetachPlugin(connectionGraph2_);
  1490. SLNet::ConnectionGraph2::DestroyInstance(connectionGraph2_);
  1491. }
  1492. connectionGraph2_ = SLNet::ConnectionGraph2::GetInstance();
  1493. rakPeer_->AttachPlugin(connectionGraph2_);
  1494. } else {
  1495. if (fullyConnectedMesh2_) {
  1496. rakPeer_->DetachPlugin(fullyConnectedMesh2_);
  1497. SLNet::FullyConnectedMesh2::DestroyInstance(fullyConnectedMesh2_);
  1498. fullyConnectedMesh2_ = nullptr;
  1499. }
  1500. if (readyEvent_) {
  1501. rakPeer_->DetachPlugin(readyEvent_);
  1502. SLNet::ReadyEvent::DestroyInstance(readyEvent_);
  1503. readyEvent_ = nullptr;
  1504. }
  1505. if (connectionGraph2_) {
  1506. rakPeer_->DetachPlugin(connectionGraph2_);
  1507. SLNet::ConnectionGraph2::DestroyInstance(connectionGraph2_);
  1508. connectionGraph2_ = nullptr;
  1509. }
  1510. }
  1511. }
  1512. void Network::SetNATAutoReconnect(bool retry)
  1513. {
  1514. natAutoReconnect_ = retry;
  1515. }
  1516. void Network::SetAllowedConnections(unsigned short connectionCount)
  1517. {
  1518. URHO3D_LOGINFO("Max incoming connection changed to " + String(connectionCount));
  1519. rakPeer_->SetMaximumIncomingConnections(connectionCount);
  1520. allowedConnectionCount_ = connectionCount;
  1521. }
  1522. void RegisterNetworkLibrary(Context* context)
  1523. {
  1524. NetworkPriority::RegisterObject(context);
  1525. }
  1526. }