Network.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574
  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. {
  205. rakPeer_ = SLNet::RakPeerInterface::GetInstance();
  206. rakPeerClient_ = SLNet::RakPeerInterface::GetInstance();
  207. fullyConnectedMesh2_ = SLNet::FullyConnectedMesh2::GetInstance();
  208. rakPeer_->AttachPlugin(fullyConnectedMesh2_);
  209. fullyConnectedMesh2_->SetAutoparticipateConnections(false);
  210. readyEvent_ = SLNet::ReadyEvent::GetInstance();
  211. rakPeer_->AttachPlugin(readyEvent_);
  212. connectionGraph2_ = SLNet::ConnectionGraph2::GetInstance();
  213. rakPeer_->AttachPlugin(connectionGraph2_);
  214. rakPeer_->SetTimeoutTime(SERVER_TIMEOUT_TIME, SLNet::UNASSIGNED_SYSTEM_ADDRESS);
  215. rakPeerClient_->SetTimeoutTime(SERVER_TIMEOUT_TIME, SLNet::UNASSIGNED_SYSTEM_ADDRESS);
  216. SetPassword("");
  217. SetDiscoveryBeacon(VariantMap());
  218. natPunchthroughClient_ = new SLNet::NatPunchthroughClient;
  219. natPunchthroughServerClient_ = new SLNet::NatPunchthroughClient;
  220. SetNATServerInfo("127.0.0.1", 61111);
  221. // Register Network library object factories
  222. RegisterNetworkLibrary(context_);
  223. SubscribeToEvent(E_BEGINFRAME, URHO3D_HANDLER(Network, HandleBeginFrame));
  224. SubscribeToEvent(E_RENDERUPDATE, URHO3D_HANDLER(Network, HandleRenderUpdate));
  225. // Blacklist remote events which are not to be allowed to be registered in any case
  226. blacklistedRemoteEvents_.Insert(E_CONSOLECOMMAND);
  227. blacklistedRemoteEvents_.Insert(E_LOGMESSAGE);
  228. blacklistedRemoteEvents_.Insert(E_BEGINFRAME);
  229. blacklistedRemoteEvents_.Insert(E_UPDATE);
  230. blacklistedRemoteEvents_.Insert(E_POSTUPDATE);
  231. blacklistedRemoteEvents_.Insert(E_RENDERUPDATE);
  232. blacklistedRemoteEvents_.Insert(E_ENDFRAME);
  233. blacklistedRemoteEvents_.Insert(E_MOUSEBUTTONDOWN);
  234. blacklistedRemoteEvents_.Insert(E_MOUSEBUTTONUP);
  235. blacklistedRemoteEvents_.Insert(E_MOUSEMOVE);
  236. blacklistedRemoteEvents_.Insert(E_MOUSEWHEEL);
  237. blacklistedRemoteEvents_.Insert(E_KEYDOWN);
  238. blacklistedRemoteEvents_.Insert(E_KEYUP);
  239. blacklistedRemoteEvents_.Insert(E_TEXTINPUT);
  240. blacklistedRemoteEvents_.Insert(E_JOYSTICKCONNECTED);
  241. blacklistedRemoteEvents_.Insert(E_JOYSTICKDISCONNECTED);
  242. blacklistedRemoteEvents_.Insert(E_JOYSTICKBUTTONDOWN);
  243. blacklistedRemoteEvents_.Insert(E_JOYSTICKBUTTONUP);
  244. blacklistedRemoteEvents_.Insert(E_JOYSTICKAXISMOVE);
  245. blacklistedRemoteEvents_.Insert(E_JOYSTICKHATMOVE);
  246. blacklistedRemoteEvents_.Insert(E_TOUCHBEGIN);
  247. blacklistedRemoteEvents_.Insert(E_TOUCHEND);
  248. blacklistedRemoteEvents_.Insert(E_TOUCHMOVE);
  249. blacklistedRemoteEvents_.Insert(E_GESTURERECORDED);
  250. blacklistedRemoteEvents_.Insert(E_GESTUREINPUT);
  251. blacklistedRemoteEvents_.Insert(E_MULTIGESTURE);
  252. blacklistedRemoteEvents_.Insert(E_DROPFILE);
  253. blacklistedRemoteEvents_.Insert(E_INPUTFOCUS);
  254. blacklistedRemoteEvents_.Insert(E_MOUSEVISIBLECHANGED);
  255. blacklistedRemoteEvents_.Insert(E_EXITREQUESTED);
  256. blacklistedRemoteEvents_.Insert(E_SERVERCONNECTED);
  257. blacklistedRemoteEvents_.Insert(E_SERVERDISCONNECTED);
  258. blacklistedRemoteEvents_.Insert(E_CONNECTFAILED);
  259. blacklistedRemoteEvents_.Insert(E_CLIENTCONNECTED);
  260. blacklistedRemoteEvents_.Insert(E_CLIENTDISCONNECTED);
  261. blacklistedRemoteEvents_.Insert(E_CLIENTIDENTITY);
  262. blacklistedRemoteEvents_.Insert(E_CLIENTSCENELOADED);
  263. blacklistedRemoteEvents_.Insert(E_NETWORKMESSAGE);
  264. blacklistedRemoteEvents_.Insert(E_NETWORKUPDATE);
  265. blacklistedRemoteEvents_.Insert(E_NETWORKUPDATESENT);
  266. blacklistedRemoteEvents_.Insert(E_NETWORKSCENELOADFAILED);
  267. blacklistedRemoteEvents_.Insert(E_NATMASTERCONNECTIONSUCCEEDED);
  268. blacklistedRemoteEvents_.Insert(E_NATMASTERCONNECTIONFAILED);
  269. blacklistedRemoteEvents_.Insert(E_NETWORKNATPUNCHTROUGHSUCCEEDED);
  270. blacklistedRemoteEvents_.Insert(E_NETWORKNATPUNCHTROUGHFAILED);
  271. blacklistedRemoteEvents_.Insert(E_P2PJOINREQUESTDENIED);
  272. blacklistedRemoteEvents_.Insert(E_P2PALLREADYCHANGED);
  273. blacklistedRemoteEvents_.Insert(E_NETWORKHOSTDISCOVERED);
  274. blacklistedRemoteEvents_.Insert(E_NETWORKINVALIDPASSWORD);
  275. blacklistedRemoteEvents_.Insert(E_NETWORKBANNED);
  276. blacklistedRemoteEvents_.Insert(E_P2PNEWHOST);
  277. blacklistedRemoteEvents_.Insert(E_P2PSESSIONSTARTED);
  278. }
  279. Network::~Network()
  280. {
  281. // If server connection exists, disconnect, but do not send an event because we are shutting down
  282. Disconnect(1000);
  283. fullyConnectedMesh2_->ResetHostCalculation();
  284. rakPeer_->DetachPlugin(natPunchthroughServerClient_);
  285. rakPeerClient_->DetachPlugin(natPunchthroughClient_);
  286. rakPeer_->DetachPlugin(fullyConnectedMesh2_);
  287. rakPeer_->DetachPlugin(connectionGraph2_);
  288. rakPeer_->DetachPlugin(readyEvent_);
  289. serverConnection_.Reset();
  290. clientConnections_.Clear();
  291. delete natPunchthroughServerClient_;
  292. natPunchthroughServerClient_ = nullptr;
  293. delete natPunchthroughClient_;
  294. natPunchthroughClient_ = nullptr;
  295. delete remoteGUID_;
  296. remoteGUID_ = nullptr;
  297. delete natPunchServerAddress_;
  298. natPunchServerAddress_ = nullptr;
  299. SLNet::RakPeerInterface::DestroyInstance(rakPeer_);
  300. SLNet::RakPeerInterface::DestroyInstance(rakPeerClient_);
  301. SLNet::FullyConnectedMesh2::DestroyInstance(fullyConnectedMesh2_);
  302. SLNet::ReadyEvent::DestroyInstance(readyEvent_);
  303. SLNet::ConnectionGraph2::DestroyInstance(connectionGraph2_);
  304. rakPeer_ = nullptr;
  305. rakPeerClient_ = nullptr;
  306. }
  307. void Network::HandleMessage(const SLNet::AddressOrGUID& source, int packetID, int msgID, const char* data, size_t numBytes)
  308. {
  309. // Only process messages from known sources
  310. Connection* connection = GetConnection(source);
  311. if (connection)
  312. {
  313. MemoryBuffer msg(data, (unsigned)numBytes);
  314. if (connection->ProcessMessage((int)msgID, msg))
  315. return;
  316. // If message was not handled internally, forward as an event
  317. using namespace NetworkMessage;
  318. VariantMap& eventData = GetEventDataMap();
  319. eventData[P_CONNECTION] = connection;
  320. eventData[P_MESSAGEID] = (int)msgID;
  321. eventData[P_DATA].SetBuffer(msg.GetData(), msg.GetSize());
  322. connection->SendEvent(E_NETWORKMESSAGE, eventData);
  323. }
  324. else {
  325. URHO3D_LOGWARNING("Discarding message from unknown MessageConnection " + String(source.ToString()) + " => " + source.rakNetGuid.ToString());
  326. }
  327. }
  328. void Network::NewConnectionEstablished(const SLNet::AddressOrGUID& connection)
  329. {
  330. P2PReadyStatusChanged();
  331. if (networkMode_ == PEER_TO_PEER && clientConnections_[connection]) {
  332. // URHO3D_LOGWARNINGF("Client already in the client list.", connection.rakNetGuid.ToString());
  333. //TODO proper scene state management
  334. clientConnections_[connection]->SetSceneLoaded(true);
  335. return;
  336. }
  337. // URHO3D_LOGINFOF("NewConnectionEstablished ---------------------------", connection.rakNetGuid.ToString());
  338. // Create a new client connection corresponding to this MessageConnection
  339. SharedPtr<Connection> newConnection(new Connection(context_, true, connection, rakPeer_));
  340. newConnection->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  341. if (networkMode_ == PEER_TO_PEER && serverConnection_) {
  342. newConnection->SetScene(serverConnection_->GetScene());
  343. newConnection->SetSceneLoaded(true);
  344. }
  345. clientConnections_[connection] = newConnection;
  346. URHO3D_LOGINFO("Client " + newConnection->ToString() + " connected");
  347. using namespace ClientConnected;
  348. VariantMap& eventData = GetEventDataMap();
  349. eventData[P_CONNECTION] = newConnection;
  350. newConnection->SendEvent(E_CLIENTCONNECTED, eventData);
  351. }
  352. void Network::ClientDisconnected(const SLNet::AddressOrGUID& connection)
  353. {
  354. // Remove the client connection that corresponds to this MessageConnection
  355. HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Find(connection);
  356. if (i != clientConnections_.End())
  357. {
  358. Connection* connection = i->second_;
  359. URHO3D_LOGINFO("Client " + connection->ToString() + " disconnected");
  360. using namespace ClientDisconnected;
  361. VariantMap& eventData = GetEventDataMap();
  362. eventData[P_CONNECTION] = connection;
  363. connection->SendEvent(E_CLIENTDISCONNECTED, eventData);
  364. clientConnections_.Erase(i);
  365. }
  366. P2PReadyStatusChanged();
  367. }
  368. void Network::SetDiscoveryBeacon(const VariantMap& data)
  369. {
  370. VectorBuffer buffer;
  371. buffer.WriteVariantMap(data);
  372. if (buffer.GetSize() > 400)
  373. URHO3D_LOGERROR("Discovery beacon of size: " + String(buffer.GetSize()) + " bytes is too large, modify MAX_OFFLINE_DATA_LENGTH in RakNet or reduce size");
  374. rakPeer_->SetOfflinePingResponse((const char*)buffer.GetData(), buffer.GetSize());
  375. }
  376. void Network::DiscoverHosts(unsigned port)
  377. {
  378. // JSandusky: Contrary to the manual, we actually do have to perform Startup first before we can Ping
  379. if (!rakPeerClient_->IsActive())
  380. {
  381. SLNet::SocketDescriptor socket;
  382. // Startup local connection with max 1 incoming connection(first param) and 1 socket description (third param)
  383. rakPeerClient_->Startup(32, &socket, 1);
  384. rakPeerClient_->SetMaximumIncomingConnections(32);
  385. }
  386. rakPeerClient_->Ping("255.255.255.255", port, false);
  387. }
  388. void Network::SetPassword(const String& password)
  389. {
  390. rakPeer_->SetIncomingPassword(password.CString(), password.Length());
  391. password_ = password;
  392. }
  393. bool Network::Connect(const String& address, unsigned short port, Scene* scene, const VariantMap& identity)
  394. {
  395. URHO3D_PROFILE(Connect);
  396. if (!rakPeerClient_->IsActive())
  397. {
  398. URHO3D_LOGINFO("Initializing client connection...");
  399. SLNet::SocketDescriptor socket;
  400. // Startup local connection with max 2 incoming connections(first param) and 1 socket description (third param)
  401. rakPeerClient_->Startup(32, &socket, 1);
  402. rakPeerClient_->SetMaximumIncomingConnections(32);
  403. } else {
  404. OnServerDisconnected();
  405. }
  406. //isServer_ = false;
  407. SLNet::ConnectionAttemptResult connectResult = rakPeerClient_->Connect(address.CString(), port, password_.CString(), password_.Length());
  408. if (connectResult != SLNet::CONNECTION_ATTEMPT_STARTED)
  409. {
  410. URHO3D_LOGERROR("Failed to connect to server " + address + ":" + String(port) + ", error code: " + String((int)connectResult));
  411. SendEvent(E_CONNECTFAILED);
  412. return false;
  413. }
  414. else
  415. {
  416. serverConnection_ = new Connection(context_, false, rakPeerClient_->GetMyGUID(), rakPeerClient_);
  417. serverConnection_->SetScene(scene);
  418. serverConnection_->SetIdentity(identity);
  419. serverConnection_->SetConnectPending(true);
  420. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  421. URHO3D_LOGINFO("Connecting to server " + address + ":" + String(port) + ", Client: " + serverConnection_->ToString());
  422. return true;
  423. }
  424. }
  425. bool Network::P2PConnectNAT(const String& address, unsigned short port)
  426. {
  427. URHO3D_PROFILE(P2PConnectNAT);
  428. if (!rakPeer_->IsActive())
  429. {
  430. URHO3D_LOGINFO("Initializing client connection...");
  431. SLNet::SocketDescriptor socket;
  432. // Startup local connection with max 2 incoming connections(first param) and 1 socket description (third param)
  433. rakPeer_->Startup(128, &socket, 1);
  434. rakPeer_->SetMaximumIncomingConnections(128);
  435. rakPeer_->AttachPlugin(natPunchthroughServerClient_);
  436. }
  437. else {
  438. OnServerDisconnected();
  439. }
  440. //isServer_ = false;
  441. SLNet::ConnectionAttemptResult connectResult = rakPeer_->Connect(address.CString(), port, nullptr, 0);
  442. if (connectResult == SLNet::ALREADY_CONNECTED_TO_ENDPOINT) {
  443. URHO3D_LOGWARNING("Already connected to server " + address + ":" + String(port) + ", error code: " + String((int)connectResult));
  444. return false;
  445. }
  446. if (connectResult != SLNet::CONNECTION_ATTEMPT_STARTED)
  447. {
  448. URHO3D_LOGERROR("Failed to connect to server " + address + ":" + String(port) + ", error code: " + String((int)connectResult));
  449. SendEvent(E_CONNECTFAILED);
  450. return false;
  451. }
  452. else
  453. {
  454. URHO3D_LOGINFO("Connecting to server " + address + ":" + String(port));
  455. return true;
  456. }
  457. }
  458. void Network::Disconnect(int waitMSec)
  459. {
  460. if (!serverConnection_)
  461. return;
  462. if (networkMode_ == PEER_TO_PEER) {
  463. rakPeer_->Shutdown(1000);
  464. clientConnections_.Clear();
  465. }
  466. URHO3D_PROFILE(Disconnect);
  467. serverConnection_->Disconnect(waitMSec);
  468. serverConnection_.Reset();
  469. }
  470. bool Network::StartServer(unsigned short port)
  471. {
  472. if (IsServerRunning())
  473. return true;
  474. URHO3D_PROFILE(StartServer);
  475. SLNet::SocketDescriptor socket;//(port, AF_INET);
  476. socket.port = port;
  477. socket.socketFamily = AF_INET;
  478. // Startup local connection with max 128 incoming connection(first param) and 1 socket description (third param)
  479. SLNet::StartupResult startResult = rakPeer_->Startup(128, &socket, 1);
  480. if (startResult == SLNet::RAKNET_STARTED)
  481. {
  482. URHO3D_LOGINFO("Started server on port " + String(port));
  483. rakPeer_->SetMaximumIncomingConnections(128);
  484. isServer_ = true;
  485. rakPeer_->SetOccasionalPing(true);
  486. rakPeer_->SetUnreliableTimeout(1000);
  487. //rakPeer_->SetIncomingPassword("Parole", (int)strlen("Parole"));
  488. return true;
  489. }
  490. else
  491. {
  492. URHO3D_LOGINFO("Failed to start server on port " + String(port) + ", error code: " + String((int)startResult));
  493. return false;
  494. }
  495. }
  496. void Network::StopServer()
  497. {
  498. clientConnections_.Clear();
  499. if (!rakPeer_)
  500. return;
  501. if (!IsServerRunning())
  502. return;
  503. // Provide 300 ms to notify
  504. rakPeer_->Shutdown(300);
  505. URHO3D_PROFILE(StopServer);
  506. URHO3D_LOGINFO("Stopped server");
  507. }
  508. void Network::SetNATServerInfo(const String& address, unsigned short port)
  509. {
  510. if (!natPunchServerAddress_)
  511. natPunchServerAddress_ = new SLNet::SystemAddress;
  512. natPunchServerAddress_->FromStringExplicitPort(address.CString(), port);
  513. }
  514. void Network::StartNATClient()
  515. {
  516. if (!rakPeer_) {
  517. URHO3D_LOGERROR("Unable to start NAT client, client not initialized!");
  518. return;
  519. }
  520. if (natPunchServerAddress_->GetPort() == 0) {
  521. URHO3D_LOGERROR("NAT master server address incorrect!");
  522. return;
  523. }
  524. rakPeer_->AttachPlugin(natPunchthroughServerClient_);
  525. guid_ = String(rakPeer_->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
  526. URHO3D_LOGINFO("GUID: " + guid_);
  527. rakPeer_->Connect(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort(), nullptr, 0);
  528. }
  529. void Network::AttemptNATPunchtrough(const String& guid, Scene* scene, const VariantMap& identity)
  530. {
  531. scene_ = scene;
  532. identity_ = identity;
  533. if (!remoteGUID_)
  534. remoteGUID_ = new SLNet::RakNetGUID;
  535. remoteGUID_->FromString(guid.CString());
  536. rakPeerClient_->AttachPlugin(natPunchthroughClient_);
  537. if (rakPeerClient_->IsActive()) {
  538. natPunchthroughClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_);
  539. }
  540. else {
  541. SLNet::SocketDescriptor socket;
  542. // Startup local connection with max 2 incoming connections(first param) and 1 socket description (third param)
  543. rakPeerClient_->Startup(32, &socket, 1);
  544. rakPeerClient_->SetMaximumIncomingConnections(32);
  545. }
  546. rakPeerClient_->Connect(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort(), nullptr, 0);
  547. }
  548. void Network::BroadcastMessage(int msgID, bool reliable, bool inOrder, const VectorBuffer& msg, unsigned contentID)
  549. {
  550. BroadcastMessage(msgID, reliable, inOrder, msg.GetData(), msg.GetSize(), contentID);
  551. }
  552. void Network::BroadcastMessage(int msgID, bool reliable, bool inOrder, const unsigned char* data, unsigned numBytes,
  553. unsigned contentID)
  554. {
  555. if (!rakPeer_)
  556. return;
  557. /* Make sure not to use SLikeNet(RakNet) internal message ID's
  558. and since RakNet uses 1 byte message ID's, they cannot exceed 255 limit */
  559. if (msgID < ID_USER_PACKET_ENUM || msgID >= 255)
  560. {
  561. URHO3D_LOGERROR("Can not send message with reserved ID");
  562. return;
  563. }
  564. VectorBuffer msgData;
  565. msgData.WriteUByte((unsigned char)msgID);
  566. msgData.Write(data, numBytes);
  567. if (isServer_) {
  568. rakPeer_->Send((const char *) msgData.GetData(), (int) msgData.GetSize(), HIGH_PRIORITY, RELIABLE, (char) 0, SLNet::UNASSIGNED_RAKNET_GUID, true);
  569. }
  570. else
  571. URHO3D_LOGERROR("Server not running, can not broadcast messages");
  572. }
  573. void Network::BroadcastRemoteEvent(StringHash eventType, bool inOrder, const VariantMap& eventData)
  574. {
  575. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin(); i != clientConnections_.End(); ++i)
  576. i->second_->SendRemoteEvent(eventType, inOrder, eventData);
  577. }
  578. void Network::BroadcastRemoteEvent(Scene* scene, StringHash eventType, bool inOrder, const VariantMap& eventData)
  579. {
  580. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  581. i != clientConnections_.End(); ++i)
  582. {
  583. if (i->second_->GetScene() == scene)
  584. i->second_->SendRemoteEvent(eventType, inOrder, eventData);
  585. }
  586. }
  587. void Network::BroadcastRemoteEvent(Node* node, StringHash eventType, bool inOrder, const VariantMap& eventData)
  588. {
  589. if (!node)
  590. {
  591. URHO3D_LOGERROR("Null sender node for remote node event");
  592. return;
  593. }
  594. if (!node->IsReplicated())
  595. {
  596. URHO3D_LOGERROR("Sender node has a local ID, can not send remote node event");
  597. return;
  598. }
  599. Scene* scene = node->GetScene();
  600. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  601. i != clientConnections_.End(); ++i)
  602. {
  603. if (i->second_->GetScene() == scene)
  604. i->second_->SendRemoteEvent(node, eventType, inOrder, eventData);
  605. }
  606. }
  607. void Network::SetUpdateFps(int fps)
  608. {
  609. updateFps_ = Max(fps, 1);
  610. updateInterval_ = 1.0f / (float)updateFps_;
  611. updateAcc_ = 0.0f;
  612. }
  613. void Network::SetSimulatedLatency(int ms)
  614. {
  615. simulatedLatency_ = Max(ms, 0);
  616. ConfigureNetworkSimulator();
  617. }
  618. void Network::SetSimulatedPacketLoss(float probability)
  619. {
  620. simulatedPacketLoss_ = Clamp(probability, 0.0f, 1.0f);
  621. ConfigureNetworkSimulator();
  622. }
  623. void Network::RegisterRemoteEvent(StringHash eventType)
  624. {
  625. if (blacklistedRemoteEvents_.Find(eventType) != blacklistedRemoteEvents_.End())
  626. {
  627. URHO3D_LOGERROR("Attempted to register blacklisted remote event type " + String(eventType));
  628. return;
  629. }
  630. allowedRemoteEvents_.Insert(eventType);
  631. }
  632. void Network::UnregisterRemoteEvent(StringHash eventType)
  633. {
  634. allowedRemoteEvents_.Erase(eventType);
  635. }
  636. void Network::UnregisterAllRemoteEvents()
  637. {
  638. allowedRemoteEvents_.Clear();
  639. }
  640. void Network::SetPackageCacheDir(const String& path)
  641. {
  642. packageCacheDir_ = AddTrailingSlash(path);
  643. }
  644. void Network::SendPackageToClients(Scene* scene, PackageFile* package)
  645. {
  646. if (!scene)
  647. {
  648. URHO3D_LOGERROR("Null scene specified for SendPackageToClients");
  649. return;
  650. }
  651. if (!package)
  652. {
  653. URHO3D_LOGERROR("Null package specified for SendPackageToClients");
  654. return;
  655. }
  656. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  657. i != clientConnections_.End(); ++i)
  658. {
  659. if (i->second_->GetScene() == scene)
  660. i->second_->SendPackageToClient(package);
  661. }
  662. }
  663. SharedPtr<HttpRequest> Network::MakeHttpRequest(const String& url, const String& verb, const Vector<String>& headers,
  664. const String& postData)
  665. {
  666. URHO3D_PROFILE(MakeHttpRequest);
  667. // The initialization of the request will take time, can not know at this point if it has an error or not
  668. SharedPtr<HttpRequest> request(new HttpRequest(url, verb, headers, postData));
  669. return request;
  670. }
  671. void Network::BanAddress(const String& address)
  672. {
  673. rakPeer_->AddToBanList(address.CString(), 0);
  674. }
  675. Connection* Network::GetConnection(const SLNet::AddressOrGUID& connection) const
  676. {
  677. if (serverConnection_ && serverConnection_->GetAddressOrGUID() == connection) {
  678. return serverConnection_;
  679. }
  680. else
  681. {
  682. HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Find(connection);
  683. if (i != clientConnections_.End())
  684. return i->second_;
  685. else
  686. return nullptr;
  687. }
  688. }
  689. Connection* Network::GetServerConnection() const
  690. {
  691. return serverConnection_;
  692. }
  693. Vector<SharedPtr<Connection> > Network::GetClientConnections() const
  694. {
  695. Vector<SharedPtr<Connection> > ret;
  696. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::ConstIterator i = clientConnections_.Begin();
  697. i != clientConnections_.End(); ++i)
  698. ret.Push(i->second_);
  699. return ret;
  700. }
  701. bool Network::IsServerRunning() const
  702. {
  703. if (!rakPeer_)
  704. return false;
  705. if (networkMode_ == PEER_TO_PEER && !isServer_) {
  706. return false;
  707. }
  708. return rakPeer_->IsActive() && isServer_;
  709. }
  710. bool Network::CheckRemoteEvent(StringHash eventType) const
  711. {
  712. return allowedRemoteEvents_.Contains(eventType);
  713. }
  714. void Network::HandleIncomingPacket(SLNet::Packet* packet, bool isServer)
  715. {
  716. unsigned char packetID = packet->data[0];
  717. // if (packetID < ID_USER_PACKET_ENUM) {
  718. // URHO3D_LOGERROR(">> " + String((int)packetID) + " HandleIncomingPacket: " + String(RAKNET_MESSAGEID_STRINGS[packetID]));
  719. // }
  720. bool packetHandled = false;
  721. // Deal with timestamped backents
  722. unsigned dataStart = sizeof(char);
  723. if (packetID == ID_TIMESTAMP)
  724. {
  725. dataStart += sizeof(SLNet::Time);
  726. packetID = packet->data[dataStart];
  727. dataStart += sizeof(char);
  728. }
  729. if (packetID == ID_NEW_INCOMING_CONNECTION)
  730. {
  731. URHO3D_LOGINFOF("ID_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
  732. if (isServer)
  733. {
  734. NewConnectionEstablished(packet->guid);
  735. }
  736. packetHandled = true;
  737. }
  738. if (packetID == ID_REMOTE_NEW_INCOMING_CONNECTION)
  739. {
  740. URHO3D_LOGINFOF("ID_REMOTE_NEW_INCOMING_CONNECTION from %s. guid=%s.", packet->systemAddress.ToString(true), packet->guid.ToString());
  741. if (networkMode_ == PEER_TO_PEER)
  742. {
  743. unsigned int count;
  744. SLNet::BitStream bsIn(packet->data, packet->length, false);
  745. bsIn.IgnoreBytes(sizeof(SLNet::MessageID));
  746. bsIn.Read(count);
  747. SLNet::SystemAddress remoteAddress;
  748. SLNet::RakNetGUID remoteGuid;
  749. NewConnectionEstablished(packet->guid);
  750. for (unsigned int i=0; i < count; i++)
  751. {
  752. bsIn.Read(remoteAddress);
  753. bsIn.Read(remoteGuid);
  754. URHO3D_LOGINFO("Remote connection " + String(remoteGuid.ToString()) + " / " + String(packet->guid));
  755. NewConnectionEstablished(packet->guid);
  756. }
  757. } else {
  758. NewConnectionEstablished(packet->systemAddress);
  759. }
  760. packetHandled = true;
  761. }
  762. else if (packetID == ID_REMOTE_CONNECTION_LOST || packetID == ID_REMOTE_DISCONNECTION_NOTIFICATION)
  763. {
  764. //TODO find out who's really sending out this message
  765. packetHandled = true;
  766. }
  767. else if (packetID == ID_ALREADY_CONNECTED)
  768. {
  769. if (natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  770. URHO3D_LOGINFO("Already connected to NAT server! ");
  771. if (!isServer && networkMode_ == SERVER_CLIENT)
  772. {
  773. natPunchthroughClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_);
  774. }
  775. }
  776. packetHandled = true;
  777. }
  778. else if (packetID == ID_CONNECTION_REQUEST_ACCEPTED) // We're a client, our connection has been accepted
  779. {
  780. if(natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  781. URHO3D_LOGINFO("Succesfully connected to NAT punchtrough server! ");
  782. SendEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  783. if (!isServer && remoteGUID_&& networkMode_ == SERVER_CLIENT)
  784. {
  785. natPunchthroughClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_);
  786. }
  787. } else {
  788. if (networkMode_ == SERVER_CLIENT) {
  789. OnServerConnected(packet->guid);
  790. } else {
  791. URHO3D_LOGERROR(">>>>>>>>>>>>>>>>>>>.");
  792. URHO3D_LOGINFOF("ID_CONNECTION_REQUEST_ACCEPTED from %s,guid=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  793. // Assume that we're connecting to the P2P host
  794. // serverConnection_->SetAddressOrGUID(packet->guid);
  795. SLNet::BitStream bsOut;
  796. bsOut.Write((unsigned char) MSG_P2P_JOIN_REQUEST);
  797. rakPeer_->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->guid, false);
  798. }
  799. }
  800. packetHandled = true;
  801. }
  802. else if (packetID == ID_NAT_TARGET_NOT_CONNECTED)
  803. {
  804. URHO3D_LOGERROR("Target server not connected to NAT master server!");
  805. packetHandled = true;
  806. }
  807. else if (packetID == ID_CONNECTION_LOST || packetID == ID_DISCONNECTION_NOTIFICATION) // We've lost connectivity with the packet source
  808. {
  809. if(natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  810. URHO3D_LOGERROR("Connection to NAT server lost!");
  811. P2PConnectNAT(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort());
  812. } else if (isServer)
  813. {
  814. ClientDisconnected(packet->guid);
  815. }
  816. else
  817. {
  818. if (networkMode_ == SERVER_CLIENT) {
  819. OnServerDisconnected();
  820. } else {
  821. ClientDisconnected(packet->guid);
  822. }
  823. }
  824. packetHandled = true;
  825. }
  826. else if (packetID == ID_CONNECTION_ATTEMPT_FAILED) // We've failed to connect to the server/peer
  827. {
  828. if (natPunchServerAddress_ && packet->systemAddress == *natPunchServerAddress_) {
  829. URHO3D_LOGERROR("Connection to NAT punchtrough server failed!");
  830. SendEvent(E_NATMASTERCONNECTIONFAILED);
  831. } else {
  832. if (!isServer)
  833. {
  834. OnServerDisconnected();
  835. }
  836. }
  837. packetHandled = true;
  838. }
  839. else if (packetID == ID_NAT_PUNCHTHROUGH_SUCCEEDED)
  840. {
  841. SLNet::SystemAddress remotePeer = packet->systemAddress;
  842. URHO3D_LOGINFO("NAT punchtrough succeeded! Remote peer: " + String(remotePeer.ToString()));
  843. if (!isServer && networkMode_ == SERVER_CLIENT)
  844. {
  845. using namespace NetworkNatPunchtroughSucceeded;
  846. VariantMap eventMap;
  847. eventMap[P_ADDRESS] = remotePeer.ToString(false);
  848. eventMap[P_PORT] = remotePeer.GetPort();
  849. SendEvent(E_NETWORKNATPUNCHTROUGHSUCCEEDED, eventMap);
  850. URHO3D_LOGINFO("Connecting to server behind NAT: " + String(remotePeer.ToString()));
  851. Connect(String(remotePeer.ToString(false)), remotePeer.GetPort(), scene_, identity_);
  852. } else if (networkMode_ == PEER_TO_PEER){
  853. SLNet::ConnectionAttemptResult car = rakPeer_->Connect(packet->systemAddress.ToString(false), packet->systemAddress.GetPort(), password_.CString(), password_.Length());
  854. }
  855. packetHandled = true;
  856. }
  857. 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)
  858. {
  859. URHO3D_LOGERROR("NAT punchtrough failed!");
  860. SLNet::SystemAddress remotePeer = packet->systemAddress;
  861. using namespace NetworkNatPunchtroughFailed;
  862. VariantMap eventMap;
  863. eventMap[P_ADDRESS] = remotePeer.ToString(false);
  864. eventMap[P_PORT] = remotePeer.GetPort();
  865. SendEvent(E_NETWORKNATPUNCHTROUGHFAILED, eventMap);
  866. packetHandled = true;
  867. }
  868. else if (packetID == ID_CONNECTION_BANNED) // We're a client and we're on the ban list
  869. {
  870. URHO3D_LOGERROR("Connection failed, you're banned!");
  871. SendEvent(E_NETWORKBANNED);
  872. packetHandled = true;
  873. }
  874. else if (packetID == ID_INVALID_PASSWORD) // We're a client, and we gave an invalid password
  875. {
  876. URHO3D_LOGERROR("Invalid password provided for connection!");
  877. SendEvent(E_NETWORKINVALIDPASSWORD);
  878. packetHandled = true;
  879. }
  880. else if (packetID == ID_DOWNLOAD_PROGRESS) // Part of a file transfer
  881. {
  882. //URHO3D_LOGINFO("101010");
  883. }
  884. else if (packetID == ID_UNCONNECTED_PING)
  885. {
  886. packetHandled = true;
  887. }
  888. else if (packetID == ID_READY_EVENT_SET)
  889. {
  890. URHO3D_LOGWARNINGF("Got ID_READY_EVENT_SET from %s", packet->guid.ToString());
  891. P2PReadyStatusChanged();
  892. }
  893. else if (packetID == ID_READY_EVENT_UNSET)
  894. {
  895. P2PReadyStatusChanged();
  896. URHO3D_LOGWARNINGF("Got ID_READY_EVENT_UNSET from %s", packet->guid.ToString());
  897. }
  898. else if (packetID == ID_READY_EVENT_ALL_SET)
  899. {
  900. P2PReadyStatusChanged();
  901. URHO3D_LOGWARNINGF("ID_READY_EVENT_ALL_SET from %s", packet->guid.ToString());
  902. }
  903. else if (packetID == ID_READY_EVENT_QUERY)
  904. {
  905. P2PReadyStatusChanged();
  906. URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_QUERY from %s", packet->guid.ToString());
  907. }
  908. else if (packetID == ID_READY_EVENT_FORCE_ALL_SET)
  909. {
  910. P2PReadyStatusChanged();
  911. URHO3D_LOGINFOF("`````````````````````````` Got ID_READY_EVENT_FORCE_ALL_SET from %s", packet->guid.ToString());
  912. }
  913. else if (packetID == ID_UNCONNECTED_PONG) // Host discovery response
  914. {
  915. if (!isServer)
  916. {
  917. using namespace NetworkHostDiscovered;
  918. dataStart += sizeof(SLNet::TimeMS);
  919. VariantMap& eventMap = context_->GetEventDataMap();
  920. if (packet->length > packet->length - dataStart) {
  921. VectorBuffer buffer(packet->data + dataStart, packet->length - dataStart);
  922. VariantMap srcData = buffer.ReadVariantMap();
  923. eventMap[P_BEACON] = srcData;
  924. }
  925. else {
  926. eventMap[P_BEACON] = VariantMap();
  927. }
  928. eventMap[P_ADDRESS] = String(packet->systemAddress.ToString(false));
  929. eventMap[P_PORT] = (int)packet->systemAddress.GetPort();
  930. SendEvent(E_NETWORKHOSTDISCOVERED, eventMap);
  931. }
  932. packetHandled = true;
  933. }
  934. else if (packetID == ID_FCM2_NEW_HOST)
  935. {
  936. URHO3D_LOGINFO("");
  937. // URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: System %s is host, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  938. SLNet::BitStream bs(packet->data,packet->length,false);
  939. bs.IgnoreBytes(1);
  940. SLNet::RakNetGUID oldHost;
  941. bs.Read(oldHost);
  942. if (serverConnection_) {
  943. serverConnection_->SetAddressOrGUID(packet->guid);
  944. }
  945. hostGuid_ = packet->guid.ToString();
  946. if (packet->guid == rakPeer_->GetMyGUID())
  947. {
  948. isServer_ = true;
  949. if (oldHost != SLNet::UNASSIGNED_RAKNET_GUID)
  950. {
  951. URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: Taking over as host from the old host [%s].", oldHost.ToString());
  952. }
  953. else
  954. {
  955. // Room not hosted if we become host the first time since this was done in CreateRoom() already
  956. URHO3D_LOGINFO("ID_FCM2_NEW_HOST: We have become host for the first time");
  957. }
  958. for (auto it = clientConnections_.Begin(); it != clientConnections_.End(); ++it) {
  959. URHO3D_LOGINFO("Setting new scene for clients");
  960. // (*it).second_->SetScene(serverConnection_->GetScene());
  961. //TODO decide what to do when we take ownership as the host, should the scene needs to be reloaded?
  962. (*it).second_->SetSceneLoaded(true);
  963. }
  964. }
  965. else
  966. {
  967. isServer_ = false;
  968. if (oldHost != SLNet::UNASSIGNED_RAKNET_GUID) {
  969. URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: A new system %s has become host, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  970. }
  971. else {
  972. URHO3D_LOGINFOF("ID_FCM2_NEW_HOST: System %s is host, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
  973. }
  974. // Send the identity map now
  975. VectorBuffer msg;
  976. msg.WriteVariantMap(serverConnection_->GetIdentity());
  977. serverConnection_->SendMessage(MSG_IDENTITY, true, true, msg);
  978. }
  979. using namespace P2PNewHost;
  980. VariantMap data = GetEventDataMap();
  981. data[P_ADDRESS] = packet->systemAddress.ToString(false);
  982. data[P_PORT] = packet->systemAddress.GetPort();
  983. data[P_GUID] = packet->guid.ToString();
  984. SendEvent(E_P2PNEWHOST, data);
  985. P2PReadyStatusChanged();
  986. URHO3D_LOGINFO("");
  987. packetHandled = true;
  988. }
  989. else if (packetID == ID_FCM2_VERIFIED_JOIN_START) {
  990. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_START");
  991. // DataStructures::List <SLNet::SystemAddress> addresses;
  992. // DataStructures::List <SLNet::RakNetGUID> guids;
  993. // DataStructures::List < SLNet::BitStream * > userData;
  994. // fullyConnectedMesh2_->GetVerifiedJoinRequiredProcessingList(packet->guid, addresses, guids, userData);
  995. // for (unsigned int i = 0; i < guids.Size(); i++)
  996. // {
  997. // natPunchthroughServerClient_->OpenNAT(guids[i], *natPunchServerAddress_);
  998. // }
  999. }
  1000. else if (packetID == ID_FCM2_VERIFIED_JOIN_CAPABLE)
  1001. {
  1002. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_CAPABLE");
  1003. fullyConnectedMesh2_->RespondOnVerifiedJoinCapable(packet, true, nullptr);
  1004. packetHandled = true;
  1005. }
  1006. else if (packetID == ID_FCM2_VERIFIED_JOIN_ACCEPTED)
  1007. {
  1008. DataStructures::List<SLNet::RakNetGUID> systemsAccepted;
  1009. bool thisSystemAccepted;
  1010. fullyConnectedMesh2_->GetVerifiedJoinAcceptedAdditionalData(packet, &thisSystemAccepted, systemsAccepted, nullptr);
  1011. if (thisSystemAccepted) {
  1012. URHO3D_LOGINFO("Game join request accepted");
  1013. }
  1014. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_ACCEPTED");
  1015. packetHandled = true;
  1016. }
  1017. else if (packetID == ID_FCM2_VERIFIED_JOIN_REJECTED)
  1018. {
  1019. URHO3D_LOGINFO("ID_FCM2_VERIFIED_JOIN_REJECTED");
  1020. }
  1021. else if (packetID == ID_FCM2_REQUEST_FCMGUID)
  1022. {
  1023. URHO3D_LOGINFO("ID_FCM2_REQUEST_FCMGUID");
  1024. }
  1025. else if (packetID == ID_FCM2_RESPOND_CONNECTION_COUNT)
  1026. {
  1027. URHO3D_LOGINFO("ID_FCM2_RESPOND_CONNECTION_COUNT");
  1028. }
  1029. else if (packetID == ID_FCM2_INFORM_FCMGUID)
  1030. {
  1031. URHO3D_LOGINFO("ID_FCM2_INFORM_FCMGUID");
  1032. }
  1033. else if (packetID == ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT)
  1034. {
  1035. URHO3D_LOGINFO("ID_FCM2_UPDATE_MIN_TOTAL_CONNECTION_COUNT");
  1036. }
  1037. else if (packetID == ID_FCM2_UPDATE_USER_CONTEXT)
  1038. {
  1039. URHO3D_LOGINFO("ID_FCM2_UPDATE_USER_CONTEXT");
  1040. }
  1041. // Urho3D messages
  1042. if (packetID >= ID_USER_PACKET_ENUM)
  1043. {
  1044. //URHO3D_LOGINFOF("ID_USER_PACKET_ENUM %i", packetID);
  1045. if (packetID == MSG_P2P_JOIN_REQUEST) {
  1046. URHO3D_LOGINFO("MSG_P2P_JOIN_REQUEST");
  1047. //TODO decide if the client is able to join
  1048. fullyConnectedMesh2_->StartVerifiedJoin(packet->guid);
  1049. //TODO or deny the join request
  1050. // VectorBuffer msg;
  1051. // GetConnection(packet->guid)->SendMessage(MSG_P2P_JOIN_REQUEST_DENIED, true, true, msg);
  1052. // ClientDisconnected(packet->guid);
  1053. } else if (networkMode_ == PEER_TO_PEER && P2PIsHostSystem())
  1054. {
  1055. // We are the host in the P2P server, parse the message accordingly
  1056. HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
  1057. }
  1058. else if (networkMode_ == SERVER_CLIENT && isServer_) {
  1059. // We are the server in the server-client connection
  1060. HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
  1061. }
  1062. else {
  1063. // we are client in either P2P or server-client mode
  1064. MemoryBuffer buffer(packet->data + dataStart, packet->length - dataStart);
  1065. bool processed = serverConnection_->ProcessMessage(packetID, buffer);
  1066. if (!processed)
  1067. {
  1068. HandleMessage(packet->guid, 0, packetID, (const char*)(packet->data + dataStart), packet->length - dataStart);
  1069. }
  1070. }
  1071. packetHandled = true;
  1072. }
  1073. if (!packetHandled && packetID < sizeof(RAKNET_MESSAGEID_STRINGS))
  1074. URHO3D_LOGERROR("Unhandled network packet: " + String(RAKNET_MESSAGEID_STRINGS[packetID]));
  1075. else if (!packetHandled)
  1076. URHO3D_LOGERRORF("Unhandled network packet: %i", packetID);
  1077. }
  1078. void Network::Update(float timeStep)
  1079. {
  1080. URHO3D_PROFILE(UpdateNetwork);
  1081. //Process all incoming messages for the server
  1082. if (rakPeer_->IsActive())
  1083. {
  1084. while (SLNet::Packet* packet = rakPeer_->Receive())
  1085. {
  1086. if (P2PIsHostSystem() || networkMode_ == SERVER_CLIENT) {
  1087. HandleIncomingPacket(packet, true);
  1088. }
  1089. else {
  1090. HandleIncomingPacket(packet, false);
  1091. }
  1092. rakPeer_->DeallocatePacket(packet);
  1093. }
  1094. }
  1095. // Process all incoming messages for the client
  1096. if (rakPeerClient_->IsActive())
  1097. {
  1098. //bool isHost = P2PIsHostSystem();
  1099. while (SLNet::Packet* packet = rakPeerClient_->Receive())
  1100. {
  1101. HandleIncomingPacket(packet, false);
  1102. rakPeerClient_->DeallocatePacket(packet);
  1103. }
  1104. }
  1105. }
  1106. void Network::PostUpdate(float timeStep)
  1107. {
  1108. URHO3D_PROFILE(PostUpdateNetwork);
  1109. // Check if periodic update should happen now
  1110. updateAcc_ += timeStep;
  1111. bool updateNow = updateAcc_ >= updateInterval_;
  1112. if (updateNow)
  1113. {
  1114. // Notify of the impending update to allow for example updated client controls to be set
  1115. SendEvent(E_NETWORKUPDATE);
  1116. updateAcc_ = fmodf(updateAcc_, updateInterval_);
  1117. if (IsServerRunning())
  1118. {
  1119. // Collect and prepare all networked scenes
  1120. {
  1121. URHO3D_PROFILE(PrepareServerUpdate);
  1122. networkScenes_.Clear();
  1123. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  1124. i != clientConnections_.End(); ++i)
  1125. {
  1126. Scene* scene = i->second_->GetScene();
  1127. if (scene)
  1128. networkScenes_.Insert(scene);
  1129. }
  1130. for (HashSet<Scene*>::ConstIterator i = networkScenes_.Begin(); i != networkScenes_.End(); ++i)
  1131. (*i)->PrepareNetworkUpdate();
  1132. }
  1133. {
  1134. URHO3D_PROFILE(SendServerUpdate);
  1135. // Then send server updates for each client connection
  1136. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  1137. i != clientConnections_.End(); ++i)
  1138. {
  1139. i->second_->SendServerUpdate();
  1140. i->second_->SendRemoteEvents();
  1141. i->second_->SendPackages();
  1142. }
  1143. }
  1144. }
  1145. if (serverConnection_)
  1146. {
  1147. if (networkMode_ == PEER_TO_PEER && !isServer_ && serverConnection_->GetGUID() != P2PGetGUID()) {
  1148. // Send the client update
  1149. serverConnection_->SendClientUpdate();
  1150. serverConnection_->SendRemoteEvents();
  1151. } else if (networkMode_ == SERVER_CLIENT) {
  1152. // Send the client update
  1153. serverConnection_->SendClientUpdate();
  1154. serverConnection_->SendRemoteEvents();
  1155. }
  1156. }
  1157. // Notify that the update was sent
  1158. SendEvent(E_NETWORKUPDATESENT);
  1159. }
  1160. }
  1161. void Network::HandleBeginFrame(StringHash eventType, VariantMap& eventData)
  1162. {
  1163. using namespace BeginFrame;
  1164. Update(eventData[P_TIMESTEP].GetFloat());
  1165. }
  1166. void Network::HandleRenderUpdate(StringHash eventType, VariantMap& eventData)
  1167. {
  1168. using namespace RenderUpdate;
  1169. PostUpdate(eventData[P_TIMESTEP].GetFloat());
  1170. }
  1171. void Network::OnServerConnected(const SLNet::AddressOrGUID& address)
  1172. {
  1173. serverConnection_->SetConnectPending(false);
  1174. serverConnection_->SetAddressOrGUID(address);
  1175. URHO3D_LOGINFO("Connected to server!");
  1176. // Send the identity map now
  1177. VectorBuffer msg;
  1178. msg.WriteVariantMap(serverConnection_->GetIdentity());
  1179. serverConnection_->SendMessage(MSG_IDENTITY, true, true, msg);
  1180. SendEvent(E_SERVERCONNECTED);
  1181. }
  1182. void Network::OnServerDisconnected()
  1183. {
  1184. if (networkMode_ == PEER_TO_PEER) {
  1185. return;
  1186. }
  1187. // Differentiate between failed connection, and disconnection
  1188. bool failedConnect = serverConnection_ && serverConnection_->IsConnectPending();
  1189. serverConnection_.Reset();
  1190. if (!failedConnect)
  1191. {
  1192. URHO3D_LOGINFO("Disconnected from server");
  1193. SendEvent(E_SERVERDISCONNECTED);
  1194. }
  1195. else
  1196. {
  1197. URHO3D_LOGERROR("Failed to connect to server");
  1198. SendEvent(E_CONNECTFAILED);
  1199. }
  1200. }
  1201. void Network::ConfigureNetworkSimulator()
  1202. {
  1203. if (serverConnection_)
  1204. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1205. for (HashMap<SLNet::AddressOrGUID, SharedPtr<Connection> >::Iterator i = clientConnections_.Begin();
  1206. i != clientConnections_.End(); ++i)
  1207. i->second_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1208. }
  1209. bool Network::P2PStartSession(Scene* scene, const VariantMap& identity)
  1210. {
  1211. Disconnect(1000);
  1212. if (!natPunchServerAddress_) {
  1213. URHO3D_LOGERROR("Set the NAT server info first!");
  1214. return false;
  1215. }
  1216. P2PConnectNAT(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort());
  1217. if (networkMode_ == SERVER_CLIENT) {
  1218. URHO3D_LOGERROR("P2P sessions are not available for SERVER_CLIENT mode!");
  1219. return false;
  1220. }
  1221. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1222. SubscribeToEvent(E_NATMASTERCONNECTIONSUCCEEDED, URHO3D_HANDLER(Network, HandleNATStartP2PSession));
  1223. scene_ = scene;
  1224. identity_ = identity;
  1225. return true;
  1226. }
  1227. void Network::HandleNATStartP2PSession(StringHash eventType, VariantMap& eventData)
  1228. {
  1229. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1230. isServer_ = false;
  1231. if (!serverConnection_) {
  1232. serverConnection_ = new Connection(context_, false, rakPeer_->GetMyGUID(), rakPeer_);
  1233. serverConnection_->SetScene(scene_);
  1234. serverConnection_->SetSceneLoaded(true);
  1235. serverConnection_->SetIdentity(identity_);
  1236. serverConnection_->SetConnectPending(true);
  1237. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1238. }
  1239. rakPeer_->SetOccasionalPing(true);
  1240. fullyConnectedMesh2_->Clear();
  1241. fullyConnectedMesh2_->ResetHostCalculation();
  1242. hostGuid_ = P2PGetGUID();
  1243. isServer_ = true;
  1244. P2PSetReady(false);
  1245. SendEvent(E_P2PSESSIONSTARTED);
  1246. }
  1247. void Network::P2PJoinSession(const String& guid, Scene* scene, const VariantMap& identity)
  1248. {
  1249. Disconnect(1000);
  1250. if (!natPunchServerAddress_) {
  1251. URHO3D_LOGERROR("Set the NAT server info first!");
  1252. return;
  1253. }
  1254. P2PConnectNAT(natPunchServerAddress_->ToString(false), natPunchServerAddress_->GetPort());
  1255. if (networkMode_ == SERVER_CLIENT) {
  1256. URHO3D_LOGERROR("P2P sessions are not available for SERVER_CLIENT mode!");
  1257. return;
  1258. }
  1259. if (remoteGUID_) {
  1260. delete remoteGUID_;
  1261. remoteGUID_ = nullptr;
  1262. }
  1263. remoteGUID_ = new SLNet::RakNetGUID;
  1264. remoteGUID_->FromString(guid.CString());
  1265. scene_ = scene;
  1266. identity_ = identity;
  1267. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1268. SubscribeToEvent(E_NATMASTERCONNECTIONSUCCEEDED, URHO3D_HANDLER(Network, HandleNATJoinP2PSession));
  1269. }
  1270. void Network::HandleNATJoinP2PSession(StringHash eventType, VariantMap& eventData)
  1271. {
  1272. UnsubscribeFromEvent(E_NATMASTERCONNECTIONSUCCEEDED);
  1273. P2PSetReady(false);
  1274. if (!serverConnection_) {
  1275. serverConnection_ = new Connection(context_, false, rakPeer_->GetMyBoundAddress(), rakPeer_);
  1276. serverConnection_->SetScene(scene_);
  1277. serverConnection_->SetSceneLoaded(true);
  1278. serverConnection_->SetIdentity(identity_);
  1279. serverConnection_->SetConnectPending(true);
  1280. serverConnection_->SetAddressOrGUID(*remoteGUID_);
  1281. serverConnection_->ConfigureNetworkSimulator(simulatedLatency_, simulatedPacketLoss_);
  1282. }
  1283. rakPeer_->SetOccasionalPing(true);
  1284. fullyConnectedMesh2_->ResetHostCalculation();
  1285. fullyConnectedMesh2_->Clear();
  1286. URHO3D_LOGINFO("Attempting to Join P2P Session : " + String(remoteGUID_->ToString()));
  1287. natPunchthroughServerClient_->OpenNAT(*remoteGUID_, *natPunchServerAddress_);
  1288. }
  1289. int Network::GetP2PParticipantCount()
  1290. {
  1291. if (networkMode_ == SERVER_CLIENT) {
  1292. return 0;
  1293. }
  1294. return fullyConnectedMesh2_->GetParticipantCount();
  1295. }
  1296. bool Network::P2PIsConnectedHost()
  1297. {
  1298. if (networkMode_ == SERVER_CLIENT) {
  1299. return false;
  1300. }
  1301. return fullyConnectedMesh2_->IsConnectedHost();
  1302. }
  1303. bool Network::P2PIsHostSystem()
  1304. {
  1305. return fullyConnectedMesh2_->IsHostSystem();
  1306. }
  1307. String Network::P2PGetHostAddress()
  1308. {
  1309. if (networkMode_ == SERVER_CLIENT) {
  1310. return "";
  1311. }
  1312. return hostGuid_;
  1313. }
  1314. void Network::P2PSetReady(bool value)
  1315. {
  1316. if (networkMode_ == SERVER_CLIENT) {
  1317. return;
  1318. }
  1319. // readyEvent_->DeleteEvent(0);
  1320. readyEvent_->SetEvent(0, value);
  1321. }
  1322. bool Network::P2PGetReady()
  1323. {
  1324. if (networkMode_ == SERVER_CLIENT) {
  1325. return false;
  1326. }
  1327. return readyEvent_->IsEventSet(0);
  1328. }
  1329. String Network::P2PGetGUID()
  1330. {
  1331. return String(rakPeer_->GetGuidFromSystemAddress(SLNet::UNASSIGNED_SYSTEM_ADDRESS).ToString());
  1332. }
  1333. void Network::P2PReadyStatusChanged()
  1334. {
  1335. if (networkMode_ == SERVER_CLIENT) {
  1336. return;
  1337. }
  1338. DataStructures::List<SLNet::RakNetGUID> participantList;
  1339. fullyConnectedMesh2_->GetParticipantList(participantList);
  1340. for (unsigned int i = 0; i < participantList.Size(); i++) {
  1341. if (participantList[i] != rakPeerClient_->GetMyGUID()) {
  1342. readyEvent_->AddToWaitList(0, participantList[i]);
  1343. }
  1344. }
  1345. static const char* STATUS_MESSAGES[] = {
  1346. "RES_NOT_WAITING",
  1347. "RES_WAITING",
  1348. "RES_READY",
  1349. "RES_ALL_READY",
  1350. "RES_UNKNOWN_EVENT"
  1351. };
  1352. fullyConnectedMesh2_->GetParticipantList(participantList);
  1353. bool allValid = true;
  1354. for (unsigned int i = 0; i < participantList.Size(); i++) {
  1355. if (participantList[i] != rakPeer_->GetMyGUID()) {
  1356. int ready = readyEvent_->GetReadyStatus(0, participantList[i]);// == SLNet::RES_READY;
  1357. if (ready != SLNet::RES_ALL_READY && ready != SLNet::RES_READY) {
  1358. allValid = false;
  1359. }
  1360. // URHO3D_LOGINFO( String(participantList[i].ToString()) + " Ready: " + String(STATUS_MESSAGES[ready]));
  1361. }
  1362. }
  1363. // URHO3D_LOGINFO(P2PGetGUID() + " Ready: " + String(STATUS_MESSAGES[readyEvent_->GetEventAtIndex(0)]));
  1364. VariantMap data = GetEventDataMap();
  1365. if (allValid && readyEvent_->IsEventSet(0)) {
  1366. data[P2PAllReadyChanged::P_READY] = true;
  1367. } else {
  1368. data[P2PAllReadyChanged::P_READY] = false;
  1369. }
  1370. // URHO3D_LOGWARNING("All ready " + String(data[P2PAllReadyChanged::P_READY].GetBool()));
  1371. SendEvent(E_P2PALLREADYCHANGED, data);
  1372. }
  1373. void Network::P2PResetHost()
  1374. {
  1375. if (networkMode_ == SERVER_CLIENT) {
  1376. return;
  1377. }
  1378. fullyConnectedMesh2_->ResetHostCalculation();
  1379. }
  1380. void Network::SetMode(NetworkMode mode, bool force)
  1381. {
  1382. if (rakPeer_->IsActive() || rakPeerClient_->IsActive()) {
  1383. URHO3D_LOGERROR("Failed to change network mode! Shutdown networking system first or use forced mode changing!");
  1384. return;
  1385. }
  1386. if (force) {
  1387. if (rakPeer_->IsActive()) {
  1388. rakPeer_->Shutdown(100);
  1389. }
  1390. if (rakPeerClient_->IsActive()) {
  1391. rakPeerClient_->Shutdown(100);
  1392. }
  1393. clientConnections_.Clear();
  1394. serverConnection_.Reset();
  1395. }
  1396. networkMode_ = mode;
  1397. }
  1398. const NetworkMode Network::GetMode() const
  1399. {
  1400. return networkMode_;
  1401. }
  1402. void RegisterNetworkLibrary(Context* context)
  1403. {
  1404. NetworkPriority::RegisterObject(context);
  1405. }
  1406. }