3
0

EntityReplicationManager.cpp 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466
  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 <Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h>
  9. #include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
  10. #include <Multiplayer/IMultiplayer.h>
  11. #include <Multiplayer/Components/NetBindComponent.h>
  12. #include <Multiplayer/EntityDomains/IEntityDomain.h>
  13. #include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
  14. #include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
  15. #include <Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h>
  16. #include <Multiplayer/ReplicationWindows/IReplicationWindow.h>
  17. #include <AzNetworking/ConnectionLayer/IConnection.h>
  18. #include <AzNetworking/ConnectionLayer/IConnectionListener.h>
  19. #include <AzNetworking/PacketLayer/IPacketHeader.h>
  20. #include <AzCore/Component/ComponentApplicationBus.h>
  21. #include <AzCore/Console/IConsole.h>
  22. #include <AzCore/Console/ILogger.h>
  23. #include <AzCore/Debug/Profiler.h>
  24. #include <AzCore/Math/Transform.h>
  25. AZ_DECLARE_BUDGET(MULTIPLAYER);
  26. namespace Multiplayer
  27. {
  28. // Current max size for a UdpPacketHeader is 11 bytes
  29. constexpr uint32_t UdpPacketHeaderSerializeSize = 12;
  30. // Take out a few extra bytes for special headers, we currently only use 1 byte for the count of entity updates
  31. constexpr uint32_t ReplicationManagerPacketOverhead = 16;
  32. AZ_CVAR(bool, bg_replicationWindowImmediateAddRemove, true, nullptr, AZ::ConsoleFunctorFlags::Null, "Update replication windows immediately on visibility Add/Removes.");
  33. AZ_CVAR(AZ::TimeMs, sv_ReplicationWindowUpdateMs, AZ::TimeMs{ 300 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Rate for replication window updates.");
  34. EntityReplicationManager::EntityReplicationManager(AzNetworking::IConnection& connection, AzNetworking::IConnectionListener& connectionListener, Mode updateMode)
  35. : m_updateMode(updateMode)
  36. , m_connection(connection)
  37. , m_connectionListener(connectionListener)
  38. , m_orphanedEntityRpcs(*this)
  39. , m_clearRemovedReplicators([this]() { ClearRemovedReplicators(); }, AZ::Name("EntityReplicationManager::ClearRemovedReplicators"))
  40. , m_entityActivatedEventHandler([this](AZ::Entity* entity) { OnEntityActivated(entity); })
  41. , m_entityDeactivatedEventHandler([this](AZ::Entity* entity) { OnEntityDeactivated(entity); })
  42. , m_updateWindow([this]() { UpdateWindow(); }, AZ::Name("EntityReplicationManager::UpdateWindow"))
  43. , m_entityExitDomainEventHandler([this](const ConstNetworkEntityHandle& entityHandle) { OnEntityExitDomain(entityHandle); })
  44. , m_notifyEntityMigrationHandler([this](const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId) { OnPostEntityMigration(entityHandle, remoteHostId); })
  45. {
  46. // Set up our remote host identifier, by default we use the IP address of the remote host
  47. m_remoteHostId = connection.GetRemoteAddress();
  48. // Our max payload size is whatever is passed in, minus room for a udp packetheader
  49. m_maxPayloadSize = connection.GetConnectionMtu() - UdpPacketHeaderSerializeSize - ReplicationManagerPacketOverhead;
  50. // Schedule ClearRemovedReplicators()
  51. m_clearRemovedReplicators.Enqueue(AZ::Time::ZeroTimeMs, true);
  52. AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RegisterEntityActivatedEventHandler(m_entityActivatedEventHandler);
  53. AZ::Interface<AZ::ComponentApplicationRequests>::Get()->RegisterEntityDeactivatedEventHandler(m_entityDeactivatedEventHandler);
  54. // Start window update events
  55. m_updateWindow.Enqueue(sv_ReplicationWindowUpdateMs, true);
  56. INetworkEntityManager* networkEntityManager = GetNetworkEntityManager();
  57. if (networkEntityManager != nullptr)
  58. {
  59. networkEntityManager->AddEntityExitDomainHandler(m_entityExitDomainEventHandler);
  60. }
  61. if (m_updateMode == Mode::LocalServerToRemoteServer)
  62. {
  63. GetMultiplayer()->AddNotifyEntityMigrationEventHandler(m_notifyEntityMigrationHandler);
  64. }
  65. }
  66. const HostId& EntityReplicationManager::GetRemoteHostId() const
  67. {
  68. return m_remoteHostId;
  69. }
  70. void EntityReplicationManager::ActivatePendingEntities()
  71. {
  72. AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: ActivatePendingEntities");
  73. AZStd::vector<NetEntityId> notReadyEntities;
  74. const AZ::TimeMs endTimeMs = AZ::GetElapsedTimeMs() + m_entityActivationTimeSliceMs;
  75. while (!m_entitiesPendingActivation.empty())
  76. {
  77. NetEntityId entityId = m_entitiesPendingActivation.front();
  78. m_entitiesPendingActivation.pop_front();
  79. EntityReplicator* entityReplicator = GetEntityReplicator(entityId);
  80. if (entityReplicator && !entityReplicator->IsMarkedForRemoval())
  81. {
  82. if (entityReplicator->IsReadyToActivate())
  83. {
  84. entityReplicator->ActivateNetworkEntity();
  85. }
  86. else
  87. {
  88. notReadyEntities.push_back(entityId);
  89. }
  90. }
  91. if (m_entityActivationTimeSliceMs > AZ::Time::ZeroTimeMs && AZ::GetElapsedTimeMs() > endTimeMs)
  92. {
  93. // If we go over our timeslice, break out the loop
  94. break;
  95. }
  96. }
  97. for (NetEntityId netEntityId : notReadyEntities)
  98. {
  99. m_entitiesPendingActivation.push_back(netEntityId);
  100. }
  101. }
  102. // Get the list of entities to update/delete, create and send update/delete messages, send RPCs, and send entity resets.
  103. void EntityReplicationManager::SendUpdates()
  104. {
  105. m_frameTimeMs = AZ::GetElapsedTimeMs();
  106. {
  107. EntityReplicatorList toSendList = GenerateEntityUpdateList();
  108. AZLOG
  109. (
  110. NET_ReplicationInfo,
  111. "Sending %zd updates from %s to %s",
  112. toSendList.size(),
  113. GetNetworkEntityManager()->GetHostId().GetString().c_str(),
  114. GetRemoteHostId().GetString().c_str()
  115. );
  116. {
  117. AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: SendUpdates - PrepareToGenerateUpdatePacket");
  118. // Prep a replication record for send, at this point, everything needs to be sent
  119. for (EntityReplicator* replicator : toSendList)
  120. {
  121. replicator->PrepareToGenerateUpdatePacket();
  122. }
  123. }
  124. {
  125. AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: SendUpdates - SendEntityUpdateMessages");
  126. // While our to send list is not empty, build up another packet to send
  127. do
  128. {
  129. SendEntityUpdateMessages(toSendList);
  130. } while (!toSendList.empty());
  131. }
  132. }
  133. SendEntityRpcs(m_deferredRpcMessagesReliable, true);
  134. SendEntityRpcs(m_deferredRpcMessagesUnreliable, false);
  135. m_orphanedEntityRpcs.Update();
  136. SendEntityResets();
  137. AZLOG
  138. (
  139. NET_ReplicationInfo,
  140. "Sending from %s to %s, replicator count %u orphan count %u deferred reliable count %u deferred unreliable count %u",
  141. GetNetworkEntityManager()->GetHostId().GetString().c_str(),
  142. GetRemoteHostId().GetString().c_str(),
  143. aznumeric_cast<uint32_t>(m_entityReplicatorMap.size()),
  144. aznumeric_cast<uint32_t>(m_orphanedEntityRpcs.Size()),
  145. aznumeric_cast<uint32_t>(m_deferredRpcMessagesReliable.size()),
  146. aznumeric_cast<uint32_t>(m_deferredRpcMessagesUnreliable.size())
  147. );
  148. }
  149. EntityReplicationManager::EntityReplicatorList EntityReplicationManager::GenerateEntityUpdateList()
  150. {
  151. if (m_replicationWindow == nullptr)
  152. {
  153. return EntityReplicatorList();
  154. }
  155. AZ_PROFILE_SCOPE(MULTIPLAYER, "EntityReplicationManager: GenerateEntityUpdateList");
  156. // Generate a list of all our entities that need updates
  157. EntityReplicatorList toSendList;
  158. uint32_t proxySendCount = 0;
  159. for (auto iter = m_replicatorsPendingSend.begin(); iter != m_replicatorsPendingSend.end();)
  160. {
  161. bool clearPendingSend = true;
  162. if (EntityReplicator* replicator = GetEntityReplicator(*iter))
  163. {
  164. NetEntityId entityId = replicator->GetEntityHandle().GetNetEntityId();
  165. if (replicator->IsReadyToPublish())
  166. {
  167. // don't have too many replicators pending creation outstanding at a time
  168. bool canSend = true;
  169. if (!replicator->IsRemoteReplicatorEstablished())
  170. {
  171. // If we have our maximum set of entities pending creation, and this entity isn't in that set, then skip it
  172. if ((m_remoteEntitiesPendingCreation.size() >= m_maxRemoteEntitiesPendingCreationCount) && (m_remoteEntitiesPendingCreation.find(entityId) == m_remoteEntitiesPendingCreation.end()))
  173. {
  174. canSend = false; // don't send this
  175. clearPendingSend = false; // there might be outstanding data here, but we won't check, so we shouldn't clear it
  176. }
  177. }
  178. else
  179. {
  180. m_remoteEntitiesPendingCreation.erase(*iter);
  181. }
  182. if (canSend && replicator->HasChangesToPublish())
  183. {
  184. clearPendingSend = false;
  185. if (!replicator->IsRemoteReplicatorEstablished())
  186. {
  187. m_remoteEntitiesPendingCreation.insert(entityId);
  188. }
  189. if (replicator->GetRemoteNetworkRole() == NetEntityRole::Autonomous ||
  190. replicator->GetBoundLocalNetworkRole() == NetEntityRole::Autonomous)
  191. {
  192. toSendList.push_back(replicator);
  193. }
  194. else if (proxySendCount < m_replicationWindow->GetMaxProxyEntityReplicatorSendCount())
  195. {
  196. toSendList.push_back(replicator);
  197. ++proxySendCount;
  198. }
  199. }
  200. }
  201. }
  202. if (clearPendingSend)
  203. {
  204. m_remoteEntitiesPendingCreation.erase(*iter);
  205. iter = m_replicatorsPendingSend.erase(iter);
  206. }
  207. else
  208. {
  209. ++iter;
  210. }
  211. }
  212. return toSendList;
  213. }
  214. void EntityReplicationManager::SendEntityUpdateMessages(EntityReplicatorList& replicatorList)
  215. {
  216. uint32_t pendingPacketSize = 0;
  217. EntityReplicatorList replicatorUpdatedList;
  218. NetworkEntityUpdateVector entityUpdates;
  219. // Serialize everything
  220. while (!replicatorList.empty())
  221. {
  222. EntityReplicator* replicator = replicatorList.front();
  223. NetworkEntityUpdateMessage updateMessage(replicator->GenerateUpdatePacket());
  224. const uint32_t nextMessageSize = updateMessage.GetEstimatedSerializeSize();
  225. // Check if we are over our limits
  226. const bool payloadFull = (pendingPacketSize + nextMessageSize > m_maxPayloadSize);
  227. const bool capacityReached = (entityUpdates.size() >= entityUpdates.capacity());
  228. const bool largeEntityDetected = (payloadFull && replicatorUpdatedList.empty());
  229. if (capacityReached || (payloadFull && !largeEntityDetected))
  230. {
  231. break;
  232. }
  233. pendingPacketSize += nextMessageSize;
  234. entityUpdates.push_back(updateMessage);
  235. replicatorUpdatedList.push_back(replicator);
  236. replicatorList.pop_front();
  237. if (largeEntityDetected)
  238. {
  239. AZLOG_WARN
  240. (
  241. "Serializing extremely large entity (%llu) - MaxPayload: %d NeededSize %d",
  242. aznumeric_cast<AZ::u64>(replicator->GetEntityHandle().GetNetEntityId()),
  243. m_maxPayloadSize,
  244. nextMessageSize
  245. );
  246. break;
  247. }
  248. }
  249. if (m_replicationWindow)
  250. {
  251. const AzNetworking::PacketId sentId = m_replicationWindow->SendEntityUpdateMessages(entityUpdates);
  252. // Update the sent things with the packet id
  253. for (EntityReplicator* replicator : replicatorUpdatedList)
  254. {
  255. replicator->RecordSentPacketId(sentId);
  256. }
  257. }
  258. else
  259. {
  260. AZ_Assert(false, "Failed to send entity update message, replication window does not exist");
  261. }
  262. }
  263. void EntityReplicationManager::SendEntityRpcs(RpcMessages& rpcMessages, bool reliable)
  264. {
  265. while (!rpcMessages.empty())
  266. {
  267. NetworkEntityRpcVector entityRpcs;
  268. uint32_t pendingPacketSize = 0;
  269. while (!rpcMessages.empty())
  270. {
  271. NetworkEntityRpcMessage& message = rpcMessages.front();
  272. const uint32_t nextRpcSize = message.GetEstimatedSerializeSize();
  273. if ((pendingPacketSize + nextRpcSize) > m_maxPayloadSize)
  274. {
  275. // We're over our limit, break and send an Rpc packet
  276. if (entityRpcs.size() == 0)
  277. {
  278. AZLOG(NET_Replicator, "Encountered an RPC that is above our MTU, message will be segmented (object size %u, max allowed size %u)", nextRpcSize, m_maxPayloadSize);
  279. entityRpcs.push_back(message);
  280. rpcMessages.pop_front();
  281. }
  282. break;
  283. }
  284. pendingPacketSize += nextRpcSize;
  285. if (entityRpcs.full())
  286. {
  287. // Packet was full, send what we've accumulated so far
  288. AZLOG(NET_Replicator, "We've hit our RPC message limit (RPC count %u, packet size %u)", aznumeric_cast<uint32_t>(entityRpcs.size()), pendingPacketSize);
  289. break;
  290. }
  291. entityRpcs.push_back(message);
  292. rpcMessages.pop_front();
  293. }
  294. if (m_replicationWindow)
  295. {
  296. m_replicationWindow->SendEntityRpcs(entityRpcs, reliable);
  297. }
  298. else
  299. {
  300. AZ_Assert(false, "Failed to send entity rpc, replication window does not exist");
  301. }
  302. }
  303. }
  304. void EntityReplicationManager::SendEntityResets()
  305. {
  306. if (m_replicationWindow)
  307. {
  308. m_replicationWindow->SendEntityResets(m_replicatorsPendingReset);
  309. }
  310. m_replicatorsPendingReset.clear();
  311. }
  312. void EntityReplicationManager::Clear(bool forMigration)
  313. {
  314. if (forMigration)
  315. {
  316. for (auto& replicatorPair : m_entityReplicatorMap)
  317. {
  318. if (!replicatorPair.second->IsMarkedForRemoval())
  319. {
  320. replicatorPair.second->MarkForRemoval();
  321. }
  322. }
  323. }
  324. else
  325. {
  326. m_replicatorsPendingRemoval.clear();
  327. m_replicatorsPendingSend.clear();
  328. m_replicatorsPendingReset.clear();
  329. }
  330. m_entityReplicatorMap.clear();
  331. }
  332. bool EntityReplicationManager::SetEntityRebasing(NetworkEntityHandle& entityHandle)
  333. {
  334. EntityReplicator* entityReplicator = GetEntityReplicator(entityHandle.GetNetEntityId());
  335. if (entityReplicator)
  336. {
  337. entityReplicator->SetRebasing();
  338. return true;
  339. }
  340. return false;
  341. }
  342. EntityReplicator* EntityReplicationManager::AddEntityReplicator(const ConstNetworkEntityHandle& entityHandle, NetEntityRole remoteNetworkRole)
  343. {
  344. EntityReplicator* entityReplicator(nullptr);
  345. if (entityHandle.GetEntity())
  346. {
  347. entityReplicator = GetEntityReplicator(entityHandle);
  348. if (entityReplicator)
  349. {
  350. // Check if we changed our remote role - this can happen during server entity migration.
  351. // Retain our replicator after migration until we are sure the other side has received all the packets (and we haven't had to do resends).
  352. // At this point, the remote host should inform us we've migrated prior to the timeout and cleanup of the old replicator
  353. const bool changedRemoteRole = (remoteNetworkRole != entityReplicator->GetRemoteNetworkRole());
  354. // Check if we've changed our bound local role - this can occur when we gain Autonomous or lose Autonomous on a client
  355. bool changedLocalRole(false);
  356. NetBindComponent* netBindComponent = entityReplicator->GetEntityHandle().GetNetBindComponent();
  357. if (netBindComponent != nullptr)
  358. {
  359. changedLocalRole = (netBindComponent->GetNetEntityRole() != entityReplicator->GetBoundLocalNetworkRole());
  360. }
  361. if (changedRemoteRole || changedLocalRole)
  362. {
  363. const AZ::u64 intEntityId = static_cast<AZ::u64>(netBindComponent->GetNetEntityId());
  364. const char* entityName = entityReplicator->GetEntityHandle().GetEntity()->GetName().c_str();
  365. if (changedLocalRole)
  366. {
  367. const char* oldRoleString = GetEnumString(entityReplicator->GetRemoteNetworkRole());
  368. const char* newRoleString = GetEnumString(remoteNetworkRole);
  369. AZLOG(NET_ReplicatorRoles, "Replicator %s(%llu) changed local role, old role = %s, new role = %s", entityName, intEntityId, oldRoleString, newRoleString);
  370. }
  371. if (changedRemoteRole)
  372. {
  373. const char* oldRoleString = GetEnumString(entityReplicator->GetBoundLocalNetworkRole());
  374. const char* newRoleString = GetEnumString(netBindComponent->GetNetEntityRole());
  375. AZLOG(NET_ReplicatorRoles, "Replicator %s(%llu) changed remote role, old role = %s, new role = %s", entityName, intEntityId, oldRoleString, newRoleString);
  376. }
  377. // If we changed roles, we need to reset everything
  378. if (!entityReplicator->IsMarkedForRemoval())
  379. {
  380. // Clear our ownership
  381. entityReplicator->MarkForRemoval();
  382. }
  383. // Reset our replicator, we are establishing a new one
  384. entityReplicator->Reset(remoteNetworkRole);
  385. }
  386. // Else case is when an entity had left relevancy and come back (but it was still pending a removal)
  387. entityReplicator->Initialize(entityHandle);
  388. AZLOG
  389. (
  390. NET_RepDeletes,
  391. "Reinited replicator for netEntityId %llu from remote host %s role %d",
  392. static_cast<AZ::u64>(entityHandle.GetNetEntityId()),
  393. GetRemoteHostId().GetString().c_str(),
  394. aznumeric_cast<int32_t>(remoteNetworkRole)
  395. );
  396. }
  397. else
  398. {
  399. // Haven't seen him before, let's add him
  400. AZ_Assert(entityHandle.GetNetBindComponent(), "No NetBindComponent");
  401. AZStd::unique_ptr<EntityReplicator> newEntityReplicator = AZStd::make_unique<EntityReplicator>(*this, &m_connection, remoteNetworkRole, entityHandle);
  402. newEntityReplicator->Initialize(entityHandle);
  403. entityReplicator = newEntityReplicator.get();
  404. m_entityReplicatorMap.emplace(entityHandle.GetNetEntityId(), AZStd::move(newEntityReplicator));
  405. AZLOG
  406. (
  407. NET_RepDeletes,
  408. "Added replicator for netEntityId %llu from remote host %s role %d",
  409. static_cast<AZ::u64>(entityHandle.GetNetEntityId()),
  410. GetRemoteHostId().GetString().c_str(),
  411. aznumeric_cast<int32_t>(remoteNetworkRole)
  412. );
  413. }
  414. }
  415. else
  416. {
  417. AZLOG_ERROR("Failed to add entity replicator, entity does not exist, netEntityId %llu", static_cast<AZ::u64>(entityHandle.GetNetEntityId()));
  418. AZ_Assert(false, "Failed to add entity replicator, entity does not exist");
  419. }
  420. return entityReplicator;
  421. }
  422. EntityReplicator* EntityReplicationManager::GetEntityReplicator(const ConstNetworkEntityHandle& entityHandle)
  423. {
  424. return GetEntityReplicator(entityHandle.GetNetEntityId());
  425. }
  426. void EntityReplicationManager::GetEntityReplicatorIdList(AZStd::list<NetEntityId>& outList)
  427. {
  428. for (const auto& pair : m_entityReplicatorMap)
  429. {
  430. outList.push_back(pair.second->GetEntityHandle().GetNetEntityId());
  431. }
  432. }
  433. uint32_t EntityReplicationManager::GetEntityReplicatorCount(NetEntityRole localNetworkRole)
  434. {
  435. uint32_t count = 0;
  436. for (auto &entityReplicatorPair : m_entityReplicatorMap)
  437. {
  438. if (entityReplicatorPair.second->GetBoundLocalNetworkRole() == localNetworkRole)
  439. {
  440. ++count;
  441. }
  442. }
  443. return count;
  444. }
  445. void EntityReplicationManager::AddDeferredRpcMessage(NetworkEntityRpcMessage& message)
  446. {
  447. if (message.GetReliability() == ReliabilityType::Reliable)
  448. {
  449. m_deferredRpcMessagesReliable.emplace_back(message);
  450. }
  451. else
  452. {
  453. m_deferredRpcMessagesUnreliable.emplace_back(message);
  454. }
  455. }
  456. // @nt: TODO - delete once dropped RPC problem fixed
  457. void EntityReplicationManager::AddAutonomousEntityReplicatorCreatedHandler(AZ::Event<NetEntityId>::Handler& handler)
  458. {
  459. handler.Connect(m_autonomousEntityReplicatorCreated);
  460. }
  461. void EntityReplicationManager::AddSendMigrateEntityEventHandler(SendMigrateEntityEvent::Handler& handler)
  462. {
  463. handler.Connect(m_sendMigrateEntityEvent);
  464. }
  465. const EntityReplicator* EntityReplicationManager::GetEntityReplicator(NetEntityId netEntityId) const
  466. {
  467. auto it = m_entityReplicatorMap.find(netEntityId);
  468. if (it != m_entityReplicatorMap.end())
  469. {
  470. return it->second.get();
  471. }
  472. else
  473. {
  474. return nullptr;
  475. }
  476. }
  477. EntityReplicator* EntityReplicationManager::GetEntityReplicator(NetEntityId netEntityId)
  478. {
  479. const EntityReplicationManager* constThis = this;
  480. return const_cast<EntityReplicator*>(constThis->GetEntityReplicator(netEntityId));
  481. }
  482. bool EntityReplicationManager::HandleEntityDeleteMessage
  483. (
  484. EntityReplicator* entityReplicator,
  485. [[maybe_unused]] const AzNetworking::IPacketHeader& packetHeader,
  486. const NetworkEntityUpdateMessage& updateMessage
  487. )
  488. {
  489. bool shouldDeleteEntity = false;
  490. // Handle Replicator cleanup
  491. if (entityReplicator)
  492. {
  493. if (entityReplicator->IsMarkedForRemoval())
  494. {
  495. [[maybe_unused]] const AZ::Entity* entity = entityReplicator->GetEntityHandle().GetEntity();
  496. AZLOG_WARN("Entity replicator for id %llu (%s) is already marked for deletion on remote host %s",
  497. static_cast<AZ::u64>(updateMessage.GetEntityId()),
  498. entity ? entity->GetName().c_str() : "<Entity Name Unknown>",
  499. GetRemoteHostId().GetString().c_str());
  500. return true;
  501. }
  502. else if (entityReplicator->OwnsReplicatorLifetime())
  503. {
  504. // This can occur if we migrate entities quickly - if this is a replicator from C to A, A migrates to B, B then migrates to C, and A's delete replicator has not arrived at C
  505. AZLOG(NET_RepDeletes, "Got a replicator delete message for a replicator we own id %llu remote host %s", static_cast<AZ::u64>(updateMessage.GetEntityId()), GetRemoteHostId().GetString().c_str());
  506. }
  507. else
  508. {
  509. shouldDeleteEntity = true;
  510. entityReplicator->MarkForRemoval();
  511. AZLOG(NET_RepDeletes, "Deleting replicator for entity id %llu remote host %s", static_cast<AZ::u64>(updateMessage.GetEntityId()), GetRemoteHostId().GetString().c_str());
  512. }
  513. }
  514. else
  515. {
  516. // Replicators are cleared on the server via ScheduledEvent. It's possible for redundant delete messages to be sent before the event fires.
  517. AZLOG(
  518. NET_RepDeletes,
  519. "Replicator for id %llu is null on remote host %s. It likely has already been deleted.",
  520. static_cast<AZ::u64>(updateMessage.GetEntityId()),
  521. GetRemoteHostId().GetString().c_str());
  522. return true;
  523. }
  524. // Handle entity cleanup
  525. if (shouldDeleteEntity)
  526. {
  527. ConstNetworkEntityHandle entity = GetNetworkEntityManager()->GetEntity(updateMessage.GetEntityId());
  528. if (entity)
  529. {
  530. if (updateMessage.GetWasMigrated())
  531. {
  532. AZLOG(NET_RepDeletes, "Leaving id %llu using timeout remote host %s", static_cast<AZ::u64>(entity.GetNetEntityId()), GetRemoteHostId().GetString().c_str());
  533. }
  534. else
  535. {
  536. AZLOG(NET_RepDeletes, "Deleting entity id %llu remote host %s", static_cast<AZ::u64>(entity.GetNetEntityId()), GetRemoteHostId().GetString().c_str());
  537. GetNetworkEntityManager()->MarkForRemoval(entity);
  538. }
  539. }
  540. else
  541. {
  542. AZLOG(NET_RepDeletes, "Trying to delete entity id %llu remote host %s, but it has been removed", static_cast<AZ::u64>(entity.GetNetEntityId()), GetRemoteHostId().GetString().c_str());
  543. }
  544. }
  545. return shouldDeleteEntity;
  546. }
  547. bool EntityReplicationManager::HandlePropertyChangeMessage
  548. (
  549. AzNetworking::IConnection* invokingConnection,
  550. EntityReplicator* entityReplicator,
  551. AzNetworking::PacketId packetId,
  552. NetEntityId netEntityId,
  553. NetEntityRole localNetworkRole,
  554. AzNetworking::ISerializer& serializer,
  555. const PrefabEntityId& prefabEntityId,
  556. [[maybe_unused]] bool isDeleted
  557. )
  558. {
  559. ConstNetworkEntityHandle replicatorEntity = GetNetworkEntityManager()->GetEntity(netEntityId);
  560. const bool createEntity = (replicatorEntity == nullptr);
  561. const bool notifySerializationChanges = (replicatorEntity && replicatorEntity.GetEntity()->GetState() == AZ::Entity::State::Active);
  562. // Create an entity if we don't have one and we're not immediately deleting it.
  563. if (createEntity)
  564. {
  565. // If the entity doesn't exist yet and we're about to delete it, don't create the entity only to apply property changes
  566. // and delete it. Just return immediately and skip both creation and deletion.
  567. if (isDeleted)
  568. {
  569. AZLOG(
  570. NET_RepDeletes,
  571. "Skip creation of entity id %llu because it is also being deleted in this message.",
  572. static_cast<AZ::u64>(netEntityId));
  573. return true;
  574. }
  575. INetworkEntityManager::EntityList entityList = GetNetworkEntityManager()->CreateEntitiesImmediate(
  576. prefabEntityId, netEntityId, localNetworkRole, AutoActivate::DoNotActivate, AZ::Transform::Identity());
  577. if (entityList.size() == 1)
  578. {
  579. replicatorEntity = entityList[0];
  580. }
  581. else
  582. {
  583. AZ_Assert(false, "There should be exactly one created entity out of prefab %s, index %d. Got: %d",
  584. prefabEntityId.m_prefabName.GetCStr(), prefabEntityId.m_entityOffset, entityList.size());
  585. return false;
  586. }
  587. }
  588. NetBindComponent* netBindComponent = replicatorEntity.GetNetBindComponent();
  589. AZ_Assert(netBindComponent != nullptr, "No NetBindComponent");
  590. if (netBindComponent->GetOwningConnectionId() != invokingConnection->GetConnectionId())
  591. {
  592. // Always ensure our owning connectionId is correct for correct rewind behaviour
  593. netBindComponent->SetOwningConnectionId(invokingConnection->GetConnectionId());
  594. }
  595. const bool changeNetworkRole = (netBindComponent->GetNetEntityRole() != localNetworkRole);
  596. if (changeNetworkRole)
  597. {
  598. AZ_Assert(localNetworkRole != NetEntityRole::Authority, "UpdateMessage trying to set local role to Authority, this should only happen via migration");
  599. AZLOG_INFO
  600. (
  601. "EntityReplicationManager: Changing network role on entity %s(%llu), old role %s new role %s",
  602. replicatorEntity.GetEntity()->GetName().c_str(),
  603. aznumeric_cast<AZ::u64>(netEntityId),
  604. GetEnumString(netBindComponent->GetNetEntityRole()),
  605. GetEnumString(localNetworkRole)
  606. );
  607. if (NetworkRoleHasController(localNetworkRole))
  608. {
  609. // We defer activation until after the data has been deserialized into our entity.
  610. // The packet may contain additional data that might be required for a component's proper activation.
  611. netBindComponent->ConstructControllers();
  612. }
  613. else
  614. {
  615. // We have lost control, deactivate and destroy the controllers
  616. netBindComponent->DeactivateControllers(EntityIsMigrating::False);
  617. netBindComponent->DestructControllers();
  618. }
  619. }
  620. const bool createReplicator = (entityReplicator == nullptr)
  621. || entityReplicator->IsMarkedForRemoval()
  622. || entityReplicator->GetBoundLocalNetworkRole() != localNetworkRole;
  623. if (createReplicator)
  624. {
  625. // Make sure this entity that we're getting a packet on hasn't been marked for removal by someone else
  626. // This can occur on a 3 server case where an entity has migrated from A->B and we are on server C, observing the migration.
  627. // A will tell us to set a timer to delete that entity (since it no longer owns it, and has been handed off), and B will tell us to create it.
  628. // This covers an edge case where the timer has popped, but the entity is pending removal when we are told by B to create the entity.
  629. GetNetworkEntityManager()->ClearEntityFromRemovalList(replicatorEntity);
  630. entityReplicator = AddEntityReplicator(replicatorEntity, NetEntityRole::Authority);
  631. //AZLOG(NET_RepUpdate, "EntityReplicationManager: Created from update entity id %u for type %s role %d", netEntityId, prefabEntityId.GetString(), localNetworkRole);
  632. }
  633. // @nt: TODO - delete once dropped RPC problem fixed
  634. // This code is temporary to work around to the problem that RPC messages are silently lost during migration
  635. // Once this problem is solved, we can remove this code and associated event
  636. if (createReplicator && localNetworkRole == NetEntityRole::Autonomous)
  637. {
  638. m_autonomousEntityReplicatorCreated.Signal(netEntityId);
  639. }
  640. //AZLOG(NET_RepUpdate, "EntityReplicationManager: Received PropertyChangeMessage message for entity id %u for type %s role %d", netEntityId, prefabEntityId.GetString(), localNetworkRole);
  641. bool didSucceed = entityReplicator->HandlePropertyChangeMessage(packetId, &serializer, notifySerializationChanges);
  642. if (changeNetworkRole)
  643. {
  644. if (NetworkRoleHasController(localNetworkRole))
  645. {
  646. // Activate the controllers since the entity had previously been activated
  647. netBindComponent->ActivateControllers(EntityIsMigrating::False);
  648. }
  649. }
  650. if (createEntity)
  651. {
  652. // We defer activation until after the packet has been deserialized (this will also implicitly activate controllers if they exist)
  653. // The actual entity activate could be deferred further, in cases where entity dependencies are not met
  654. m_entitiesPendingActivation.push_back(netEntityId);
  655. }
  656. if (createReplicator && !createEntity)
  657. {
  658. // See if we have any outstanding RPCs that came in prior to creating the entity
  659. didSucceed &= m_orphanedEntityRpcs.DispatchOrphanedRpcs(*entityReplicator);
  660. }
  661. return didSucceed;
  662. }
  663. EntityReplicationManager::UpdateValidationResult EntityReplicationManager::ValidateUpdate
  664. (
  665. const NetworkEntityUpdateMessage& updateMessage,
  666. AzNetworking::PacketId packetId,
  667. EntityReplicator* entityReplicator
  668. )
  669. {
  670. UpdateValidationResult result = UpdateValidationResult::HandleMessage;
  671. switch (m_updateMode)
  672. {
  673. case Mode::LocalServerToRemoteClient:
  674. {
  675. // Don't trust the client by default
  676. result = UpdateValidationResult::DropMessageAndDisconnect;
  677. // Clients sending data must have a replicator and be sending in the correct mode, further, they must have a replicator and can never delete a replicator
  678. if (updateMessage.GetNetworkRole() == NetEntityRole::Authority && entityReplicator && !updateMessage.GetIsDelete())
  679. {
  680. // Make sure we our replicator is in the expected configuration
  681. if ((entityReplicator->GetRemoteNetworkRole() == NetEntityRole::Autonomous) && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Authority))
  682. {
  683. // If we're marked for removal, just drop the message - migration message is likely in flight
  684. if (entityReplicator->IsMarkedForRemoval())
  685. {
  686. result = UpdateValidationResult::DropMessage;
  687. }
  688. else
  689. {
  690. // We can process this
  691. result = UpdateValidationResult::HandleMessage;
  692. }
  693. } // If we've migrated the entity away from the server, but we get this late, just drop it
  694. else if ((entityReplicator->GetRemoteNetworkRole() == NetEntityRole::Client) && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Server))
  695. {
  696. result = UpdateValidationResult::DropMessage;
  697. }
  698. }
  699. if (result == UpdateValidationResult::DropMessageAndDisconnect)
  700. {
  701. AZLOG_WARN
  702. (
  703. "Dropping Packet and LocalServerToRemoteClient connection, unexpected packet "
  704. "LocalShard=%s EntityId=%llu RemoteNetworkRole=%u BoundLocalNetworkRole=%u ActualNetworkRole=%u IsMarkedForRemoval=%s",
  705. GetNetworkEntityManager()->GetHostId().GetString().c_str(),
  706. aznumeric_cast<AZ::u64>(entityReplicator->GetEntityHandle().GetNetEntityId()),
  707. aznumeric_cast<uint32_t>(entityReplicator->GetRemoteNetworkRole()),
  708. aznumeric_cast<uint32_t>(entityReplicator->GetBoundLocalNetworkRole()),
  709. aznumeric_cast<uint32_t>(entityReplicator->GetNetBindComponent()->GetNetEntityRole()),
  710. entityReplicator->IsMarkedForRemoval() ? "true" : "false"
  711. );
  712. }
  713. }
  714. break;
  715. case Mode::LocalServerToRemoteServer:
  716. {
  717. AZ_Assert(updateMessage.GetNetworkRole() == NetEntityRole::Server || updateMessage.GetIsDelete(), "Unexpected update type coming from peer server");
  718. // Trust messages from a peer server by default
  719. result = UpdateValidationResult::HandleMessage;
  720. // If we have a replicator, make sure we're in the correct state
  721. if (entityReplicator)
  722. {
  723. if (!entityReplicator->IsMarkedForRemoval() && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Authority))
  724. {
  725. // Likely an old message from a previous owner trying to delete the replicator it had, while we've received ownership
  726. // This can happen when Shard A migrates an entity to Shard B, then shard B migrates the entity to Shard C, and Shard A tries to delete a replicator it had to Shard C (which has already made a new replicator for Shard A)
  727. result = UpdateValidationResult::DropMessage;
  728. }
  729. else if (entityReplicator->GetRemoteNetworkRole() != NetEntityRole::Authority) // We expect the remote role to be NetEntityRole::Authority
  730. {
  731. // This entity has migrated previously, and we haven't heard back that the remove was successful, so we can accept the message
  732. AZ_Assert(entityReplicator->IsMarkedForRemoval() && entityReplicator->GetRemoteNetworkRole() == NetEntityRole::Server, "Unexpected server message is not Authority or Server");
  733. }
  734. }
  735. }
  736. break;
  737. case Mode::LocalClientToRemoteServer:
  738. {
  739. // By default, trust everything from the server
  740. result = UpdateValidationResult::HandleMessage;
  741. // For delete messages, we can potentially skip processing them if the entity hasn't been created or has already
  742. // been deleted.
  743. if (updateMessage.GetIsDelete())
  744. {
  745. if (!entityReplicator)
  746. {
  747. // If the entity hasn't been created (or has already been deleted), drop the delete message.
  748. // We won't create or delete the entity. If we tried to handle the message, we would end up both
  749. // creating and deleting the entity in the same frame from this message. The entity would never even
  750. // have a chance to activate, so there's no real value in processing it.
  751. result = UpdateValidationResult::DropMessage;
  752. AZLOG(
  753. NET_RepDeletes,
  754. "Dropping message that would both add and delete entity id %llu from remote host %s",
  755. aznumeric_cast<AZ::u64>(updateMessage.GetEntityId()),
  756. GetRemoteHostId().GetString().c_str());
  757. }
  758. else if (entityReplicator && entityReplicator->IsMarkedForRemoval())
  759. {
  760. // If the entity is already marked for deletion, we can drop the redundant delete message.
  761. result = UpdateValidationResult::DropMessage;
  762. AZLOG(
  763. NET_RepDeletes,
  764. "Dropping redundant client message to delete entity id %llu from remote host %s",
  765. aznumeric_cast<AZ::u64>(updateMessage.GetEntityId()),
  766. GetRemoteHostId().GetString().c_str());
  767. }
  768. }
  769. }
  770. break;
  771. }
  772. // Make sure if everything else looks good, that we don't have an old out of order message
  773. if (result == UpdateValidationResult::HandleMessage && entityReplicator && !entityReplicator->IsMarkedForRemoval())
  774. {
  775. if (!entityReplicator->IsPacketIdValid(packetId))
  776. {
  777. // Got an old message
  778. result = UpdateValidationResult::DropMessage;
  779. if (updateMessage.GetIsDelete())
  780. {
  781. AZLOG(NET_RepDeletes, "EntityReplicationManager: Received old DeleteProxy message for entity id %llu, sequence %d latest sequence %d from remote host %s",
  782. aznumeric_cast<AZ::u64>(updateMessage.GetEntityId()),
  783. aznumeric_cast<uint32_t>(packetId),
  784. aznumeric_cast<uint32_t>(entityReplicator->GetLastReceivedPacketId()),
  785. GetRemoteHostId().GetString().c_str());
  786. }
  787. else
  788. {
  789. AZLOG(NET_RepUpdate, "EntityReplicationManager: Received old PropertyChangeMessage message for entity id %llu, sequence %d latest sequence %d from remote host %s",
  790. aznumeric_cast<AZ::u64>(updateMessage.GetEntityId()),
  791. aznumeric_cast<uint32_t>(packetId),
  792. aznumeric_cast<uint32_t>(entityReplicator->GetLastReceivedPacketId()),
  793. GetRemoteHostId().GetString().c_str());
  794. }
  795. }
  796. }
  797. return result;
  798. }
  799. bool EntityReplicationManager::HandleEntityUpdateMessage
  800. (
  801. AzNetworking::IConnection* invokingConnection,
  802. const AzNetworking::IPacketHeader& packetHeader,
  803. const NetworkEntityUpdateMessage& updateMessage
  804. )
  805. {
  806. if (updateMessage.GetIsDelete())
  807. {
  808. AZLOG(NET_RepDeletes, "Handling entity delete message for entity %llu.", aznumeric_cast<AZ::u64>(updateMessage.GetEntityId()));
  809. }
  810. // May still be nullptr
  811. EntityReplicator* entityReplicator = GetEntityReplicator(updateMessage.GetEntityId());
  812. UpdateValidationResult result = ValidateUpdate(updateMessage, packetHeader.GetPacketId(), entityReplicator);
  813. switch (result)
  814. {
  815. case UpdateValidationResult::HandleMessage:
  816. break;
  817. case UpdateValidationResult::DropMessage:
  818. return true;
  819. case UpdateValidationResult::DropMessageAndDisconnect:
  820. return false;
  821. default:
  822. AZ_Assert(false, "Unhandled case");
  823. }
  824. OutputSerializer outputSerializer(updateMessage.GetData()->GetBuffer(), static_cast<uint32_t>(updateMessage.GetData()->GetSize()));
  825. PrefabEntityId prefabEntityId;
  826. if (updateMessage.GetHasValidPrefabId())
  827. {
  828. // If the update packet contained a PrefabEntityId, use that directly
  829. prefabEntityId = updateMessage.GetPrefabEntityId();
  830. }
  831. else
  832. {
  833. // No PrefabEntityId was provided, so the remote endpoint assumed we already have a replicator set up
  834. // Validate that our replicator actually exists and that it contains a valid PrefabEntityId
  835. if ((entityReplicator == nullptr) || !entityReplicator->IsPrefabEntityIdSet())
  836. {
  837. // Note that we need to make sure the replicator is not marked for removal if we're server authority
  838. // If a client migrates and we receive a property update message out-of-order, this would re-create a replicator which would be bad
  839. AZLOG_ERROR("Unable to process NetworkEntityUpdateMessage without a prefabEntityId, our local EntityReplicator is not set up or is configured incorrectly");
  840. m_replicatorsPendingReset.emplace(updateMessage.GetEntityId());
  841. return true;
  842. }
  843. // Use the cached slice entry data from the entity replicator
  844. prefabEntityId = entityReplicator->GetPrefabEntityId();
  845. }
  846. bool handled = true;
  847. // This may implicitly create a replicator for us
  848. if (updateMessage.GetData()->GetSize() != 0)
  849. {
  850. handled = HandlePropertyChangeMessage(
  851. invokingConnection,
  852. entityReplicator,
  853. packetHeader.GetPacketId(),
  854. updateMessage.GetEntityId(),
  855. updateMessage.GetNetworkRole(),
  856. outputSerializer,
  857. prefabEntityId,
  858. updateMessage.GetIsDelete()) &&
  859. handled;
  860. AZ_Assert(handled, "Failed to handle NetworkEntityUpdateMessage message");
  861. }
  862. else
  863. {
  864. AZ_Assert(updateMessage.GetIsDelete(), "Only delete messages should be able to have 0 data changes.");
  865. }
  866. // Process deletes *after* processing the property updates so that any deactivation / deletion logic
  867. // has access to the most up-to-date property values.
  868. if (updateMessage.GetIsDelete())
  869. {
  870. handled = HandleEntityDeleteMessage(entityReplicator, packetHeader, updateMessage) && handled;
  871. AZLOG(NET_RepDeletes, "Handled entity delete message for entity %llu.", aznumeric_cast<AZ::u64>(updateMessage.GetEntityId()));
  872. }
  873. return handled;
  874. }
  875. bool EntityReplicationManager::HandleEntityRpcMessages(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcVector& rpcVector)
  876. {
  877. for (NetworkEntityRpcMessage& rpcMessage : rpcVector)
  878. {
  879. EntityReplicator* entityReplicator = GetEntityReplicator(rpcMessage.GetEntityId());
  880. const bool isReplicatorValid = (entityReplicator != nullptr) && !entityReplicator->IsMarkedForRemoval();
  881. const bool isEntityActivated = isReplicatorValid && entityReplicator->GetEntityHandle() && (entityReplicator->GetEntityHandle().GetEntity()->GetState() == AZ::Entity::State::Active);
  882. if (!isReplicatorValid || !isEntityActivated)
  883. {
  884. m_orphanedEntityRpcs.AddOrphanedRpc(rpcMessage.GetEntityId(), rpcMessage);
  885. }
  886. else
  887. {
  888. if (!entityReplicator->HandleRpcMessage(invokingConnection, rpcMessage))
  889. {
  890. AZ_Assert(false, "Failed processing RPC messages, disconnecting");
  891. return false;
  892. }
  893. }
  894. }
  895. return true;
  896. }
  897. bool EntityReplicationManager::HandleEntityResetMessages([[maybe_unused]] AzNetworking::IConnection* invokingConnection, const NetEntityIdsForReset& resetIds)
  898. {
  899. for (NetEntityId netEntityId : resetIds)
  900. {
  901. EntityReplicator* entityReplicator = GetEntityReplicator(netEntityId);
  902. if (entityReplicator != nullptr)
  903. {
  904. // Don't reset the remote role, we want to reset the publisher/subscriber
  905. entityReplicator->Reset(entityReplicator->GetRemoteNetworkRole());
  906. }
  907. }
  908. return true;
  909. }
  910. bool EntityReplicationManager::DispatchOrphanedRpc(NetworkEntityRpcMessage& message, EntityReplicator* entityReplicator)
  911. {
  912. if (entityReplicator == nullptr)
  913. {
  914. AZLOG_INFO
  915. (
  916. "EntityReplicationManager: Dropping remote RPC message for component %s of rpc index %s, entityId %llu has already been deleted",
  917. GetMultiplayerComponentRegistry()->GetComponentName(message.GetComponentId()),
  918. GetMultiplayerComponentRegistry()->GetComponentRpcName(message.GetComponentId(), message.GetRpcIndex()),
  919. static_cast<AZ::u64>(message.GetEntityId())
  920. );
  921. return false;
  922. }
  923. return entityReplicator->HandleRpcMessage(nullptr, message);
  924. }
  925. AZ::TimeMs EntityReplicationManager::GetResendTimeoutTimeMs() const
  926. {
  927. return aznumeric_cast<AZ::TimeMs>(aznumeric_cast<uint32_t>(m_connection.GetMetrics().m_connectionRtt.GetRoundTripTimeSeconds()) * 1000 * 2);
  928. }
  929. void EntityReplicationManager::SetMaxRemoteEntitiesPendingCreationCount(uint32_t maxPendingEntities)
  930. {
  931. m_maxRemoteEntitiesPendingCreationCount = maxPendingEntities;
  932. }
  933. void EntityReplicationManager::SetEntityActivationTimeSliceMs(AZ::TimeMs timeSliceMs)
  934. {
  935. m_entityActivationTimeSliceMs = timeSliceMs;
  936. }
  937. void EntityReplicationManager::SetEntityPendingRemovalMs(AZ::TimeMs entityPendingRemovalMs)
  938. {
  939. m_entityPendingRemovalMs = entityPendingRemovalMs;
  940. }
  941. AzNetworking::IConnection& EntityReplicationManager::GetConnection()
  942. {
  943. return m_connection;
  944. }
  945. AZ::TimeMs EntityReplicationManager::GetFrameTimeMs()
  946. {
  947. return m_frameTimeMs;
  948. }
  949. EntityReplicationManager::OrphanedEntityRpcs::OrphanedEntityRpcs(EntityReplicationManager& replicationManager)
  950. : m_replicationManager(replicationManager)
  951. {
  952. ;
  953. }
  954. void EntityReplicationManager::OrphanedEntityRpcs::Update()
  955. {
  956. m_timeoutQueue.UpdateTimeouts([this](AzNetworking::TimeoutQueue::TimeoutItem& item)
  957. {
  958. NetEntityId timedOutEntityId = aznumeric_cast<NetEntityId>(item.m_userData);
  959. auto entityRpcsIter = m_entityRpcMap.find(timedOutEntityId);
  960. if (entityRpcsIter != m_entityRpcMap.end())
  961. {
  962. for (NetworkEntityRpcMessage& rpcMessage : entityRpcsIter->second.m_rpcMessages)
  963. {
  964. m_replicationManager.DispatchOrphanedRpc(rpcMessage, nullptr);
  965. }
  966. m_entityRpcMap.erase(entityRpcsIter);
  967. }
  968. return AzNetworking::TimeoutResult::Delete;
  969. });
  970. }
  971. bool EntityReplicationManager::OrphanedEntityRpcs::DispatchOrphanedRpcs(EntityReplicator& entityReplicator)
  972. {
  973. auto orphanedRpcsIter = m_entityRpcMap.find(entityReplicator.GetEntityHandle().GetNetEntityId());
  974. if (orphanedRpcsIter != m_entityRpcMap.end())
  975. {
  976. bool dispatchedAll = true;
  977. for (NetworkEntityRpcMessage& rpcMessage : orphanedRpcsIter->second.m_rpcMessages)
  978. {
  979. dispatchedAll &= m_replicationManager.DispatchOrphanedRpc(rpcMessage, &entityReplicator);
  980. }
  981. m_timeoutQueue.RemoveItem(orphanedRpcsIter->second.m_timeoutId);
  982. m_entityRpcMap.erase(orphanedRpcsIter);
  983. return dispatchedAll;
  984. }
  985. return true;
  986. }
  987. void EntityReplicationManager::OrphanedEntityRpcs::AddOrphanedRpc(NetEntityId netEntityId, NetworkEntityRpcMessage& message)
  988. {
  989. auto orphanedRpcsIter = m_entityRpcMap.find(netEntityId);
  990. if (orphanedRpcsIter == m_entityRpcMap.end())
  991. {
  992. OrphanedRpcs& orphanedRpcs = m_entityRpcMap[netEntityId];
  993. orphanedRpcs.m_timeoutId = m_timeoutQueue.RegisterItem(aznumeric_cast<uint64_t>(netEntityId), m_replicationManager.GetResendTimeoutTimeMs());
  994. orphanedRpcsIter = m_entityRpcMap.find(netEntityId);
  995. }
  996. orphanedRpcsIter->second.m_rpcMessages.emplace_back(AZStd::move(message));
  997. }
  998. void EntityReplicationManager::OnEntityActivated(AZ::Entity* entity)
  999. {
  1000. ConstNetworkEntityHandle entityHandle(entity);
  1001. NetBindComponent* netBindComponent = entityHandle.GetNetBindComponent();
  1002. if (netBindComponent != nullptr && netBindComponent->HasController())
  1003. {
  1004. if (m_replicationWindow && m_replicationWindow->AddEntity(entity))
  1005. {
  1006. if (!m_entityReplicatorMap.contains(entityHandle.GetNetEntityId()))
  1007. {
  1008. const ReplicationSet& window = m_replicationWindow->GetReplicationSet();
  1009. AddEntityReplicator(entityHandle, window.find(entityHandle)->second.m_netEntityRole);
  1010. }
  1011. }
  1012. }
  1013. }
  1014. void EntityReplicationManager::OnEntityDeactivated(AZ::Entity* entity)
  1015. {
  1016. if (m_replicationWindow)
  1017. {
  1018. m_replicationWindow->RemoveEntity(entity);
  1019. ConstNetworkEntityHandle entityHandle(entity);
  1020. EntityReplicator* replicator = GetEntityReplicator(entityHandle);
  1021. if (replicator && !replicator->IsMarkedForRemoval())
  1022. {
  1023. replicator->MarkForRemoval();
  1024. }
  1025. }
  1026. }
  1027. void EntityReplicationManager::UpdateWindow()
  1028. {
  1029. if (!m_replicationWindow)
  1030. {
  1031. // No window setup, this will occur during connection
  1032. return;
  1033. }
  1034. if (m_replicationWindow->ReplicationSetUpdateReady())
  1035. {
  1036. m_replicationWindow->UpdateWindow();
  1037. const ReplicationSet& newWindow = m_replicationWindow->GetReplicationSet();
  1038. // Walk both for adds and removals
  1039. auto newWindowIter = newWindow.begin();
  1040. auto currWindowIter = m_entityReplicatorMap.begin();
  1041. while (newWindowIter != newWindow.end() && currWindowIter != m_entityReplicatorMap.end())
  1042. {
  1043. if (newWindowIter->first && (newWindowIter->first.GetNetEntityId() < currWindowIter->first))
  1044. {
  1045. AddEntityReplicator(newWindowIter->first, newWindowIter->second.m_netEntityRole);
  1046. ++newWindowIter;
  1047. }
  1048. else if (newWindowIter->first.GetNetEntityId() > currWindowIter->first)
  1049. {
  1050. EntityReplicator* currReplicator = currWindowIter->second.get();
  1051. if (currReplicator->OwnsReplicatorLifetime())
  1052. {
  1053. currReplicator->SetPendingRemoval(m_entityPendingRemovalMs);
  1054. }
  1055. ++currWindowIter;
  1056. }
  1057. else // Same entity
  1058. {
  1059. // Check if we changed modes
  1060. EntityReplicator* currReplicator = currWindowIter->second.get();
  1061. if (currReplicator->GetRemoteNetworkRole() != newWindowIter->second.m_netEntityRole)
  1062. {
  1063. currReplicator = AddEntityReplicator(newWindowIter->first, newWindowIter->second.m_netEntityRole);
  1064. }
  1065. currReplicator->ClearPendingRemoval();
  1066. ++newWindowIter;
  1067. ++currWindowIter;
  1068. }
  1069. }
  1070. // Do remaining adds
  1071. while (newWindowIter != newWindow.end())
  1072. {
  1073. AddEntityReplicator(newWindowIter->first, newWindowIter->second.m_netEntityRole);
  1074. ++newWindowIter;
  1075. }
  1076. // Do remaining removes
  1077. while (currWindowIter != m_entityReplicatorMap.end())
  1078. {
  1079. EntityReplicator* currReplicator = currWindowIter->second.get();
  1080. if (currReplicator->OwnsReplicatorLifetime())
  1081. {
  1082. currReplicator->SetPendingRemoval(m_entityPendingRemovalMs);
  1083. }
  1084. ++currWindowIter;
  1085. }
  1086. }
  1087. }
  1088. void EntityReplicationManager::MigrateAllEntities()
  1089. {
  1090. AZStd::list<NetEntityId> replicatorList;
  1091. GetEntityReplicatorIdList(replicatorList);
  1092. for (auto iter = replicatorList.begin(); iter != replicatorList.end(); ++iter)
  1093. {
  1094. auto replicator = GetEntityReplicator(*iter);
  1095. if (replicator && replicator->OwnsReplicatorLifetime())
  1096. {
  1097. MigrateEntityInternal(*iter);
  1098. }
  1099. else
  1100. {
  1101. ++iter;
  1102. }
  1103. }
  1104. }
  1105. void EntityReplicationManager::MigrateEntity(NetEntityId netEntityId)
  1106. {
  1107. MigrateEntityInternal(netEntityId);
  1108. }
  1109. bool EntityReplicationManager::CanMigrateEntity(const ConstNetworkEntityHandle& entityHandle) const
  1110. {
  1111. bool hasAuthority{ false };
  1112. bool isInDomain{ false };
  1113. bool isMarkedForRemoval{ true };
  1114. bool isRemoteReplicatorEstablished{ false };
  1115. NetBindComponent* netBindComponent = entityHandle.GetNetBindComponent();
  1116. AZ_Assert(netBindComponent, "No NetBindComponent");
  1117. const EntityReplicator* entityReplicator = GetEntityReplicator(entityHandle.GetNetEntityId());
  1118. hasAuthority = (netBindComponent->GetNetEntityRole() == NetEntityRole::Authority); // Make sure someone hasn't migrated this already
  1119. isInDomain = (m_remoteEntityDomain && m_remoteEntityDomain->IsInDomain(entityHandle)); // Make sure the remote side would want it
  1120. if (entityReplicator && entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Authority)
  1121. {
  1122. isMarkedForRemoval = entityReplicator->IsMarkedForRemoval(); // Make sure we aren't telling the other side to remove the replicator
  1123. AZ_Assert(entityReplicator->IsReadyToPublish(), "Expected to be ready to publish");
  1124. isRemoteReplicatorEstablished =
  1125. entityReplicator->IsRemoteReplicatorEstablished(); // Make sure they are setup to receive the replicator
  1126. }
  1127. return hasAuthority && isInDomain && !isMarkedForRemoval && isRemoteReplicatorEstablished;
  1128. }
  1129. bool EntityReplicationManager::HasRemoteAuthority(const ConstNetworkEntityHandle& entityHandle) const
  1130. {
  1131. if (const EntityReplicator* replicator = GetEntityReplicator(entityHandle.GetNetEntityId()))
  1132. {
  1133. return replicator->GetRemoteNetworkRole() == NetEntityRole::Authority;
  1134. }
  1135. return false;
  1136. }
  1137. void EntityReplicationManager::SetRemoteEntityDomain(AZStd::unique_ptr<IEntityDomain> entityDomain)
  1138. {
  1139. m_remoteEntityDomain = AZStd::move(entityDomain);
  1140. }
  1141. IEntityDomain* EntityReplicationManager::GetRemoteEntityDomain()
  1142. {
  1143. return m_remoteEntityDomain.get();
  1144. }
  1145. void EntityReplicationManager::SetReplicationWindow(AZStd::unique_ptr<IReplicationWindow> replicationWindow)
  1146. {
  1147. m_replicationWindow = AZStd::move(replicationWindow);
  1148. UpdateWindow();
  1149. }
  1150. IReplicationWindow* EntityReplicationManager::GetReplicationWindow()
  1151. {
  1152. return m_replicationWindow.get();
  1153. }
  1154. void EntityReplicationManager::MigrateEntityInternal(NetEntityId netEntityId)
  1155. {
  1156. ConstNetworkEntityHandle entityHandle = GetNetworkEntityManager()->GetEntity(netEntityId);
  1157. AZ::Entity* localEnt = entityHandle.GetEntity();
  1158. if (!localEnt)
  1159. {
  1160. return;
  1161. }
  1162. NetBindComponent* netBindComponent = entityHandle.GetNetBindComponent();
  1163. AZ_Assert(netBindComponent, "No NetBindComponent");
  1164. if (netBindComponent && netBindComponent->GetNetEntityRole() == NetEntityRole::Authority)
  1165. {
  1166. EntityReplicator* replicator = AddEntityReplicator(entityHandle, NetEntityRole::Server);
  1167. if (m_updateMode == EntityReplicationManager::Mode::LocalServerToRemoteServer)
  1168. {
  1169. netBindComponent->NotifyServerMigration(GetRemoteHostId());
  1170. }
  1171. if (localEnt->GetState() == AZ::Entity::State::Active)
  1172. {
  1173. netBindComponent->DeactivateControllers(EntityIsMigrating::True);
  1174. }
  1175. netBindComponent->DestructControllers();
  1176. EntityMigrationMessage message = replicator->GenerateMigrationPacket();
  1177. m_sendMigrateEntityEvent.Signal(m_connection, message);
  1178. AZLOG(NET_RepDeletes, "Migration packet sent %llu to remote host %s", static_cast<AZ::u64>(netEntityId), GetRemoteHostId().GetString().c_str());
  1179. // Notify all other EntityReplicationManagers that this entity has migrated so they can adjust their own replicators given our new proxy status
  1180. GetMultiplayer()->SendNotifyEntityMigrationEvent(entityHandle, GetRemoteHostId());
  1181. // Immediately add a new replicator so that we catch RPC invocations, the remote side will make us a new one, and then remove us if needs be
  1182. AddEntityReplicator(entityHandle, NetEntityRole::Authority);
  1183. }
  1184. }
  1185. bool EntityReplicationManager::HandleEntityMigration(AzNetworking::IConnection* invokingConnection, EntityMigrationMessage& message)
  1186. {
  1187. EntityReplicator* replicator = GetEntityReplicator(message.m_netEntityId);
  1188. {
  1189. if (message.m_propertyUpdateData.GetSize() > 0)
  1190. {
  1191. constexpr bool IsDeleted = false;
  1192. OutputSerializer outputSerializer(message.m_propertyUpdateData.GetBuffer(), static_cast<uint32_t>(message.m_propertyUpdateData.GetSize()));
  1193. if (!HandlePropertyChangeMessage
  1194. (
  1195. invokingConnection,
  1196. replicator,
  1197. AzNetworking::InvalidPacketId,
  1198. message.m_netEntityId,
  1199. NetEntityRole::Server,
  1200. outputSerializer,
  1201. message.m_prefabEntityId,
  1202. IsDeleted
  1203. ))
  1204. {
  1205. AZ_Assert(false, "Unable to process network properties during server entity migration");
  1206. return false;
  1207. }
  1208. }
  1209. }
  1210. // The HandlePropertyChangeMessage will have made a replicator if we didn't have one already
  1211. if (!replicator)
  1212. {
  1213. replicator = GetEntityReplicator(message.m_netEntityId);
  1214. }
  1215. AZ_Assert(replicator, "Do not have replicator after handling migration message");
  1216. ConstNetworkEntityHandle entityHandle = replicator->GetEntityHandle();
  1217. NetBindComponent* netBindComponent = entityHandle.GetNetBindComponent();
  1218. AZ_Assert(netBindComponent, "No NetBindComponent");
  1219. // Stop listening to the OnEntityNetworkRoleChange, since we are about to change it and we don't want that callback
  1220. netBindComponent->ConstructControllers();
  1221. if (entityHandle.GetEntity()->GetState() == AZ::Entity::State::Active)
  1222. {
  1223. // Only activate controllers if the entity was previously activated, otherwise, wait for the normal entity activation flow
  1224. netBindComponent->ActivateControllers(EntityIsMigrating::True);
  1225. }
  1226. // Change the role on the replicator
  1227. AddEntityReplicator(entityHandle, NetEntityRole::Server);
  1228. AZLOG(NET_RepDeletes, "Handle Migration %llu new authority from remote host %s", static_cast<AZ::u64>(entityHandle.GetNetEntityId()), GetRemoteHostId().GetString().c_str());
  1229. return true;
  1230. }
  1231. void EntityReplicationManager::OnEntityExitDomain(const ConstNetworkEntityHandle& entityHandle)
  1232. {
  1233. if (CanMigrateEntity(entityHandle))
  1234. {
  1235. MigrateEntity(entityHandle.GetNetEntityId());
  1236. }
  1237. }
  1238. void EntityReplicationManager::OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId)
  1239. {
  1240. if (remoteHostId == GetRemoteHostId())
  1241. {
  1242. // Don't handle self sent messages
  1243. return;
  1244. }
  1245. NetEntityRole remoteRole = NetEntityRole::InvalidRole;
  1246. // TODO: Rethink the IsInWindow call here, this is an IReplicationWindow concern - should we need this at all?
  1247. if (m_replicationWindow && m_replicationWindow->IsInWindow(entityHandle, remoteRole))
  1248. {
  1249. AddEntityReplicator(entityHandle, remoteRole);
  1250. }
  1251. else
  1252. {
  1253. EntityReplicator* replicator = GetEntityReplicator(entityHandle);
  1254. if (replicator)
  1255. {
  1256. replicator->SetWasMigrated(true);
  1257. replicator->MarkForRemoval();
  1258. }
  1259. }
  1260. }
  1261. void EntityReplicationManager::AddReplicatorToPendingRemoval(const EntityReplicator& replicator)
  1262. {
  1263. m_replicatorsPendingRemoval.emplace(replicator.GetEntityHandle().GetNetEntityId());
  1264. }
  1265. void EntityReplicationManager::AddReplicatorToPendingSend(const EntityReplicator& replicator)
  1266. {
  1267. m_replicatorsPendingSend.emplace(replicator.GetEntityHandle().GetNetEntityId());
  1268. }
  1269. void EntityReplicationManager::RemoveReplicatorFromPendingSend(const EntityReplicator& replicator)
  1270. {
  1271. m_replicatorsPendingSend.erase(replicator.GetEntityHandle().GetNetEntityId());
  1272. }
  1273. bool EntityReplicationManager::IsUpdateModeToServerClient()
  1274. {
  1275. return (m_updateMode != Mode::LocalServerToRemoteServer);
  1276. }
  1277. void EntityReplicationManager::ClearRemovedReplicators()
  1278. {
  1279. for (auto iter = m_replicatorsPendingRemoval.begin(); iter != m_replicatorsPendingRemoval.end();)
  1280. {
  1281. EntityReplicator* replicator = GetEntityReplicator(*iter);
  1282. AZ_Assert(replicator, "Replicator deleted unexpectedly");
  1283. if (replicator->IsMarkedForRemoval())
  1284. {
  1285. if (replicator->IsDeletionAcknowledged())
  1286. {
  1287. AZLOG(
  1288. NET_RepDeletes,
  1289. "Deletion acknowledged for entity %llu from remote host %s",
  1290. static_cast<AZ::u64>(replicator->GetEntityHandle().GetNetEntityId()),
  1291. GetRemoteHostId().GetString().c_str());
  1292. m_remoteEntitiesPendingCreation.erase(replicator->GetEntityHandle().GetNetEntityId());
  1293. m_entityReplicatorMap.erase(*iter);
  1294. iter = m_replicatorsPendingRemoval.erase(iter);
  1295. }
  1296. else
  1297. {
  1298. ++iter;
  1299. }
  1300. }
  1301. else
  1302. {
  1303. // no longer marked for removal, remove it from the set
  1304. iter = m_replicatorsPendingRemoval.erase(iter);
  1305. }
  1306. }
  1307. }
  1308. } // namespace Multiplayer