RemoteToolsSystemComponent.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <RemoteToolsSystemComponent.h>
  9. #include <AzCore/Component/ComponentApplicationBus.h>
  10. #include <AzCore/Serialization/SerializeContext.h>
  11. #include <AzCore/Serialization/EditContext.h>
  12. #include <AzCore/Serialization/EditContextConstants.inl>
  13. #include <AzCore/Serialization/ObjectStream.h>
  14. #include <AzNetworking/Framework/INetworking.h>
  15. #include <AzNetworking/Utilities/CidrAddress.h>
  16. #include <Source/AutoGen/RemoteTools.AutoPackets.h>
  17. #include <Source/AutoGen/RemoteTools.AutoPacketDispatcher.h>
  18. namespace RemoteTools
  19. {
  20. static constexpr const char* RemoteServerAddress = "127.0.0.1";
  21. // id for the local application
  22. static constexpr AZ::u32 SelfNetworkId = 0xFFFFFFFF;
  23. AZ_CVAR(uint16_t, remote_outbox_interval, 50, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The interval to process outbound messages.");
  24. AZ_CVAR(uint16_t, remote_join_interval, 1000, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The interval to attempt automatic connecitons.");
  25. void RemoteToolsSystemComponent::Reflect(AZ::ReflectContext* context)
  26. {
  27. if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
  28. {
  29. serialize->Class<RemoteToolsSystemComponent, AZ::Component>()
  30. ->Version(0)
  31. ;
  32. if (AZ::EditContext* ec = serialize->GetEditContext())
  33. {
  34. ec->Class<RemoteToolsSystemComponent>("RemoteTools", "[Description of functionality provided by this System Component]")
  35. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  36. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  37. ;
  38. }
  39. }
  40. }
  41. void RemoteToolsSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  42. {
  43. provided.push_back(AZ_CRC_CE("RemoteToolsService"));
  44. }
  45. void RemoteToolsSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  46. {
  47. incompatible.push_back(AZ_CRC_CE("RemoteToolsService"));
  48. }
  49. void RemoteToolsSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required)
  50. {
  51. ;
  52. }
  53. void RemoteToolsSystemComponent::GetDependentServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& dependent)
  54. {
  55. ;
  56. }
  57. RemoteToolsSystemComponent::RemoteToolsSystemComponent()
  58. {
  59. #if defined(ENABLE_REMOTE_TOOLS)
  60. if (AzFramework::RemoteToolsInterface::Get() == nullptr)
  61. {
  62. AzFramework::RemoteToolsInterface::Register(this);
  63. }
  64. #endif
  65. }
  66. RemoteToolsSystemComponent::~RemoteToolsSystemComponent()
  67. {
  68. #if defined(ENABLE_REMOTE_TOOLS)
  69. if (AzFramework::RemoteToolsInterface::Get() == this)
  70. {
  71. AzFramework::RemoteToolsInterface::Unregister(this);
  72. }
  73. #endif
  74. }
  75. void RemoteToolsSystemComponent::Init()
  76. {
  77. }
  78. void RemoteToolsSystemComponent::Activate()
  79. {
  80. m_joinThread = AZStd::make_unique<RemoteToolsJoinThread>(remote_join_interval, this);
  81. AZ::SystemTickBus::Handler::BusConnect();
  82. }
  83. void RemoteToolsSystemComponent::Deactivate()
  84. {
  85. AZ::SystemTickBus::Handler::BusDisconnect();
  86. m_joinThread = nullptr;
  87. if (AzNetworking::INetworking* networking = AZ::Interface<AzNetworking::INetworking>::Get())
  88. {
  89. for (auto registryIt = m_entryRegistry.begin(); registryIt != m_entryRegistry.end(); ++registryIt)
  90. {
  91. networking->DestroyNetworkInterface(registryIt->second.m_name);
  92. }
  93. }
  94. m_entryRegistry.clear();
  95. }
  96. void RemoteToolsSystemComponent::OnSystemTick()
  97. {
  98. // Join thread can stop itself, check if it needs to join
  99. if (m_joinThread && !m_joinThread->IsRunning())
  100. {
  101. m_joinThread->Join();
  102. }
  103. }
  104. void RemoteToolsSystemComponent::RegisterToolingServiceClient(AZ::Crc32 key, AZ::Name name, uint16_t port)
  105. {
  106. if (!m_entryRegistry.contains(key))
  107. {
  108. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  109. }
  110. m_entryRegistry[key].m_isHost = false;
  111. m_entryRegistry[key].m_name = name;
  112. m_entryRegistry[key].m_ip = AzNetworking::IpAddress(RemoteServerAddress, port, AzNetworking::ProtocolType::Tcp);
  113. if (AzNetworking::INetworking* networking = AZ::Interface<AzNetworking::INetworking>::Get())
  114. {
  115. AzNetworking::INetworkInterface* netInterface = networking->CreateNetworkInterface(
  116. name, AzNetworking::ProtocolType::Tcp, AzNetworking::TrustZone::ExternalClientToServer, *this);
  117. netInterface->SetTimeoutMs(AZ::TimeMs(0));
  118. }
  119. if (m_joinThread && !m_joinThread->IsRunning())
  120. {
  121. m_joinThread->Join();
  122. m_joinThread->Start();
  123. }
  124. }
  125. void RemoteToolsSystemComponent::RegisterToolingServiceHost(AZ::Crc32 key, AZ::Name name, uint16_t port)
  126. {
  127. if (!m_entryRegistry.contains(key))
  128. {
  129. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  130. }
  131. m_entryRegistry[key].m_isHost = true;
  132. m_entryRegistry[key].m_name = name;
  133. AzFramework::RemoteToolsEndpointContainer::pair_iter_bool ret = m_entryRegistry[key].m_availableTargets.insert_key(key);
  134. AzFramework::RemoteToolsEndpointInfo& ti = ret.first->second;
  135. ti.SetInfo("Self", key, SelfNetworkId);
  136. if (AzNetworking::INetworking* networking = AZ::Interface<AzNetworking::INetworking>::Get())
  137. {
  138. AzNetworking::INetworkInterface* netInterface = networking->CreateNetworkInterface(
  139. name, AzNetworking::ProtocolType::Tcp, AzNetworking::TrustZone::ExternalClientToServer, *this);
  140. netInterface->SetTimeoutMs(AZ::TimeMs(0));
  141. netInterface->Listen(port);
  142. }
  143. }
  144. const AzFramework::ReceivedRemoteToolsMessages* RemoteToolsSystemComponent::GetReceivedMessages(AZ::Crc32 key) const
  145. {
  146. if (m_inbox.contains(key))
  147. {
  148. return &m_inbox.at(key);
  149. }
  150. return nullptr;
  151. }
  152. void RemoteToolsSystemComponent::ClearReceivedMessages(AZ::Crc32 key)
  153. {
  154. if (m_inbox.contains(key))
  155. {
  156. m_inbox.at(key).clear();
  157. }
  158. }
  159. void RemoteToolsSystemComponent::RegisterRemoteToolsEndpointJoinedHandler(
  160. AZ::Crc32 key, AzFramework::RemoteToolsEndpointStatusEvent::Handler& handler)
  161. {
  162. if (!m_entryRegistry.contains(key))
  163. {
  164. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  165. }
  166. handler.Connect(m_entryRegistry[key].m_endpointJoinedEvent);
  167. }
  168. void RemoteToolsSystemComponent::RegisterRemoteToolsEndpointLeftHandler(
  169. AZ::Crc32 key, AzFramework::RemoteToolsEndpointStatusEvent::Handler& handler)
  170. {
  171. if (!m_entryRegistry.contains(key))
  172. {
  173. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  174. }
  175. handler.Connect(m_entryRegistry[key].m_endpointLeftEvent);
  176. }
  177. void RemoteToolsSystemComponent::RegisterRemoteToolsEndpointConnectedHandler(
  178. AZ::Crc32 key, AzFramework::RemoteToolsEndpointConnectedEvent::Handler& handler)
  179. {
  180. if (!m_entryRegistry.contains(key))
  181. {
  182. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  183. }
  184. handler.Connect(m_entryRegistry[key].m_endpointConnectedEvent);
  185. }
  186. void RemoteToolsSystemComponent::RegisterRemoteToolsEndpointChangedHandler(
  187. AZ::Crc32 key, AzFramework::RemoteToolsEndpointChangedEvent::Handler& handler)
  188. {
  189. if (!m_entryRegistry.contains(key))
  190. {
  191. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  192. }
  193. handler.Connect(m_entryRegistry[key].m_endpointChangedEvent);
  194. }
  195. void RemoteToolsSystemComponent::EnumTargetInfos(AZ::Crc32 key, AzFramework::RemoteToolsEndpointContainer& infos)
  196. {
  197. if (m_entryRegistry.contains(key))
  198. {
  199. infos = m_entryRegistry[key].m_availableTargets;
  200. }
  201. else
  202. {
  203. infos = AzFramework::RemoteToolsEndpointContainer();
  204. }
  205. }
  206. void RemoteToolsSystemComponent::SetDesiredEndpoint(AZ::Crc32 key, AZ::u32 desiredTargetID)
  207. {
  208. AZ_TracePrintf("RemoteToolsSystemComponent", "Set Target - %u", desiredTargetID);
  209. if (m_entryRegistry.contains(key))
  210. {
  211. RemoteToolsRegistryEntry& entry = m_entryRegistry[key];
  212. if (desiredTargetID != entry.m_lastTarget.GetPersistentId())
  213. {
  214. AzFramework::RemoteToolsEndpointInfo ti = GetEndpointInfo(key, desiredTargetID);
  215. AZ::u32 oldTargetID = entry.m_lastTarget.GetPersistentId();
  216. entry.m_lastTarget = ti;
  217. entry.m_tmpInboundBuffer.clear();
  218. entry.m_tmpInboundBufferPos = 0;
  219. m_entryRegistry[key].m_endpointChangedEvent.Signal(desiredTargetID, oldTargetID);
  220. if (ti.IsValid() && ti.IsOnline())
  221. {
  222. m_entryRegistry[key].m_endpointConnectedEvent.Signal(true);
  223. }
  224. else
  225. {
  226. m_entryRegistry[key].m_endpointConnectedEvent.Signal(false);
  227. }
  228. }
  229. }
  230. }
  231. void RemoteToolsSystemComponent::SetDesiredEndpointInfo(AZ::Crc32 key, const AzFramework::RemoteToolsEndpointInfo& targetInfo)
  232. {
  233. SetDesiredEndpoint(key, targetInfo.GetPersistentId());
  234. }
  235. AzFramework::RemoteToolsEndpointInfo RemoteToolsSystemComponent::GetDesiredEndpoint(AZ::Crc32 key)
  236. {
  237. if (m_entryRegistry.contains(key))
  238. {
  239. return m_entryRegistry[key].m_lastTarget;
  240. }
  241. return AzFramework::RemoteToolsEndpointInfo(); // return an invalid target info.
  242. }
  243. AzFramework::RemoteToolsEndpointInfo RemoteToolsSystemComponent::GetEndpointInfo(AZ::Crc32 key, AZ::u32 desiredTargetID)
  244. {
  245. if (m_entryRegistry.contains(key))
  246. {
  247. AzFramework::RemoteToolsEndpointContainer container = m_entryRegistry[key].m_availableTargets;
  248. AzFramework::RemoteToolsEndpointContainer::const_iterator finder = container.find(desiredTargetID);
  249. if (finder != container.end())
  250. {
  251. return finder->second;
  252. }
  253. }
  254. return AzFramework::RemoteToolsEndpointInfo(); // return an invalid target info.
  255. }
  256. bool RemoteToolsSystemComponent::IsEndpointOnline(AZ::Crc32 key, AZ::u32 desiredTargetID)
  257. {
  258. if (m_entryRegistry.contains(key))
  259. {
  260. AzFramework::RemoteToolsEndpointContainer container = m_entryRegistry[key].m_availableTargets;
  261. AzFramework::RemoteToolsEndpointContainer::const_iterator finder = container.find(desiredTargetID);
  262. if (finder != container.end())
  263. {
  264. return finder->second.IsOnline();
  265. }
  266. }
  267. return false;
  268. }
  269. void RemoteToolsSystemComponent::SendRemoteToolsMessage(
  270. const AzFramework::RemoteToolsEndpointInfo& target, const AzFramework::RemoteToolsMessage& msg)
  271. {
  272. AZ::SerializeContext* serializeContext;
  273. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  274. // Messages targeted at our own application just transfer right over to the inbox.
  275. if (target.IsSelf())
  276. {
  277. AzFramework::RemoteToolsMessage* inboxMessage = aznew AzFramework::RemoteToolsMessage(msg.GetId());
  278. inboxMessage->SetSenderTargetId(target.GetPersistentId());
  279. if (msg.GetCustomBlobSize() > 0)
  280. {
  281. if (msg.GetIsBlobOwner())
  282. {
  283. void* blob = azmalloc(msg.GetCustomBlobSize(), 16, AZ::OSAllocator);
  284. memcpy(blob, msg.GetCustomBlob().data(), msg.GetCustomBlobSize());
  285. inboxMessage->AddCustomBlob(blob, msg.GetCustomBlobSize(), true);
  286. }
  287. else
  288. {
  289. inboxMessage->AddCustomBlob(msg.GetCustomBlob(), false);
  290. }
  291. }
  292. m_inboxMutex.lock();
  293. m_inbox[msg.GetSenderTargetId()].push_back(inboxMessage);
  294. m_inboxMutex.unlock();
  295. return;
  296. }
  297. AZStd::vector<char, AZ::OSStdAllocator> msgBuffer;
  298. AZ::IO::ByteContainerStream<AZStd::vector<char, AZ::OSStdAllocator>> outMsg(&msgBuffer);
  299. AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&outMsg, *serializeContext, AZ::ObjectStream::ST_BINARY);
  300. objStream->WriteClass(&msg);
  301. if (!objStream->Finalize())
  302. {
  303. AZ_Assert(false, "ObjectStream failed to serialize outbound TmMsg!");
  304. }
  305. size_t customBlobSize = msg.GetCustomBlobSize();
  306. if (msg.GetCustomBlobSize() > 0)
  307. {
  308. outMsg.Write(customBlobSize, msg.GetCustomBlob().data());
  309. }
  310. AzNetworking::INetworkInterface* networkInterface =
  311. AZ::Interface<AzNetworking::INetworking>::Get()->RetrieveNetworkInterface(
  312. AZ::Name(m_entryRegistry[target.GetPersistentId()].m_name));
  313. auto connectionId = static_cast<AzNetworking::ConnectionId>(target.GetNetworkId());
  314. const uint8_t* outBuffer = reinterpret_cast<const uint8_t*>(msgBuffer.data());
  315. const size_t totalSize = msgBuffer.size();
  316. size_t outSize = totalSize;
  317. while (outSize > 0 && networkInterface != nullptr)
  318. {
  319. // Fragment the message into RemoteToolsMessageBuffer packet sized chunks and send
  320. size_t bufferSize = AZStd::min(outSize, aznumeric_cast<size_t>(RemoteToolsBufferSize));
  321. RemoteToolsPackets::RemoteToolsMessage tmPacket;
  322. tmPacket.SetPersistentId(target.GetPersistentId());
  323. tmPacket.SetSize(aznumeric_cast<uint32_t>(totalSize));
  324. RemoteToolsMessageBuffer encodingBuffer;
  325. encodingBuffer.CopyValues(outBuffer + (totalSize - outSize), bufferSize);
  326. tmPacket.SetMessageBuffer(encodingBuffer);
  327. if (!networkInterface->SendReliablePacket(connectionId, tmPacket))
  328. {
  329. AZ_Error("RemoteToolsSystemComponent", false, "SendReliablePacket failed with remaining bytes %zu of %zu.\n", outSize, totalSize);
  330. break;
  331. }
  332. outSize -= bufferSize;
  333. }
  334. }
  335. void RemoteToolsSystemComponent::OnMessageParsed(
  336. AzFramework::RemoteToolsMessage** ppMsg, void* classPtr, const AZ::Uuid& classId, const AZ::SerializeContext* sc)
  337. {
  338. // Check that classPtr is a RemoteToolsMessage
  339. AZ_Assert(*ppMsg == nullptr, "ppMsg is already set! are we deserializing multiple messages in one call?");
  340. *ppMsg = sc->Cast<AzFramework::RemoteToolsMessage*>(classPtr, classId);
  341. AZ_Assert(*ppMsg, "Failed to downcast msg pointer to a TmMsg. Is RTTI and reflection set up properly?");
  342. }
  343. bool RemoteToolsSystemComponent::HandleRequest(
  344. AzNetworking::IConnection* connection,
  345. [[maybe_unused]] const AzNetworking::IPacketHeader& packetHeader,
  346. const RemoteToolsPackets::RemoteToolsConnect& packet)
  347. {
  348. AZ::Crc32 key = packet.GetPersistentId();
  349. if (m_entryRegistry.contains(key))
  350. {
  351. const uint32_t persistentId = packet.GetPersistentId();
  352. AzFramework::RemoteToolsEndpointContainer::pair_iter_bool ret =
  353. m_entryRegistry[key].m_availableTargets.insert_key(persistentId);
  354. AzFramework::RemoteToolsEndpointInfo& ti = ret.first->second;
  355. ti.SetInfo(packet.GetDisplayName(), persistentId, static_cast<uint32_t>(connection->GetConnectionId()));
  356. m_entryRegistry[key].m_endpointJoinedEvent.Signal(ti);
  357. }
  358. return true;
  359. }
  360. bool RemoteToolsSystemComponent::HandleRequest(
  361. AzNetworking::IConnection* connection,
  362. [[maybe_unused]] const AzNetworking::IPacketHeader& packetHeader,
  363. [[maybe_unused]] const RemoteToolsPackets::RemoteToolsMessage& packet)
  364. {
  365. AZ::Crc32 key = packet.GetPersistentId();
  366. // Receive
  367. if (connection->GetConnectionRole() == AzNetworking::ConnectionRole::Acceptor
  368. && static_cast<uint32_t>(connection->GetConnectionId()) != m_entryRegistry[key].m_lastTarget.GetNetworkId())
  369. {
  370. // Listener should route traffic based on selected target
  371. return true;
  372. }
  373. if (!m_entryRegistry.contains(key))
  374. {
  375. m_entryRegistry[key] = RemoteToolsRegistryEntry();
  376. }
  377. // If we're a client, set the host to our desired target
  378. if (connection->GetConnectionRole() == AzNetworking::ConnectionRole::Connector)
  379. {
  380. if (GetEndpointInfo(key, packet.GetPersistentId()).GetPersistentId() == 0)
  381. {
  382. AzFramework::RemoteToolsEndpointContainer::pair_iter_bool ret =
  383. m_entryRegistry[key].m_availableTargets.insert_key(packet.GetPersistentId());
  384. AzFramework::RemoteToolsEndpointInfo& ti = ret.first->second;
  385. ti.SetInfo("Host", packet.GetPersistentId(), static_cast<uint32_t>(connection->GetConnectionId()));
  386. m_entryRegistry[key].m_endpointJoinedEvent.Signal(ti);
  387. }
  388. if (GetDesiredEndpoint(key).GetPersistentId() != packet.GetPersistentId())
  389. {
  390. SetDesiredEndpoint(key, packet.GetPersistentId());
  391. }
  392. }
  393. const uint32_t totalBufferSize = packet.GetSize();
  394. // Messages can be larger than the size of a packet so reserve a buffer for the total message size
  395. if (m_entryRegistry[key].m_tmpInboundBufferPos == 0)
  396. {
  397. m_entryRegistry[key].m_tmpInboundBuffer.reserve(totalBufferSize);
  398. }
  399. // Read as much data as the packet can include and append it to the buffer
  400. const uint32_t readSize = AZStd::min(totalBufferSize - m_entryRegistry[key].m_tmpInboundBufferPos, RemoteToolsBufferSize);
  401. memcpy(
  402. m_entryRegistry[key].m_tmpInboundBuffer.begin() + m_entryRegistry[key].m_tmpInboundBufferPos,
  403. packet.GetMessageBuffer().GetBuffer(), readSize);
  404. m_entryRegistry[key].m_tmpInboundBufferPos += readSize;
  405. if (m_entryRegistry[key].m_tmpInboundBufferPos == totalBufferSize)
  406. {
  407. AZ::SerializeContext* serializeContext;
  408. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  409. // Deserialize the complete buffer
  410. AZ::IO::MemoryStream msgBuffer(m_entryRegistry[key].m_tmpInboundBuffer.data(), totalBufferSize, totalBufferSize);
  411. AzFramework::RemoteToolsMessage* msg = nullptr;
  412. AZ::ObjectStream::ClassReadyCB readyCB(AZStd::bind(
  413. &RemoteToolsSystemComponent::OnMessageParsed, this, &msg, AZStd::placeholders::_1, AZStd::placeholders::_2,
  414. AZStd::placeholders::_3));
  415. AZ::ObjectStream::LoadBlocking(
  416. &msgBuffer, *serializeContext, readyCB,
  417. AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES));
  418. // Append to the inbox for handling
  419. if (msg)
  420. {
  421. if (msg->GetCustomBlobSize() > 0)
  422. {
  423. void* blob = azmalloc(msg->GetCustomBlobSize(), 1, AZ::OSAllocator);
  424. msgBuffer.Read(msg->GetCustomBlobSize(), blob);
  425. msg->AddCustomBlob(blob, msg->GetCustomBlobSize(), true);
  426. }
  427. msg->SetSenderTargetId(packet.GetPersistentId());
  428. m_inboxMutex.lock();
  429. m_inbox[msg->GetSenderTargetId()].push_back(msg);
  430. m_inboxMutex.unlock();
  431. m_entryRegistry[key].m_tmpInboundBuffer.clear();
  432. m_entryRegistry[key].m_tmpInboundBufferPos = 0;
  433. }
  434. }
  435. return true;
  436. }
  437. AzNetworking::ConnectResult RemoteToolsSystemComponent::ValidateConnect(
  438. [[maybe_unused]] const AzNetworking::IpAddress& remoteAddress,
  439. [[maybe_unused]] const AzNetworking::IPacketHeader& packetHeader,
  440. [[maybe_unused]] AzNetworking::ISerializer& serializer)
  441. {
  442. return AzNetworking::ConnectResult::Accepted;
  443. }
  444. void RemoteToolsSystemComponent::OnConnect([[maybe_unused]] AzNetworking::IConnection* connection)
  445. {
  446. // Invoked when a tooling connection is established, handshake logic is handled via ToolingConnect message
  447. ;
  448. }
  449. AzNetworking::PacketDispatchResult RemoteToolsSystemComponent::OnPacketReceived(
  450. AzNetworking::IConnection* connection,
  451. [[maybe_unused]] const AzNetworking::IPacketHeader& packetHeader,
  452. [[maybe_unused]] AzNetworking::ISerializer& serializer)
  453. {
  454. return RemoteToolsPackets::DispatchPacket(connection, packetHeader, serializer, *this);
  455. }
  456. void RemoteToolsSystemComponent::OnPacketLost(
  457. [[maybe_unused]] AzNetworking::IConnection* connection, [[maybe_unused]] AzNetworking::PacketId packetId)
  458. {
  459. ;
  460. }
  461. void RemoteToolsSystemComponent::OnDisconnect(
  462. [[maybe_unused]] AzNetworking::IConnection* connection,
  463. [[maybe_unused]] AzNetworking::DisconnectReason reason,
  464. [[maybe_unused]] AzNetworking::TerminationEndpoint endpoint)
  465. {
  466. // If our desired target has left the network, flag it and notify listeners
  467. if (reason != AzNetworking::DisconnectReason::ConnectionRejected)
  468. {
  469. for (auto registryIt = m_entryRegistry.begin(); registryIt != m_entryRegistry.end(); ++registryIt)
  470. {
  471. AzFramework::RemoteToolsEndpointContainer& container = registryIt->second.m_availableTargets;
  472. for (auto endpointIt = container.begin(); endpointIt != container.end(); ++endpointIt)
  473. {
  474. if (endpointIt->second.GetNetworkId() == static_cast<AZ::u32>(connection->GetConnectionId()))
  475. {
  476. AzFramework::RemoteToolsEndpointInfo ti = endpointIt->second;
  477. registryIt->second.m_endpointLeftEvent.Signal(ti);
  478. container.extract(endpointIt);
  479. break;
  480. }
  481. }
  482. }
  483. }
  484. if (m_joinThread && !m_joinThread->IsRunning())
  485. {
  486. m_joinThread->Join();
  487. m_joinThread->Start();
  488. }
  489. }
  490. } // namespace RemoteTools