NetworkInput.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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/NetworkInput/NetworkInput.h>
  9. #include <Multiplayer/Components/MultiplayerComponentRegistry.h>
  10. #include <Multiplayer/Components/NetBindComponent.h>
  11. #include <Multiplayer/IMultiplayer.h>
  12. #include <AzCore/Console/IConsole.h>
  13. #include <AzCore/Console/ILogger.h>
  14. namespace Multiplayer
  15. {
  16. NetworkInput::NetworkInput(const NetworkInput& rhs)
  17. : m_inputId(rhs.m_inputId)
  18. , m_owner(rhs.m_owner)
  19. {
  20. CopyInternal(rhs);
  21. }
  22. NetworkInput& NetworkInput::operator= (const NetworkInput& rhs)
  23. {
  24. if (&rhs != this)
  25. {
  26. CopyInternal(rhs);
  27. }
  28. return *this;
  29. }
  30. void NetworkInput::SetClientInputId(ClientInputId inputId)
  31. {
  32. m_inputId = inputId;
  33. }
  34. ClientInputId NetworkInput::GetClientInputId() const
  35. {
  36. return m_inputId;
  37. }
  38. ClientInputId& NetworkInput::ModifyClientInputId()
  39. {
  40. return m_inputId;
  41. }
  42. void NetworkInput::SetHostFrameId(HostFrameId hostFrameId)
  43. {
  44. m_hostFrameId = hostFrameId;
  45. }
  46. HostFrameId NetworkInput::GetHostFrameId() const
  47. {
  48. return m_hostFrameId;
  49. }
  50. HostFrameId& NetworkInput::ModifyHostFrameId()
  51. {
  52. return m_hostFrameId;
  53. }
  54. void NetworkInput::SetHostTimeMs(AZ::TimeMs hostTimeMs)
  55. {
  56. m_hostTimeMs = hostTimeMs;
  57. }
  58. AZ::TimeMs NetworkInput::GetHostTimeMs() const
  59. {
  60. return m_hostTimeMs;
  61. }
  62. AZ::TimeMs& NetworkInput::ModifyHostTimeMs()
  63. {
  64. return m_hostTimeMs;
  65. }
  66. void NetworkInput::SetHostBlendFactor(float hostBlendFactor)
  67. {
  68. m_hostBlendFactor = hostBlendFactor;
  69. }
  70. float NetworkInput::GetHostBlendFactor() const
  71. {
  72. return m_hostBlendFactor;
  73. }
  74. AZStd::vector<MultiplayerAuditingElement> NetworkInput::GetComponentInputDeltaLogs() const
  75. {
  76. AZStd::vector<MultiplayerAuditingElement> logs;
  77. for (uint16_t idx = 0; idx < m_componentInputs.size(); ++idx)
  78. {
  79. MultiplayerAuditingElement log = m_componentInputs[idx].get()->GetInputDeltaLog();
  80. if (!log.m_elements.empty())
  81. {
  82. logs.push_back(AZStd::move(log));
  83. }
  84. }
  85. return logs;
  86. }
  87. const AZStd::string NetworkInput::GetOwnerName() const
  88. {
  89. const AZ::Entity* owner = m_owner.GetEntity();
  90. if (owner != nullptr)
  91. {
  92. return owner->GetName();
  93. }
  94. return "";
  95. }
  96. void NetworkInput::AttachNetBindComponent(NetBindComponent* netBindComponent)
  97. {
  98. m_wasAttached = true;
  99. m_componentInputs.clear();
  100. if (netBindComponent)
  101. {
  102. m_owner = netBindComponent->GetEntityHandle();
  103. m_componentInputs = netBindComponent->AllocateComponentInputs();
  104. }
  105. }
  106. bool NetworkInput::Serialize(AzNetworking::ISerializer& serializer)
  107. {
  108. if (!serializer.Serialize(m_inputId, "InputId")
  109. || !serializer.Serialize(m_hostTimeMs, "HostTimeMs")
  110. || !serializer.Serialize(m_hostFrameId, "HostFrameId")
  111. || !serializer.Serialize(m_hostBlendFactor, "HostBlendFactor"))
  112. {
  113. return false;
  114. }
  115. uint16_t componentInputCount = static_cast<uint16_t>(m_componentInputs.size());
  116. serializer.Serialize(componentInputCount, "ComponentInputCount");
  117. m_componentInputs.resize(componentInputCount);
  118. if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
  119. {
  120. for (uint16_t i = 0; i < componentInputCount; ++i)
  121. {
  122. // We need to do a little extra work here, the delta serializer won't actually write out values if they were the same as the parent.
  123. // We need to make sure we don't lose state that is intrinsic to the underlying type
  124. // The default InvalidNetComponentId is a placeholder, we expect it to be overwritten by the serializer
  125. // This happens when deserializing a non-delta'd input command
  126. // However in the delta serializer case, we use the previous input as our initial value
  127. // which will have the NetworkInputs setup and therefore won't write out the componentId
  128. NetComponentId componentId = m_componentInputs[i] ? m_componentInputs[i]->GetNetComponentId() : InvalidNetComponentId;
  129. serializer.Serialize(componentId, "ComponentId");
  130. // Create a new input if we don't have one or the types do not match
  131. if ((m_componentInputs[i] == nullptr) || (componentId != m_componentInputs[i]->GetNetComponentId()))
  132. {
  133. m_componentInputs[i] = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(componentId));
  134. }
  135. if (!m_componentInputs[i])
  136. {
  137. // If the client tells us a component type that does not have a NetworkInput, they are likely hacking
  138. AZLOG_ERROR("Unexpected MultiplayerComponent type, unable to deserialize, dropping message");
  139. return false;
  140. }
  141. serializer.Serialize(*m_componentInputs[i], "ComponentInput");
  142. }
  143. m_wasAttached = true;
  144. }
  145. else
  146. {
  147. AZ_Assert(m_wasAttached, "AttachNetSystemComponent was never called for NetworkInput");
  148. // We assume that the order of the network inputs is fixed between the server and client
  149. for (auto& componentInput : m_componentInputs)
  150. {
  151. NetComponentId componentId = componentInput->GetNetComponentId();
  152. serializer.Serialize(componentId, "ComponentId");
  153. serializer.Serialize(*componentInput, "ComponentInput");
  154. }
  155. }
  156. return true;
  157. }
  158. const IMultiplayerComponentInput* NetworkInput::FindComponentInput(NetComponentId componentId) const
  159. {
  160. // linear search since we expect to have very few components
  161. for (auto& componentInput : m_componentInputs)
  162. {
  163. if (componentInput->GetNetComponentId() == componentId)
  164. {
  165. return componentInput.get();
  166. }
  167. }
  168. return nullptr;
  169. }
  170. IMultiplayerComponentInput* NetworkInput::FindComponentInput(NetComponentId componentId)
  171. {
  172. const NetworkInput* tmp = this;
  173. return const_cast<IMultiplayerComponentInput*>(tmp->FindComponentInput(componentId));
  174. }
  175. void NetworkInput::CopyInternal(const NetworkInput& rhs)
  176. {
  177. m_inputId = rhs.m_inputId;
  178. m_hostFrameId = rhs.m_hostFrameId;
  179. m_hostTimeMs = rhs.m_hostTimeMs;
  180. m_hostBlendFactor = rhs.m_hostBlendFactor;
  181. m_componentInputs.resize(rhs.m_componentInputs.size());
  182. for (int32_t i = 0; i < rhs.m_componentInputs.size(); ++i)
  183. {
  184. const NetComponentId rhsComponentId = rhs.m_componentInputs[i]->GetNetComponentId();
  185. if (m_componentInputs[i] == nullptr || m_componentInputs[i]->GetNetComponentId() != rhsComponentId)
  186. {
  187. m_componentInputs[i] = AZStd::move(GetMultiplayerComponentRegistry()->AllocateComponentInput(rhsComponentId));
  188. }
  189. *(m_componentInputs[i]) = *(rhs.m_componentInputs[i]);
  190. }
  191. m_wasAttached = rhs.m_wasAttached;
  192. }
  193. }