3
0

NetBindComponent.cpp 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  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/Components/NetBindComponent.h>
  9. #include <Multiplayer/Components/MultiplayerComponent.h>
  10. #include <Multiplayer/Components/MultiplayerController.h>
  11. #include <Multiplayer/INetworkSpawnableLibrary.h>
  12. #include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
  13. #include <Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h>
  14. #include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
  15. #include <Multiplayer/NetworkInput/NetworkInput.h>
  16. #include <Source/NetworkEntity/NetworkEntityTracker.h>
  17. #include <AzCore/Console/IConsole.h>
  18. #include <AzCore/Console/ILogger.h>
  19. #include <AzCore/Interface/Interface.h>
  20. #include <AzCore/RTTI/BehaviorContext.h>
  21. #include <AzCore/Serialization/SerializeContext.h>
  22. #include <AzCore/Serialization/EditContext.h>
  23. #include <AzCore/std/sort.h>
  24. namespace Multiplayer
  25. {
  26. void NetBindComponent::Reflect(AZ::ReflectContext* context)
  27. {
  28. PrefabEntityId::Reflect(context);
  29. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  30. if (serializeContext)
  31. {
  32. serializeContext->Class<NetBindComponent, AZ::Component>()
  33. ->Version(2)
  34. ->Field("Prefab EntityId", &NetBindComponent::m_prefabEntityId)
  35. ->Field("Prefab AssetId", &NetBindComponent::m_prefabAssetId)
  36. ;
  37. AZ::EditContext* editContext = serializeContext->GetEditContext();
  38. if (editContext)
  39. {
  40. editContext->Class<NetBindComponent>(
  41. "Network Binding", "The Network Binding component marks an entity as able to be replicated across the network")
  42. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  43. ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer")
  44. ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/NetworkBinding.svg")
  45. ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/NetworkBinding.svg")
  46. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("Game"));
  47. }
  48. }
  49. AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context);
  50. if (behaviorContext)
  51. {
  52. behaviorContext->Class<NetBindComponent>("NetBindComponent")
  53. ->Attribute(AZ::Script::Attributes::Module, "multiplayer")
  54. ->Attribute(AZ::Script::Attributes::Category, "Multiplayer")
  55. ->Method("IsNetEntityRoleAuthority", [](AZ::EntityId id) -> bool {
  56. AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
  57. if (!entity)
  58. {
  59. AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleAuthority failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
  60. return false;
  61. }
  62. NetBindComponent* netBindComponent = GetNetworkEntityTracker()->GetNetBindComponent(entity);
  63. if (!netBindComponent)
  64. {
  65. AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleAuthority failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str())
  66. return false;
  67. }
  68. return netBindComponent->IsNetEntityRoleAuthority();
  69. })
  70. ->Method("IsNetEntityRoleAutonomous", [](AZ::EntityId id) -> bool {
  71. AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
  72. if (!entity)
  73. {
  74. AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleAutonomous failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
  75. return false;
  76. }
  77. NetBindComponent* netBindComponent = GetNetworkEntityTracker()->GetNetBindComponent(entity);
  78. if (!netBindComponent)
  79. {
  80. AZ_Warning("NetBindComponent", false, "NetBindComponent IsNetEntityRoleAutonomous failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str())
  81. return false;
  82. }
  83. return netBindComponent->IsNetEntityRoleAutonomous();
  84. })
  85. ->Method("IsNetEntityRoleClient", [](AZ::EntityId id) -> bool {
  86. AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
  87. if (!entity)
  88. {
  89. AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleClient failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
  90. return false;
  91. }
  92. NetBindComponent* netBindComponent = GetNetworkEntityTracker()->GetNetBindComponent(entity);
  93. if (!netBindComponent)
  94. {
  95. AZ_Warning("NetBindComponent", false, "NetBindComponent IsNetEntityRoleClient failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str())
  96. return false;
  97. }
  98. return netBindComponent->IsNetEntityRoleClient();
  99. })
  100. ->Method("IsNetEntityRoleServer", [](AZ::EntityId id) -> bool {
  101. AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
  102. if (!entity)
  103. {
  104. AZ_Warning( "NetBindComponent", false, "NetBindComponent IsNetEntityRoleServer failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str())
  105. return false;
  106. }
  107. NetBindComponent* netBindComponent = GetNetworkEntityTracker()->GetNetBindComponent(entity);
  108. if (!netBindComponent)
  109. {
  110. AZ_Warning("NetBindComponent", false, "NetBindComponent IsNetEntityRoleServer failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str())
  111. return false;
  112. }
  113. return netBindComponent->IsNetEntityRoleServer();
  114. })
  115. ->Method("MarkForRemoval", [](AZ::EntityId id) {
  116. AZ::Entity* entity = AZ::Interface<AZ::ComponentApplicationRequests>::Get()->FindEntity(id);
  117. if (!entity)
  118. {
  119. AZ_Warning("NetBindComponent", false, "NetBindComponent MarkForRemoval failed. The entity with id %s doesn't exist, please provide a valid entity id.", id.ToString().c_str());
  120. return;
  121. }
  122. NetBindComponent* netBindComponent = GetNetworkEntityTracker()->GetNetBindComponent(entity);
  123. if (!netBindComponent)
  124. {
  125. AZ_Warning("NetBindComponent", false, "NetBindComponent MarkForRemoval failed. Entity '%s' (id: %s) is missing a NetBindComponent, make sure this entity contains a component which derives from NetBindComponent.", entity->GetName().c_str(), id.ToString().c_str())
  126. return;
  127. }
  128. AZ::Interface<IMultiplayer>::Get()->GetNetworkEntityManager()->MarkForRemoval(netBindComponent->GetEntityHandle());
  129. });
  130. }
  131. }
  132. void NetBindComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  133. {
  134. provided.push_back(AZ_CRC_CE("NetBindService"));
  135. }
  136. void NetBindComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  137. {
  138. incompatible.push_back(AZ_CRC_CE("NetBindService"));
  139. }
  140. NetBindComponent::NetBindComponent()
  141. : m_handleLocalServerRpcMessageEventHandle([this](NetworkEntityRpcMessage& message) { HandleLocalServerRpcMessage(message); })
  142. , m_handleLocalAutonomousToAuthorityRpcMessageEventHandle([this](NetworkEntityRpcMessage& message) { HandleLocalAutonomousToAuthorityRpcMessage(message); })
  143. , m_handleLocalAuthorityToAutonomousRpcMessageEventHandle([this](NetworkEntityRpcMessage& message) { HandleLocalAuthorityToAutonomousRpcMessage(message); })
  144. , m_handleLocalAuthorityToClientRpcMessageEventHandle([this](NetworkEntityRpcMessage& message) { HandleLocalAuthorityToClientRpcMessage(message); })
  145. , m_handleMarkedDirty([this]() { HandleMarkedDirty(); })
  146. , m_handleNotifyChanges([this]() { NotifyLocalChanges(); })
  147. , m_handleEntityStateEvent([this](AZ::Entity::State oldState, AZ::Entity::State newState) { OnEntityStateEvent(oldState, newState); })
  148. {
  149. ;
  150. }
  151. NetBindComponent::~NetBindComponent()
  152. {
  153. // If the entity is initialized but never activated, then it's possible to still be in a registered state.
  154. // Make sure that the entity is unregistered from the NetworkEntityManager and NetworkEntityTracker before destruction.
  155. Unregister();
  156. }
  157. void NetBindComponent::Init()
  158. {
  159. auto* netEntityManager = AZ::Interface<INetworkEntityManager>::Get();
  160. if (m_netEntityId == InvalidNetEntityId && netEntityManager && m_prefabAssetId.IsValid())
  161. {
  162. // The component hasn't been pre-setup with NetworkEntityManager yet. Setup now.
  163. const AZ::Name netSpawnableName = AZ::Interface<INetworkSpawnableLibrary>::Get()->GetSpawnableNameFromAssetId(m_prefabAssetId);
  164. // In client-server the level asset is a temporary Root.network.spawnable and is not expected to be registered in time.
  165. AZ_Assert(GetMultiplayer()->GetAgentType() == MultiplayerAgentType::ClientServer || !netSpawnableName.IsEmpty(),
  166. "Could not locate net spawnable on Init for Prefab AssetId: %s",
  167. m_prefabAssetId.ToFixedString().c_str());
  168. PrefabEntityId prefabEntityId;
  169. prefabEntityId.m_prefabName = netSpawnableName;
  170. prefabEntityId.m_entityOffset = m_prefabEntityId.m_entityOffset;
  171. netEntityManager->SetupNetEntity(GetEntity(), prefabEntityId, NetEntityRole::Authority);
  172. }
  173. }
  174. void NetBindComponent::Register(AZ::Entity* entity)
  175. {
  176. if (!m_isRegistered)
  177. {
  178. GetNetworkEntityTracker()->RegisterNetBindComponent(entity, this);
  179. m_netEntityHandle = GetNetworkEntityManager()->AddEntityToEntityMap(m_netEntityId, entity);
  180. m_isRegistered = true;
  181. }
  182. }
  183. void NetBindComponent::Unregister()
  184. {
  185. if (m_isRegistered)
  186. {
  187. GetNetworkEntityTracker()->UnregisterNetBindComponent(this);
  188. GetNetworkEntityManager()->RemoveEntityFromEntityMap(m_netEntityId);
  189. m_netEntityHandle = {};
  190. m_isRegistered = false;
  191. }
  192. }
  193. void NetBindComponent::Activate()
  194. {
  195. // If this entity has been activated and deactivated multiple times since creation, we might need to re-register
  196. // with the NetworkEntityTracker and NetworkEntityManager.
  197. Register(GetEntity());
  198. m_needsToBeStopped = true;
  199. if (m_netEntityRole == NetEntityRole::Authority)
  200. {
  201. m_handleLocalServerRpcMessageEventHandle.Connect(m_sendServerToAuthorityRpcEvent);
  202. if (Multiplayer::GetMultiplayer()->GetAgentType() == MultiplayerAgentType::ClientServer)
  203. {
  204. m_handleLocalAutonomousToAuthorityRpcMessageEventHandle.Connect(m_sendAutonomousToAuthorityRpcEvent);
  205. m_handleLocalAuthorityToAutonomousRpcMessageEventHandle.Connect(m_sendAuthorityToAutonomousRpcEvent);
  206. m_handleLocalAuthorityToClientRpcMessageEventHandle.Connect(m_sendAuthorityToClientRpcEvent);
  207. }
  208. }
  209. if (HasController())
  210. {
  211. DetermineInputOrdering();
  212. // Listen for the entity to completely activate so that we can notify that all controllers have been activated
  213. GetEntity()->AddStateEventHandler(m_handleEntityStateEvent);
  214. }
  215. }
  216. void NetBindComponent::Deactivate()
  217. {
  218. StopEntity();
  219. m_handleLocalServerRpcMessageEventHandle.Disconnect();
  220. m_handleLocalAutonomousToAuthorityRpcMessageEventHandle.Disconnect();
  221. m_handleLocalAuthorityToClientRpcMessageEventHandle.Disconnect();
  222. if (HasController())
  223. {
  224. GetNetworkEntityManager()->NotifyControllersDeactivated(m_netEntityHandle, EntityIsMigrating::False);
  225. }
  226. // Remove this entity from the NetworkEntityTracker and NetworkEntityManager.
  227. Unregister();
  228. }
  229. NetEntityRole NetBindComponent::GetNetEntityRole() const
  230. {
  231. return m_netEntityRole;
  232. }
  233. bool NetBindComponent::IsNetEntityRoleAuthority() const
  234. {
  235. return (m_netEntityRole == NetEntityRole::Authority);
  236. }
  237. bool NetBindComponent::IsNetEntityRoleAutonomous() const
  238. {
  239. return (m_netEntityRole == NetEntityRole::Autonomous)
  240. || (m_netEntityRole == NetEntityRole::Authority) && m_playerHostAutonomyEnabled;
  241. }
  242. bool NetBindComponent::IsNetEntityRoleServer() const
  243. {
  244. return (m_netEntityRole == NetEntityRole::Server);
  245. }
  246. bool NetBindComponent::IsNetEntityRoleClient() const
  247. {
  248. return (m_netEntityRole == NetEntityRole::Client);
  249. }
  250. void NetBindComponent::SetAllowEntityMigration(EntityMigration value)
  251. {
  252. m_netEntityMigration = value;
  253. }
  254. EntityMigration NetBindComponent::GetAllowEntityMigration() const
  255. {
  256. return m_netEntityMigration;
  257. }
  258. bool NetBindComponent::ValidatePropertyRead(const char* propertyName, NetEntityRole replicateFrom, NetEntityRole replicateTo) const
  259. {
  260. bool isValid(false);
  261. if (replicateFrom == NetEntityRole::Authority)
  262. {
  263. // Things that replicate to clients are readable by all network entity roles
  264. const bool replicatesToClient = (replicateTo == NetEntityRole::Client);
  265. // Things that replicate from Authority can be read by all hosts
  266. const bool isHost = (IsNetEntityRoleAuthority() || IsNetEntityRoleServer());
  267. // Things that replicate to Autonomous can't be read by clients
  268. const bool isAutonomous = ((replicateTo == NetEntityRole::Autonomous) && !IsNetEntityRoleClient());
  269. isValid = replicatesToClient || isHost || isAutonomous;
  270. }
  271. else
  272. {
  273. // Autonomous can only replicate to Authority, and won't replicate to servers, it's meant for client authoritative values like basic client metrics
  274. AZ_Assert(replicateTo == NetEntityRole::Authority, "The only valid case where properties replicate from a non-authority is in autonomous to authority");
  275. isValid = IsNetEntityRoleAuthority() || IsNetEntityRoleAutonomous();
  276. }
  277. if (!isValid)
  278. {
  279. AZLOG_INFO("%s is not replicated to role %s, property read will return invalid data.", propertyName, GetEnumString(GetNetEntityRole()));
  280. }
  281. return isValid;
  282. }
  283. bool NetBindComponent::ValidatePropertyWrite(const char* propertyName, NetEntityRole replicateFrom, [[maybe_unused]] NetEntityRole replicateTo, bool isPredictable) const
  284. {
  285. bool isValid = (replicateFrom == GetNetEntityRole())
  286. || (isPredictable && IsNetEntityRoleAutonomous());
  287. if (!isValid)
  288. {
  289. AZLOG_INFO("%s can't be written by role %s, property set will desync network state.", propertyName, GetEnumString(GetNetEntityRole()));
  290. }
  291. return isValid;
  292. }
  293. bool NetBindComponent::HasController() const
  294. {
  295. return (m_netEntityRole == NetEntityRole::Authority)
  296. || (m_netEntityRole == NetEntityRole::Autonomous);
  297. }
  298. NetEntityId NetBindComponent::GetNetEntityId() const
  299. {
  300. return m_netEntityId;
  301. }
  302. const PrefabEntityId& NetBindComponent::GetPrefabEntityId() const
  303. {
  304. return m_prefabEntityId;
  305. }
  306. void NetBindComponent::SetPrefabEntityId(const PrefabEntityId& prefabEntityId)
  307. {
  308. m_prefabEntityId = prefabEntityId;
  309. }
  310. ConstNetworkEntityHandle NetBindComponent::GetEntityHandle() const
  311. {
  312. return m_netEntityHandle;
  313. }
  314. NetworkEntityHandle NetBindComponent::GetEntityHandle()
  315. {
  316. return m_netEntityHandle;
  317. }
  318. void NetBindComponent::SetOwningConnectionId(AzNetworking::ConnectionId connectionId)
  319. {
  320. m_owningConnectionId = connectionId;
  321. for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector)
  322. {
  323. multiplayerComponent->SetOwningConnectionId(connectionId);
  324. }
  325. }
  326. AzNetworking::ConnectionId NetBindComponent::GetOwningConnectionId() const
  327. {
  328. return m_owningConnectionId;
  329. }
  330. void NetBindComponent::EnablePlayerHostAutonomy(bool enabled)
  331. {
  332. if (m_playerHostAutonomyEnabled == enabled)
  333. {
  334. return; // nothing to change
  335. }
  336. if (!IsNetEntityRoleAuthority())
  337. {
  338. AZ_Error("NetBindComponent", false,
  339. "Failed to enable player host autonomy for network entity (%s). Entity has incorrect network role (%s). This method only allows a player host to autonomously control their player entity.",
  340. GetEntity()->GetName().c_str(),
  341. GetEnumString(GetNetEntityRole()));
  342. return;
  343. }
  344. // If the entity is already activated then deactivate all of the entity's multiplayer controllers before changing autonomy.
  345. // Multiplayer controllers will commonly perform different logic during their "OnActivate" depending on if the entity is autonomous.
  346. if (GetEntity()->GetState() == AZ::Entity::State::Active)
  347. {
  348. // deactivate controllers in reverse dependency order
  349. const AZ::Entity::ComponentArrayType& components = GetEntity()->GetComponents();
  350. for (auto componentIter = components.rbegin(); componentIter != components.rend(); ++componentIter)
  351. {
  352. if (auto multiplayerComponent = azrtti_cast<MultiplayerComponent*>(*componentIter))
  353. {
  354. multiplayerComponent->GetController()->Deactivate(EntityIsMigrating::False);
  355. }
  356. }
  357. // This flag allows a player host to autonomously control their player entity, even though the entity is in an authority role
  358. m_playerHostAutonomyEnabled = enabled;
  359. // reactivate the controllers now that allow autonomy is true
  360. for (auto component : components)
  361. {
  362. if (auto multiplayerComponent = azrtti_cast<MultiplayerComponent*>(component))
  363. {
  364. multiplayerComponent->GetController()->Activate(EntityIsMigrating::False);
  365. }
  366. }
  367. }
  368. else // This entity isn't activated yet, so there's no need to refresh its multiplayer component controllers
  369. {
  370. // This flag allows a player host to autonomously control their player entity, even though the entity is in an authority role
  371. m_playerHostAutonomyEnabled = enabled;
  372. }
  373. }
  374. MultiplayerComponentInputVector NetBindComponent::AllocateComponentInputs()
  375. {
  376. MultiplayerComponentInputVector componentInputs;
  377. const size_t multiplayerComponentSize = m_multiplayerInputComponentVector.size();
  378. for (size_t i = 0; i < multiplayerComponentSize; ++i)
  379. {
  380. const NetComponentId netComponentId = m_multiplayerInputComponentVector[i]->GetNetComponentId();
  381. AZStd::unique_ptr<IMultiplayerComponentInput> componentInput = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(netComponentId));
  382. if (componentInput != nullptr)
  383. {
  384. componentInputs.emplace_back(AZStd::move(componentInput));
  385. }
  386. }
  387. return componentInputs;
  388. }
  389. bool NetBindComponent::IsProcessingInput() const
  390. {
  391. return m_isProcessingInput;
  392. }
  393. bool NetBindComponent::IsReprocessingInput() const
  394. {
  395. return m_isReprocessingInput;
  396. }
  397. void NetBindComponent::CreateInput(NetworkInput& networkInput, float deltaTime)
  398. {
  399. // Only autonomous runs this logic
  400. AZ_Assert(IsNetEntityRoleAutonomous(), "Incorrect network role for input creation");
  401. for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector)
  402. {
  403. multiplayerComponent->GetController()->CreateInputFromScript(networkInput, deltaTime);
  404. multiplayerComponent->GetController()->CreateInput(networkInput, deltaTime);
  405. }
  406. }
  407. void NetBindComponent::ProcessInput(NetworkInput& networkInput, float deltaTime)
  408. {
  409. m_isProcessingInput = true;
  410. // Only autonomous and authority runs this logic
  411. AZ_Assert((HasController()), "Incorrect network role for input processing");
  412. for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector)
  413. {
  414. multiplayerComponent->GetController()->ProcessInputFromScript(networkInput, deltaTime);
  415. multiplayerComponent->GetController()->ProcessInput(networkInput, deltaTime);
  416. }
  417. m_isProcessingInput = false;
  418. }
  419. void NetBindComponent::ReprocessInput(NetworkInput& networkInput, float deltaTime)
  420. {
  421. m_isReprocessingInput = true;
  422. ProcessInput(networkInput, deltaTime);
  423. m_isReprocessingInput = false;
  424. }
  425. bool NetBindComponent::HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetEntityRole remoteRole, NetworkEntityRpcMessage& message)
  426. {
  427. auto findIt = m_multiplayerComponentMap.find(message.GetComponentId());
  428. if (findIt != m_multiplayerComponentMap.end())
  429. {
  430. return findIt->second->HandleRpcMessage(invokingConnection, remoteRole, message);
  431. }
  432. return false;
  433. }
  434. bool NetBindComponent::HandlePropertyChangeMessage(AzNetworking::ISerializer& serializer, bool notifyChanges)
  435. {
  436. const NetEntityRole netEntityRole = m_netEntityRole;
  437. ReplicationRecord replicationRecord(netEntityRole);
  438. replicationRecord.Serialize(serializer);
  439. if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && (netEntityRole == NetEntityRole::Server))
  440. {
  441. // Make sure to capture the entirety of the TotalRecord, before we clear out bits that haven't changed from our local state
  442. // If this entity migrates, we need to send all bits that might have changed from original baseline
  443. m_totalRecord.Append(replicationRecord);
  444. }
  445. // This will modify the replicationRecord and clear out bits that have not changed from the local state, this prevents us from notifying that something has changed multiple times
  446. SerializeStateDeltaMessage(replicationRecord, serializer);
  447. if (serializer.IsValid())
  448. {
  449. replicationRecord.ResetConsumedBits();
  450. if (notifyChanges)
  451. {
  452. NotifyStateDeltaChanges(replicationRecord);
  453. }
  454. // If we are deserializing on an entity, and this is a server simulation, then we need to remark our bits as dirty to replicate to the client
  455. if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && (netEntityRole == NetEntityRole::Server))
  456. {
  457. m_currentRecord.Append(replicationRecord);
  458. MarkDirty();
  459. }
  460. }
  461. return serializer.IsValid();
  462. }
  463. RpcSendEvent& NetBindComponent::GetSendAuthorityToClientRpcEvent()
  464. {
  465. return m_sendAuthorityToClientRpcEvent;
  466. }
  467. RpcSendEvent& NetBindComponent::GetSendAuthorityToAutonomousRpcEvent()
  468. {
  469. return m_sendAuthorityToAutonomousRpcEvent;
  470. }
  471. RpcSendEvent& NetBindComponent::GetSendServerToAuthorityRpcEvent()
  472. {
  473. return m_sendServerToAuthorityRpcEvent;
  474. }
  475. RpcSendEvent& NetBindComponent::GetSendAutonomousToAuthorityRpcEvent()
  476. {
  477. return m_sendAutonomousToAuthorityRpcEvent;
  478. }
  479. const ReplicationRecord& NetBindComponent::GetPredictableRecord() const
  480. {
  481. return m_predictableRecord;
  482. }
  483. void NetBindComponent::MarkDirty()
  484. {
  485. if (!m_handleMarkedDirty.IsConnected())
  486. {
  487. GetNetworkEntityManager()->AddEntityMarkedDirtyHandler(m_handleMarkedDirty);
  488. }
  489. }
  490. void NetBindComponent::NotifyLocalChanges()
  491. {
  492. m_localNotificationRecord.ResetConsumedBits(); // Make sure our consumed bits are reset so that we can run through the notifications
  493. NotifyStateDeltaChanges(m_localNotificationRecord);
  494. m_localNotificationRecord.Clear();
  495. }
  496. void NetBindComponent::NotifySyncRewindState()
  497. {
  498. m_syncRewindEvent.Signal();
  499. }
  500. void NetBindComponent::NotifyServerMigration(const HostId& remoteHostId)
  501. {
  502. m_entityServerMigrationEvent.Signal(m_netEntityHandle, remoteHostId);
  503. }
  504. void NetBindComponent::NotifyPreRender(float deltaTime)
  505. {
  506. m_entityPreRenderEvent.Signal(deltaTime);
  507. }
  508. void NetBindComponent::NotifyCorrection()
  509. {
  510. m_entityCorrectionEvent.Signal();
  511. }
  512. void NetBindComponent::AddEntityStopEventHandler(EntityStopEvent::Handler& eventHandler)
  513. {
  514. eventHandler.Connect(m_entityStopEvent);
  515. }
  516. void NetBindComponent::AddEntityDirtiedEventHandler(EntityDirtiedEvent::Handler& eventHandler)
  517. {
  518. eventHandler.Connect(m_dirtiedEvent);
  519. }
  520. void NetBindComponent::AddEntitySyncRewindEventHandler(EntitySyncRewindEvent::Handler& eventHandler)
  521. {
  522. eventHandler.Connect(m_syncRewindEvent);
  523. }
  524. void NetBindComponent::AddEntityServerMigrationEventHandler(EntityServerMigrationEvent::Handler& eventHandler)
  525. {
  526. eventHandler.Connect(m_entityServerMigrationEvent);
  527. }
  528. void NetBindComponent::AddEntityPreRenderEventHandler(EntityPreRenderEvent::Handler& eventHandler)
  529. {
  530. eventHandler.Connect(m_entityPreRenderEvent);
  531. }
  532. void NetBindComponent::AddEntityCorrectionEventHandler(EntityCorrectionEvent::Handler& eventHandler)
  533. {
  534. eventHandler.Connect(m_entityCorrectionEvent);
  535. }
  536. void NetBindComponent::AddNetworkActivatedEventHandler(AZ::Event<>::Handler& eventHandler)
  537. {
  538. eventHandler.Connect(m_onNetworkActivated);
  539. }
  540. bool NetBindComponent::SerializeEntityCorrection(AzNetworking::ISerializer& serializer)
  541. {
  542. m_predictableRecord.ResetConsumedBits();
  543. ReplicationRecord tmpRecord = m_predictableRecord;
  544. // The m_predictableRecord is a record that that marks every NetworkProperty that has been set as Predictable
  545. // We copy this record and use a temporary so that SerializeStateDeltaMessage will not modify the m_predictableRecord
  546. // since SerializeStateDeltaMessage will clear the dirty bit for the NetworkProperty if it did not actually change
  547. const bool success = SerializeStateDeltaMessage(tmpRecord, serializer);
  548. if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
  549. {
  550. tmpRecord.ResetConsumedBits();
  551. NotifyStateDeltaChanges(tmpRecord);
  552. }
  553. return success;
  554. }
  555. bool NetBindComponent::SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer)
  556. {
  557. auto& stats = GetMultiplayer()->GetStats();
  558. stats.RecordEntitySerializeStart(serializer.GetSerializerMode(), GetEntityId(), GetEntity()->GetName().c_str());
  559. bool success = true;
  560. serializer.BeginObject(GetEntity()->GetName().c_str());
  561. for (auto iter = m_multiplayerSerializationComponentVector.begin(); iter != m_multiplayerSerializationComponentVector.end(); ++iter)
  562. {
  563. success &= (*iter)->SerializeStateDeltaMessage(replicationRecord, serializer);
  564. stats.RecordComponentSerializeEnd(serializer.GetSerializerMode(), (*iter)->GetNetComponentId());
  565. }
  566. serializer.EndObject(GetEntity()->GetName().c_str());
  567. stats.RecordEntitySerializeStop(serializer.GetSerializerMode(), GetEntityId(), GetEntity()->GetName().c_str());
  568. return success;
  569. }
  570. void NetBindComponent::NotifyStateDeltaChanges(ReplicationRecord& replicationRecord)
  571. {
  572. for (auto iter = m_multiplayerSerializationComponentVector.begin(); iter != m_multiplayerSerializationComponentVector.end(); ++iter)
  573. {
  574. (*iter)->NotifyStateDeltaChanges(replicationRecord);
  575. }
  576. }
  577. void NetBindComponent::FillReplicationRecord(ReplicationRecord& replicationRecord) const
  578. {
  579. if (m_currentRecord.HasChanges())
  580. {
  581. replicationRecord.Append(m_currentRecord);
  582. }
  583. }
  584. void NetBindComponent::FillTotalReplicationRecord(ReplicationRecord& replicationRecord) const
  585. {
  586. replicationRecord.Append(m_totalRecord);
  587. // If we have any outstanding changes yet to be logged, grab those as well
  588. if (m_currentRecord.HasChanges())
  589. {
  590. replicationRecord.Append(m_currentRecord);
  591. }
  592. }
  593. void NetBindComponent::PreInit(AZ::Entity* entity, const PrefabEntityId& prefabEntityId, NetEntityId netEntityId, NetEntityRole netEntityRole)
  594. {
  595. AZ_Assert(entity != nullptr, "AZ::Entity is null");
  596. m_netEntityId = netEntityId;
  597. m_netEntityRole = netEntityRole;
  598. m_prefabEntityId = prefabEntityId;
  599. // Register the entity with the NetworkEntityTracker and NetworkEntityManager.
  600. Register(entity);
  601. for (AZ::Component* component : entity->GetComponents())
  602. {
  603. MultiplayerComponent* multiplayerComponent = azrtti_cast<MultiplayerComponent*>(component);
  604. if (multiplayerComponent != nullptr)
  605. {
  606. m_multiplayerComponentMap[multiplayerComponent->GetNetComponentId()] = multiplayerComponent;
  607. }
  608. }
  609. // Populate the component vector using component map ordering, since it's ordered by component type
  610. // It is absolutely essential that the ordering of this vector be consistent between client and server
  611. for (auto iter : m_multiplayerComponentMap)
  612. {
  613. m_multiplayerSerializationComponentVector.push_back(iter.second);
  614. }
  615. NetworkAttach();
  616. }
  617. void NetBindComponent::ConstructControllers()
  618. {
  619. switch (m_netEntityRole)
  620. {
  621. case NetEntityRole::Client:
  622. m_netEntityRole = NetEntityRole::Autonomous;
  623. break;
  624. case NetEntityRole::Server:
  625. m_netEntityRole = NetEntityRole::Authority;
  626. break;
  627. default:
  628. AZ_Assert(false, "Controller already constructed");
  629. }
  630. // Use AZ component ordering to preserve component dependency ordering during controller construction
  631. const AZ::Entity::ComponentArrayType& entityComponents = GetEntity()->GetComponents();
  632. for (auto iter = entityComponents.begin(); iter != entityComponents.end(); ++iter)
  633. {
  634. MultiplayerComponent* multiplayerComponent = azrtti_cast<MultiplayerComponent*>(*iter);
  635. if (multiplayerComponent != nullptr)
  636. {
  637. multiplayerComponent->ConstructController();
  638. }
  639. }
  640. }
  641. void NetBindComponent::DestructControllers()
  642. {
  643. // Use AZ component ordering to preserve component dependency ordering during controller destruction
  644. const AZ::Entity::ComponentArrayType& entityComponents = GetEntity()->GetComponents();
  645. for (auto iter = entityComponents.rbegin(); iter != entityComponents.rend(); ++iter)
  646. {
  647. MultiplayerComponent* multiplayerComponent = azrtti_cast<MultiplayerComponent*>(*iter);
  648. if (multiplayerComponent != nullptr)
  649. {
  650. multiplayerComponent->DestructController();
  651. }
  652. }
  653. switch (m_netEntityRole)
  654. {
  655. case NetEntityRole::Autonomous:
  656. m_netEntityRole = NetEntityRole::Client;
  657. break;
  658. case NetEntityRole::Authority:
  659. m_netEntityRole = NetEntityRole::Server;
  660. break;
  661. default:
  662. AZ_Assert(false, "Controllers already destructed");
  663. }
  664. }
  665. void NetBindComponent::ActivateControllers(EntityIsMigrating entityIsMigrating)
  666. {
  667. // Use AZ component ordering to preserve component dependency ordering
  668. const AZ::Entity::ComponentArrayType& entityComponents = GetEntity()->GetComponents();
  669. for (auto iter = entityComponents.begin(); iter != entityComponents.end(); ++iter)
  670. {
  671. MultiplayerComponent* multiplayerComponent = azrtti_cast<MultiplayerComponent*>(*iter);
  672. if (multiplayerComponent != nullptr)
  673. {
  674. multiplayerComponent->ActivateController(entityIsMigrating);
  675. }
  676. }
  677. DetermineInputOrdering();
  678. if (GetNetEntityRole() == NetEntityRole::Authority)
  679. {
  680. m_handleLocalServerRpcMessageEventHandle.Connect(m_sendServerToAuthorityRpcEvent);
  681. }
  682. GetNetworkEntityManager()->NotifyControllersActivated(m_netEntityHandle, entityIsMigrating);
  683. }
  684. void NetBindComponent::DeactivateControllers(EntityIsMigrating entityIsMigrating)
  685. {
  686. m_handleLocalServerRpcMessageEventHandle.Disconnect();
  687. // Use AZ component ordering to preserve component dependency ordering
  688. const AZ::Entity::ComponentArrayType& entityComponents = GetEntity()->GetComponents();
  689. for (auto iter = entityComponents.rbegin(); iter != entityComponents.rend(); ++iter)
  690. {
  691. MultiplayerComponent* multiplayerComponent = azrtti_cast<MultiplayerComponent*>(*iter);
  692. if (multiplayerComponent != nullptr)
  693. {
  694. multiplayerComponent->DeactivateController(entityIsMigrating);
  695. }
  696. }
  697. GetNetworkEntityManager()->NotifyControllersDeactivated(m_netEntityHandle, entityIsMigrating);
  698. }
  699. void NetBindComponent::OnEntityStateEvent([[maybe_unused]] AZ::Entity::State oldState, AZ::Entity::State newState)
  700. {
  701. // Wait for the entity to change to an active state
  702. if (newState == AZ::Entity::State::Active)
  703. {
  704. GetNetworkEntityManager()->NotifyControllersActivated(m_netEntityHandle, EntityIsMigrating::False);
  705. m_handleEntityStateEvent.Disconnect();
  706. }
  707. }
  708. void NetBindComponent::NetworkAttach()
  709. {
  710. for (auto* component : m_multiplayerSerializationComponentVector)
  711. {
  712. component->NetworkAttach(this, m_currentRecord, m_predictableRecord);
  713. }
  714. m_totalRecord = m_currentRecord;
  715. }
  716. void NetBindComponent::NetworkActivated()
  717. {
  718. m_onNetworkActivated.Signal();
  719. }
  720. void NetBindComponent::HandleMarkedDirty()
  721. {
  722. m_dirtiedEvent.Signal();
  723. if (HasController())
  724. {
  725. m_localNotificationRecord.Append(m_currentRecord);
  726. if (!m_handleNotifyChanges.IsConnected())
  727. {
  728. GetNetworkEntityManager()->AddEntityNotifyChangesHandler(m_handleNotifyChanges);
  729. }
  730. }
  731. m_totalRecord.Append(m_currentRecord);
  732. m_currentRecord.Clear();
  733. }
  734. void NetBindComponent::HandleLocalServerRpcMessage(NetworkEntityRpcMessage& message)
  735. {
  736. message.SetRpcDeliveryType(RpcDeliveryType::ServerToAuthority);
  737. GetNetworkEntityManager()->HandleLocalRpcMessage(message);
  738. }
  739. void NetBindComponent::HandleLocalAutonomousToAuthorityRpcMessage(NetworkEntityRpcMessage& message)
  740. {
  741. message.SetRpcDeliveryType(RpcDeliveryType::AutonomousToAuthority);
  742. GetNetworkEntityManager()->HandleLocalRpcMessage(message);
  743. }
  744. void NetBindComponent::HandleLocalAuthorityToAutonomousRpcMessage(NetworkEntityRpcMessage& message)
  745. {
  746. message.SetRpcDeliveryType(RpcDeliveryType::AuthorityToAutonomous);
  747. GetNetworkEntityManager()->HandleLocalRpcMessage(message);
  748. }
  749. void NetBindComponent::HandleLocalAuthorityToClientRpcMessage(NetworkEntityRpcMessage& message)
  750. {
  751. message.SetRpcDeliveryType(RpcDeliveryType::AuthorityToClient);
  752. GetNetworkEntityManager()->HandleLocalRpcMessage(message);
  753. }
  754. void NetBindComponent::DetermineInputOrdering()
  755. {
  756. AZ_Assert(HasController(), "Incorrect network role for input processing");
  757. m_multiplayerInputComponentVector.clear();
  758. // walk the components in the activation order so that our default ordering for input matches our dependency sort
  759. for (AZ::Component* component : GetEntity()->GetComponents())
  760. {
  761. MultiplayerComponent* multiplayerComponent = azrtti_cast<MultiplayerComponent*>(component);
  762. if (multiplayerComponent != nullptr)
  763. {
  764. multiplayerComponent->SetOwningConnectionId(m_owningConnectionId);
  765. m_multiplayerInputComponentVector.push_back(multiplayerComponent);
  766. }
  767. }
  768. AZStd::stable_sort
  769. (
  770. m_multiplayerInputComponentVector.begin(),
  771. m_multiplayerInputComponentVector.end(),
  772. [](MultiplayerComponent* left, MultiplayerComponent* right) -> bool
  773. {
  774. return left->GetController()->GetInputOrder() < right->GetController()->GetInputOrder();
  775. }
  776. );
  777. }
  778. void NetBindComponent::StopEntity()
  779. {
  780. if (m_needsToBeStopped)
  781. {
  782. m_needsToBeStopped = false;
  783. m_entityStopEvent.Signal(m_netEntityHandle);
  784. }
  785. }
  786. const AZ::Data::AssetId& NetBindComponent::GetPrefabAssetId() const
  787. {
  788. return m_prefabAssetId;
  789. }
  790. void NetBindComponent::SetPrefabAssetId(const AZ::Data::AssetId& prefabAssetId)
  791. {
  792. m_prefabAssetId = prefabAssetId;
  793. }
  794. bool NetworkRoleHasController(NetEntityRole networkRole)
  795. {
  796. switch (networkRole)
  797. {
  798. case NetEntityRole::Autonomous: // Fall through
  799. case NetEntityRole::Authority:
  800. return true;
  801. default:
  802. return false;
  803. }
  804. }
  805. }