Integrating up through commit 90f050496
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
{% set Namespace = dataFiles[0].attrib['Namespace'] %}
|
||||
namespace {{ Namespace }}
|
||||
{
|
||||
enum class ComponentTypes
|
||||
{
|
||||
{% for Component in dataFiles %}
|
||||
{% set ComponentName = Component.attrib['Name'] %}
|
||||
{{ ComponentName }},
|
||||
{% endfor %}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
{% macro UpperFirst(text) %}{{ text[0] | upper}}{{ text[1:] }}{% endmacro %}
|
||||
{% macro LowerFirst(text) %}{{ text[0] | lower}}{{ text[1:] }}{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro ParseRpcParams(property, outNames, outTypes, outDefines, use_default_value=False) -%}
|
||||
{%- for Param in property.iter('Param') -%}
|
||||
{%- do outNames.append(Param.attrib['Name']) -%}
|
||||
{%- do outTypes.append(Param.attrib['Type']) -%}
|
||||
{%- if use_default_value and Param.attrib['DefaultValue'] -%}
|
||||
{%- do outDefines.append('const ' ~ Param.attrib['Type'] ~ '& ' + Param.attrib['Name'] + ' = ' + Param.attrib['DefaultValue']) -%}
|
||||
{%- else -%}
|
||||
{%- do outDefines.append('const ' ~ Param.attrib['Type'] ~ '& ' ~ Param.attrib['Name']) -%}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro ParseIncludes(Component) -%}
|
||||
{%- for Include in Component.iter('Include') -%}
|
||||
{{ caller(Include) -}}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro ParseNetworkInputs(Component) -%}
|
||||
{%- for NetworkInput in Component.iter('NetworkInput') -%}
|
||||
{{ caller(NetworkInput) -}}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro ParseArchetypeProperties(Component) -%}
|
||||
{%- for ArchetypeProperty in Component.iter('ArchetypeProperty') -%}
|
||||
{{ caller(ArchetypeProperty) -}}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) -%}
|
||||
{%- for NetworkProperty in Component.iter('NetworkProperty') -%}
|
||||
{%- if NetworkProperty.attrib['ReplicateFrom'] == ReplicateFrom and NetworkProperty.attrib['ReplicateTo'] == ReplicateTo -%}
|
||||
{{ caller(NetworkProperty) -}}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro ParseRemoteProcedures(Component, InvokeFrom, HandleOn) -%}
|
||||
{%- for RemoteProcedure in Component.iter('RemoteProcedure') -%}
|
||||
{%- if RemoteProcedure.attrib['InvokeFrom'] == InvokeFrom and RemoteProcedure.attrib['HandleOn'] == HandleOn -%}
|
||||
{{ caller(RemoteProcedure) -}}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetNetPropertiesClassName(Component, ClassType) -%}
|
||||
{{ Component.attrib['Name'] }}{{ ClassType }}NetProperties
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetNetPropertiesDirtyEnumName(Component, ClassType, ReplicateFrom, ReplicateTo) -%}
|
||||
{{ ReplicateFrom }}To{{ ReplicateTo }}DirtyEnum
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetNetPropertiesPropertyDirtyEnum(Property) -%}
|
||||
{{ Property.attrib['Name'] }}_DirtyFlag
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetNetPropertiesQualifiedPropertyDirtyEnum(Component, ClassType, ReplicateFrom, ReplicateTo, Property) -%}
|
||||
{{ GetNetPropertiesDirtyEnumName(Component, ClassType, ReplicateFrom, ReplicateTo) }}::{{ GetNetPropertiesPropertyDirtyEnum(Property) }}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetModelClassName(Component, ClassType) -%}
|
||||
{{ Component.attrib['Name'] }}Model{{ ClassType }}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetArchetypeClassName(Entity, ClassType) -%}
|
||||
{{ Entity.attrib['Name'] }}Archetype{{ ClassType }}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetNetPropertiesSetName(ReplicateFrom, ReplicateTo) -%}
|
||||
{{ ReplicateFrom }}To{{ ReplicateTo }}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetModelReplicationRecordName(Component, ClassType) -%}
|
||||
{{ Component.attrib['Name'] }}{{ ClassType }}ReplicationRecord
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetComponentDeltaName(Component, ClassType) -%}
|
||||
{{ Component.attrib['Name'] }}Delta{{ ClassType }}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetNetworkPropertyEventType(Property) -%}
|
||||
AZ::Event<{{ Property.attrib['Type'] }}>
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetEntityClassName(Entity, ClassType) -%}
|
||||
{{ Entity.attrib['Name'] }}{{ ClassType }}
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetEntityReplicatorName(Entity, ClassType) -%}
|
||||
{{ Entity.attrib['Name'] }}{{ ClassType }}Replicator
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetEntityReplicationRecordName(Entity) -%}
|
||||
{{ Entity.attrib['Name'] }}ReplicationRecord
|
||||
{%- endmacro -%}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DefineNetworkPropertyReflection(Component, ReplicateFrom, ReplicateTo, ClassName) %}
|
||||
{% call(Property) ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% if Property.attrib['ExposeToEditor'] | booleanTrue %}
|
||||
->Field("{{ Property.attrib['Name'] }}", &{{ ClassName }}::m_{{ LowerFirst(Property.attrib['Name']) }})
|
||||
{% endif %}
|
||||
{% endcall -%}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DefineArchetypePropertyReflection(Component, ClassName) %}
|
||||
{% call(Property) ParseArchetypeProperties(Component) %}
|
||||
{% if Property.attrib['ExposeToEditor'] | booleanTrue %}
|
||||
->Field("{{ Property.attrib['Name'] }}", &{{ ClassName }}::m_{{ LowerFirst(Property.attrib['Name']) }})
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DefineNetworkPropertyConstructors(Component, ReplicateFrom, ReplicateTo, ClassType) %}
|
||||
{% call(Property) ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
, m_{{ LowerFirst(Property.attrib['Name']) }}({% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{{ Property.attrib['Type'] }}, Multiplayer::RewindHistorySize>({% endif %}{{ Property.attrib['Init'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, this){% endif %})
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
, m_{{ LowerFirst(Property.attrib['Name']) }}({{ Property.attrib['Init'] }})
|
||||
{% elif Property.attrib['IsRewindable']|booleanTrue %}
|
||||
, m_{{ LowerFirst(Property.attrib['Name']) }}({{ Property.attrib['Init'] }}, this)
|
||||
{% else %}
|
||||
, m_{{ LowerFirst(Property.attrib['Name']) }}({{ Property.attrib['Init'] }})
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DefineArchetypePropertyConstructors(Component) %}
|
||||
{% call(Property) ParseArchetypeProperties(Component) %}
|
||||
{% if Property.attrib['Container'] == 'Vector' %}
|
||||
, m_{{ LowerFirst(Property.attrib['Name']) }}({{ Property.attrib['Init'] }}, {{ Property.attrib['Count'] }})
|
||||
{% else %}
|
||||
, m_{{ LowerFirst(Property.attrib['Name']) }}({{ Property.attrib['Init'] }})
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro ParseComponentServiceTypeAndName(Component) %}
|
||||
{% for Service in Component.iter('ComponentRelation') %}
|
||||
{% if Service.attrib['Constraint'] != 'Incompatible' %}
|
||||
{% set Type = Service.attrib['Namespace'] + "::" + Service.attrib['Name'] %}
|
||||
{% set Name = 'm_' + LowerFirst(Service.attrib['Name']) %}
|
||||
{{ caller(Type, Name) -}}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro GetRpcEventAccessorName(InvokeFrom, HandleOn) -%}
|
||||
{{ "GetRpc" + InvokeFrom + "To" + HandleOn + "Event" }}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareRpcHandler(Property, HandleOn, IsOverride) %}
|
||||
{% set paramNames = [] %}
|
||||
{% set paramTypes = [] %}
|
||||
{% set paramDefines = [] %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{{ ParseRpcParams(Property, paramNames, paramTypes, paramDefines) }}
|
||||
{% if IsOverride %}
|
||||
void Handle{{ PropertyName }}({{ ', '.join(paramDefines) }}) override {}
|
||||
{% else %}
|
||||
//! {{ PropertyName }} Handler
|
||||
//! {{ Property.attrib['Description'] }}
|
||||
//! HandleOn {{ HandleOn }}
|
||||
virtual void Handle{{ PropertyName }}({{ ', '.join(paramDefines) }}) = 0;
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareRpcHandlers(Component, InvokeFrom, HandleOn, IsOverride) %}
|
||||
{% call(Property) ParseRemoteProcedures(Component, InvokeFrom, HandleOn) %}
|
||||
{{- DeclareRpcHandler(Property, HandleOn, IsOverride) -}}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{%- macro EmitDerivedClassesComment(dataFileNames, Component, ComponentName, ComponentNameBase, ComponentDerived, ControllerName, ControllerNameBase, ControllerDerived, NetworkInputCount) -%}
|
||||
{% if ComponentDerived or ControllerDerived %}
|
||||
/*
|
||||
/// You may use the classes below as a basis for your new derived classes. Derived classes must be marked in {{ (dataFileNames[0] | basename) }}
|
||||
/// Place in your .h
|
||||
#pragma once
|
||||
|
||||
#include <Source/AutoGen/{{ ComponentName }}.AutoComponent.h>
|
||||
|
||||
namespace {{ Component.attrib['Namespace'] }}
|
||||
{
|
||||
{% if ComponentDerived %}
|
||||
class {{ ComponentName }}
|
||||
: public {{ ComponentNameBase }}
|
||||
{
|
||||
public:
|
||||
AZ_MULTIPLAYER_COMPONENT({{ Component.attrib['Namespace'] }}::{{ ComponentName }}, s_{{ LowerFirst(ComponentName) }}ConcreteUuid, {{ Component.attrib['Namespace'] }}::{{ ComponentNameBase }});
|
||||
|
||||
static void Reflect([[maybe_unused]] AZ::ReflectContext* context);
|
||||
|
||||
void OnInit() override {}
|
||||
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
|
||||
{{ DeclareRpcHandlers(Component, 'Authority', 'Client', true)|indent(8) }}
|
||||
};
|
||||
{% endif %}
|
||||
|
||||
{% if ControllerDerived %}
|
||||
class {{ ControllerName }}
|
||||
: public {{ ControllerNameBase }}
|
||||
{
|
||||
public:
|
||||
{{ ControllerName }}({{ ComponentName }}& parent) : {{ ControllerNameBase }}(parent) {}
|
||||
|
||||
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
{% if NetworkInputCount > 0 %}
|
||||
//! Common input processing logic for the NetworkInput.
|
||||
//! @param input input structure to process
|
||||
//! @param deltaTime amount of time to integrate the provided inputs over
|
||||
void ProcessInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) override {}
|
||||
{%endif %}
|
||||
{{ DeclareRpcHandlers(Component, 'Server', 'Authority', true)|indent(8) }}
|
||||
{{ DeclareRpcHandlers(Component, 'Client', 'Authority', true)|indent(8) }}
|
||||
{{ DeclareRpcHandlers(Component, 'Autonomous', 'Authority', true)|indent(8) }}
|
||||
{{ DeclareRpcHandlers(Component, 'Authority', 'Autonomous', true)|indent(8) }}
|
||||
};
|
||||
{% endif %}
|
||||
}
|
||||
{% if ComponentDerived %}
|
||||
/// Place in your .cpp
|
||||
namespace {{ Component.attrib['Namespace'] }}
|
||||
{
|
||||
void {{ ComponentName }}::{{ ComponentName }}::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<{{ ComponentName }}, {{ ComponentNameBase }}>()
|
||||
->Version(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
*/
|
||||
{% else %}
|
||||
// NOTE:
|
||||
// No component roles have been overridden. You can modify {{ (dataFileNames[0] | basename) }} to specify derived classes for your desired network role.
|
||||
// Once your modifications are complete, build the game.
|
||||
// Your build will fail, but this comment will be replaced with a stub that can be used as the basis for your derived component roles.
|
||||
{% endif %}
|
||||
{%- endmacro -%}
|
||||
@@ -0,0 +1,479 @@
|
||||
{% import 'AutoComponent_Common.jinja' as AutoComponentMacros %}
|
||||
{% macro UpperFirst(text) %}{{ text[0] | upper}}{{ text[1:] }}{% endmacro %}
|
||||
{% macro LowerFirst(text) %}{{ text[0] | lower}}{{ text[1:] }}{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareNetworkPropertyGetter(Property) %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
{% if Property.attrib['GenerateEventBindings']|booleanTrue %}
|
||||
void {{ PropertyName }}AddEvent(AZ::Event<int32_t, {{ Property.attrib['Type'] }}>::Handler& handler);
|
||||
{% endif %}
|
||||
const AZStd::array<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::k_RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Array() const;
|
||||
const {{ Property.attrib['Type'] }} &Get{{ PropertyName }}(int32_t index) const;
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
{% if Property.attrib['GenerateEventBindings']|booleanTrue %}
|
||||
void {{ PropertyName }}AddEvent(AZ::Event<int32_t, {{ Property.attrib['Type'] }}>::Handler& handler);
|
||||
void {{ PropertyName }}SizeChangedAddEvent(AZ::Event<uint32_t>::Handler& handler);
|
||||
{% endif %}
|
||||
const AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Vector() const;
|
||||
const {{ Property.attrib['Type'] }} &Get{{ PropertyName }}(int32_t index) const;
|
||||
const {{ Property.attrib['Type'] }} &{{ PropertyName }}GetBack() const;
|
||||
uint32_t {{ PropertyName }}GetSize() const;
|
||||
{% else %}
|
||||
{% if Property.attrib['GenerateEventBindings']|booleanTrue %}
|
||||
void {{ PropertyName }}AddEvent(AZ::Event<{{ Property.attrib['Type'] }}>::Handler& handler);
|
||||
{% endif %}
|
||||
const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}() const;
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareNetworkPropertySetter(Property) %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{% if Property.attrib['IsPredictable'] | booleanTrue %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
void Set{{ PropertyName }}(const Multiplayer::NetworkInput&, int32_t index, const {{ Property.attrib['Type'] }}& value);
|
||||
{{ Property.attrib['Type'] }}& Modify{{ PropertyName }}(const Multiplayer::NetworkInput&, int32_t index);
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
void Set{{ PropertyName }}(const Multiplayer::NetworkInput&, int32_t index, const {{ Property.attrib['Type'] }}& value);
|
||||
{{ Property.attrib['Type'] }}& Modify{{ PropertyName }}(const Multiplayer::NetworkInput&, int32_t index);
|
||||
bool {{ PropertyName }}PushBack(const Multiplayer::NetworkInput&, const {{ Property.attrib['Type'] }}& value);
|
||||
bool {{ PropertyName }}PopBack(const Multiplayer::NetworkInput&);
|
||||
void {{ PropertyName }}Clear(const Multiplayer::NetworkInput&);
|
||||
{% elif Property.attrib['Container'] == 'Object' %}
|
||||
void Set{{ PropertyName }}(const Multiplayer::NetworkInput&, const {{ Property.attrib['Type'] }}& value);
|
||||
{{ Property.attrib['Type'] }}& Modify{{ PropertyName }}(const Multiplayer::NetworkInput&);
|
||||
{% else %}
|
||||
void Set{{ PropertyName }}(const Multiplayer::NetworkInput&, const {{ Property.attrib['Type'] }}& value);
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareNetworkPropertyGetters(Component, ReplicateFrom, ReplicateTo, IsProtected) %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{% if Property.attrib['IsPublic'] | booleanTrue != IsProtected %}
|
||||
//! {{ PropertyName }} Accessors
|
||||
//! {{ Property.attrib['Description'] }}.
|
||||
{{ DeclareNetworkPropertyGetter(Property) }}
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareArchetypePropertyGetter(Property) %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
const AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& Get{{ PropertyName }}Array() const;
|
||||
const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}(int32_t index) const;
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
const AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& Get{{ PropertyName }}Vector() const;
|
||||
const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}(int32_t index) const;
|
||||
const {{ Property.attrib['Type'] }}& {{ PropertyName }}GetBack() const;
|
||||
uint32_t {{ PropertyName }}GetSize() const;
|
||||
const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}() const;
|
||||
{% else %}
|
||||
const {{ Property.attrib['Type'] }}& Get{{ PropertyName }}() const;
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareArchetypePropertyGetters(Component) %}
|
||||
{% call(Property) AutoComponentMacros.ParseArchetypeProperties(Component) %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
//! Get{{ PropertyName }}
|
||||
//! {{ Property.attrib['Description'] }}.
|
||||
{{ DeclareArchetypePropertyGetter(Property) }}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareNetworkPropertyAccessors(Component, ReplicateFrom, ReplicateTo, IsProtected) %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{% if Property.attrib['IsPublic'] | booleanTrue != IsProtected %}
|
||||
//! {{ PropertyName }} Accessors
|
||||
//! {{ Property.attrib['Description'] }}.
|
||||
{{ DeclareNetworkPropertyGetter(Property) -}}
|
||||
{{ DeclareNetworkPropertySetter(Property) }}
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareRpcInvocation(Property, HandleOn) %}
|
||||
{% set paramNames = [] %}
|
||||
{% set paramTypes = [] %}
|
||||
{% set paramDefines = [] %}
|
||||
{% set PropertyName = UpperFirst(Property.attrib['Name']) %}
|
||||
{{ AutoComponentMacros.ParseRpcParams(Property, paramNames, paramTypes, paramDefines, true) }}
|
||||
//! {{ PropertyName }} Invocation
|
||||
//! {{ Property.attrib['Description'] }}
|
||||
//! HandleOn {{ HandleOn }}
|
||||
void {{ PropertyName }}({{ ', '.join(paramDefines) }});
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareRpcInvocations(Component, Section, HandleOn, ProctectedSection) %}
|
||||
{% call(Property) AutoComponentMacros.ParseRemoteProcedures(Component, Section, HandleOn) %}
|
||||
{% if Property.attrib['IsPublic']|booleanTrue == ProctectedSection %}
|
||||
{{- DeclareRpcInvocation(Property, HandleOn) -}}
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareNetworkPropertyEvents(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
{% if Property.attrib['GenerateEventBindings']|booleanTrue %}
|
||||
AZ::Event<int32_t, {{ Property.attrib['Type'] }}> m_{{ LowerFirst(Property.attrib['Name']) }}Event;
|
||||
{% endif %}
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
{% if Property.attrib['GenerateEventBindings']|booleanTrue %}
|
||||
AZ::Event<int32_t, {{ Property.attrib['Type'] }}> m_{{ LowerFirst(Property.attrib['Name']) }}Event;
|
||||
AZ::Event<uint32_t> m_{{ LowerFirst(Property.attrib['Name']) }}SizeChangedEvent;
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if Property.attrib['GenerateEventBindings']|booleanTrue %}
|
||||
AZ::Event<{{ Property.attrib['Type'] }}> m_{{ LowerFirst(Property.attrib['Name']) }}Event;
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareNetworkPropertyVars(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
AZStd::array<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> m_{{ Property.attrib['Name'] }};
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }};
|
||||
{% elif Property.attrib['IsRewindable']|booleanTrue %}
|
||||
Multiplayer::RewindableObject<{{ Property.attrib['Type'] }}, Multiplayer::RewindHistorySize> m_{{ LowerFirst(Property.attrib['Name']) }} = {{ Property.attrib['Init'] }};
|
||||
{% else %}
|
||||
{{ Property.attrib['Type'] }} m_{{ LowerFirst(Property.attrib['Name']) }} = {{ Property.attrib['Init'] }};
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
{% macro DeclareArchetypePropertyVars(Component) %}
|
||||
{% call(Property) AutoComponentMacros.ParseArchetypeProperties(Component) %}
|
||||
{% if Property.attrib['Container'] == 'Array' %}
|
||||
AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }};
|
||||
{% elif Property.attrib['Container'] == 'Vector' %}
|
||||
AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }};
|
||||
{% else %}
|
||||
{{ Property.attrib['Type'] }} m_{{ LowerFirst(Property.attrib['Name']) }};
|
||||
{% endif %}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
{#
|
||||
|
||||
#}
|
||||
#pragma once
|
||||
|
||||
{% for Component in dataFiles %}
|
||||
{% set ComponentName = Component.attrib['Name'] %}
|
||||
{% set ComponentBaseName = ComponentName %}
|
||||
{% set ComponentDerived = Component.attrib['OverrideComponent']|booleanTrue %}
|
||||
{% set ControllerDerived = Component.attrib['OverrideController']|booleanTrue %}
|
||||
{% if ComponentDerived %}
|
||||
{% set ComponentBaseName = ComponentName + "Base" %}
|
||||
{% endif %}
|
||||
{% set ControllerName = ComponentName + "Controller" %}
|
||||
{% set ControllerBaseName = ControllerName %}
|
||||
{% if ControllerDerived %}
|
||||
{% set ControllerBaseName = ControllerName + "Base" %}
|
||||
{% endif %}
|
||||
{% set NetworkInputCount = Component.findall('NetworkInput') | len %}
|
||||
{% set NetworkPropertyCount = Component.findall('NetworkProperty') | len %}
|
||||
{% set RpcCount = Component.findall('RemoteProcedure') | len %}
|
||||
#include "AutoComponentTypes.h"
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzNetworking/DataStructures/FixedSizeBitsetView.h>
|
||||
#include <Source/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Source/NetworkEntity/EntityReplication/ReplicationRecord.h>
|
||||
#include <Source/Components/MultiplayerComponent.h>
|
||||
#include <Source/Components/MultiplayerController.h>
|
||||
#include <Source/NetworkInput/IMultiplayerComponentInput.h>
|
||||
#include <Source/NetworkTime/RewindableObject.h>
|
||||
#include <Source/MultiplayerTypes.h>
|
||||
{% call(Include) AutoComponentMacros.ParseIncludes(Component) %}
|
||||
#include <{{ Include.attrib['File'] }}>
|
||||
{% endcall %}
|
||||
|
||||
{% for Service in Component.iter('ComponentRelation') %}
|
||||
{% if Service.attrib['Constraint'] != 'Incompatible' %}
|
||||
namespace {{ Service.attrib['Namespace'] }}
|
||||
{
|
||||
class {{ Service.attrib['Name'] }};
|
||||
{% if Service.attrib['HasController']|booleanTrue %}
|
||||
class {{ Service.attrib['Name'] }}Controller;
|
||||
{% endif %}
|
||||
}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{{ AutoComponentMacros.EmitDerivedClassesComment(dataFileNames, Component, ComponentName, ComponentBaseName, ComponentDerived, ControllerName, ControllerBaseName, ControllerDerived, NetworkInputCount) }}
|
||||
namespace {{ Component.attrib['Namespace'] }}
|
||||
{
|
||||
//! Forward declarations
|
||||
class {{ ComponentName }};
|
||||
class {{ ControllerName }};
|
||||
|
||||
//! Returns a human readable name for the provided remoteProcedureId.
|
||||
const char* GetRemoteProcedureName(uint16_t remoteProcedureId);
|
||||
|
||||
{% set RecordName = ComponentName + "Record" %}
|
||||
//! @class {{RecordName }}
|
||||
//! @brief A record of the changed bits in the NetworkProperties for component {{ ComponentName }}.
|
||||
class {{ RecordName }}
|
||||
{
|
||||
public:
|
||||
//! AllocateRecord
|
||||
//! Allocates and returns a new record. Will reserve storage in the provided ReplicationRecord.
|
||||
static AZStd::unique_ptr<{{ RecordName }}> AllocateRecord(Multiplayer::ReplicationRecord& replicationRecord);
|
||||
|
||||
//! CanAttachRecord
|
||||
//! Returns a true if we can attach a {{ ClassType }}Record to the ReplicationRecord.
|
||||
static bool CanAttachRecord(Multiplayer::ReplicationRecord& replicationRecord);
|
||||
|
||||
//! AttachRecord
|
||||
//! Returns a {{ ClassType }}Record that has been attached to the ReplicationRecord. This will consume bits in the provided ReplicationRecord.
|
||||
static {{ RecordName }} AttachRecord(Multiplayer::ReplicationRecord& replicationRecord);
|
||||
|
||||
//! SetPredictableBits
|
||||
//! Sets the bits in the attached record that correspond to predictable network properties.
|
||||
void SetPredictableBits();
|
||||
|
||||
{% set networkPropertyCount = {'value' : 0} %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, 'Authority', 'Client') %}
|
||||
{%- if networkPropertyCount.update({'value': networkPropertyCount.value + 1}) %}{% endif -%}
|
||||
{% endcall %}
|
||||
{% if networkPropertyCount.value > 0 %}
|
||||
AzNetworking::FixedSizeBitsetView m_authorityToClient;
|
||||
{% endif %}
|
||||
{% set networkPropertyCount = {'value' : 0} %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, 'Authority', 'Server') %}
|
||||
{%- if networkPropertyCount.update({'value': networkPropertyCount.value + 1}) %}{% endif -%}
|
||||
{% endcall %}
|
||||
{% if networkPropertyCount.value > 0 %}
|
||||
AzNetworking::FixedSizeBitsetView m_authorityToServer};
|
||||
{% endif %}
|
||||
{% set networkPropertyCount = {'value' : 0} %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, 'Authority', 'Autonomous') %}
|
||||
{%- if networkPropertyCount.update({'value': networkPropertyCount.value + 1}) %}{% endif -%}
|
||||
{% endcall %}
|
||||
{% if networkPropertyCount.value > 0 %}
|
||||
AzNetworking::FixedSizeBitsetView m_authorityToAutonomous;
|
||||
{% endif %}
|
||||
{% set networkPropertyCount = {'value' : 0} %}
|
||||
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, 'Autonomous', 'Authority') %}
|
||||
{%- if networkPropertyCount.update({'value': networkPropertyCount.value + 1}) %}{% endif -%}
|
||||
{% endcall %}
|
||||
{% if networkPropertyCount.value > 0 %}
|
||||
AzNetworking::FixedSizeBitsetView m_autonomousToAuthority;
|
||||
{% endif %}
|
||||
|
||||
private:
|
||||
{{ RecordName }}
|
||||
(
|
||||
Multiplayer::ReplicationRecord& replicationRecord,
|
||||
uint32_t authorityToClientSimluationStartOffset,
|
||||
uint32_t authorityToServerSimluationStartOffset,
|
||||
uint32_t authorityToAutonomousStartOffset,
|
||||
uint32_t autonomousToAuthorityStartOffset
|
||||
);
|
||||
};
|
||||
|
||||
{% if NetworkInputCount > 0 %}
|
||||
class NetworkInput
|
||||
: public Multiplayer::IMultiplayerComponentInput
|
||||
{
|
||||
public:
|
||||
static const Multiplayer::NetComponentId s_componentId = static_cast<Multiplayer::NetComponentId>({{ Component.attrib['Namespace'] }}::ComponentTypes::{{ Component.attrib['Name'] }});
|
||||
Multiplayer::NetComponentId GetComponentId() const override;
|
||||
INetworkInput& operator=(const INetworkInput& rhs) override;
|
||||
bool Serialize(AzNetworking::ISerializer& serializer);
|
||||
|
||||
{% call(Input) AutoComponentMacros.ParseNetworkInputs(Component) %}
|
||||
{{ Input.attrib['Type'] }} m_{{ LowerFirst(Input.attrib['Name']) }} = {{ Input.attrib['Type'] }}({{ Input.attrib['Init'] }});
|
||||
{% endcall %}
|
||||
};
|
||||
|
||||
{% endif %}
|
||||
class {{ ControllerBaseName }}{% if not ControllerDerived %} final{% endif %}{{ "" }}
|
||||
: public Multiplayer::MultiplayerController
|
||||
{
|
||||
public:
|
||||
{{ ControllerBaseName }}({{ ComponentName }}& owner);
|
||||
~{{ ControllerBaseName }}() override = default;
|
||||
|
||||
void NetworkAttach(Multiplayer::NetBindComponent* netBindComponent, Multiplayer::ReplicationRecord& predictableEntityRecord);
|
||||
|
||||
void Activate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void Deactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
const {{ ComponentName }}& GetParent() const;
|
||||
{{ ComponentName }}& GetParent();
|
||||
|
||||
{% if ControllerDerived %}
|
||||
virtual void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) = 0;
|
||||
virtual void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) = 0;
|
||||
|
||||
{% endif %}
|
||||
//! MultiplayerController interface
|
||||
//! @{
|
||||
Multiplayer::MultiplayerController::InputPriorityOrder GetInputOrder() const override { return Multiplayer::MultiplayerController::InputPriorityOrder::Default; }
|
||||
AZ::Aabb GetRewindBoundsForInput([[maybe_unused]] const NetworkInput& networkInput, [[maybe_unused]] float deltaTime) const override { return AZ::Aabb::CreateNull(); }
|
||||
void CreateInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) override {}
|
||||
void ProcessInput([[maybe_unused]] Multiplayer::NetworkInput& input, [[maybe_unused]] float deltaTime) override {}
|
||||
//! @}
|
||||
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Authority', 'Server', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Authority', 'Client', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyAccessors(Component, 'Authority', 'Autonomous', false)|indent(8) }}
|
||||
{{ DeclareArchetypePropertyGetters(Component)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', false)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', true)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Client', 'Authority', false)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Client', 'Authority', true)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Autonomous', 'Authority', false)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Autonomous', 'Authority', true)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Authority', 'Autonomous', false)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Authority', 'Autonomous', true)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Authority', 'Client', false)|indent(8) }}
|
||||
{{ DeclareRpcInvocations(Component, 'Authority', 'Client', true)|indent(8) }}
|
||||
{{ AutoComponentMacros.DeclareRpcHandlers(Component, 'Server', 'Authority', false)|indent(8) }}
|
||||
{{ AutoComponentMacros.DeclareRpcHandlers(Component, 'Client', 'Authority', false)|indent(8) }}
|
||||
{{ AutoComponentMacros.DeclareRpcHandlers(Component, 'Autonomous', 'Authority', false)|indent(8) }}
|
||||
{{ AutoComponentMacros.DeclareRpcHandlers(Component, 'Authority', 'Autonomous', false)|indent(8) }}
|
||||
{% for Service in Component.iter('ComponentRelation') %}
|
||||
{% if (Service.attrib['HasController']|booleanTrue) and (Service.attrib['Constraint'] != 'Incompatible') %}
|
||||
{{ Service.attrib['Namespace'] }}::{{ Service.attrib['Name'] }}Controller* Get{{ Service.attrib['Name'] }}Controller();
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
};
|
||||
|
||||
static const AZ::Uuid s_{{ LowerFirst(ComponentName) }}ConcreteUuid = "{{ (ComponentName) | createHashGuid }}";
|
||||
class {{ ComponentBaseName }}{% if not ComponentDerived %} final{% endif %}{{ "" }}
|
||||
: public Multiplayer::MultiplayerComponent
|
||||
{
|
||||
friend class {{ ControllerName }};
|
||||
friend class {{ ControllerBaseName }};
|
||||
public:
|
||||
{% if ComponentDerived %}
|
||||
AZ_CLASS_ALLOCATOR({{ ComponentBaseName }}, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI({{ ComponentBaseName }}, s_{{ LowerFirst(ComponentName) }}ConcreteUuid, AZ::Component);
|
||||
{% else %}
|
||||
AZ_MULTIPLAYER_COMPONENT({{ Component.attrib['Namespace'] }}::{{ ComponentBaseName }}, s_{{ LowerFirst(ComponentName) }}ConcreteUuid, Multiplayer::MultiplayerComponent);
|
||||
{% endif %}
|
||||
|
||||
static const Multiplayer::NetComponentId s_componentId = static_cast<Multiplayer::NetComponentId>({{ Component.attrib['Namespace'] }}::ComponentTypes::{{ Component.attrib['Name'] }});
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
|
||||
{{ ComponentBaseName }}() = default;
|
||||
~{{ ComponentBaseName }}() override = default;
|
||||
|
||||
void Init() override;
|
||||
void Activate() override;
|
||||
void Deactivate() override;
|
||||
{% if ComponentDerived %}
|
||||
virtual void OnInit() = 0;
|
||||
virtual void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) = 0;
|
||||
virtual void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) = 0;
|
||||
{% endif %}
|
||||
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Server', false)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Client', false)|indent(8) }}
|
||||
{{ DeclareArchetypePropertyGetters(Component)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', false)|indent(8) }}
|
||||
|
||||
//! MultiplayerComponent interface
|
||||
//! @{
|
||||
NetComponentId GetNetComponentId() const override;
|
||||
bool HandleRpcMessage(Multiplayer::NetEntityRole remoteRole, Multiplayer::NetworkEntityRpcMessage& rpcMessage) override;
|
||||
bool SerializeStateDeltaMessage(Multiplayer::ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer) override;
|
||||
void NotifyStateDeltaChanges(Multiplayer::ReplicationRecord& replicationRecord) override;
|
||||
|
||||
protected:
|
||||
bool HasController() const override;
|
||||
MultiplayerController* GetController() override;
|
||||
void ConstructController() override;
|
||||
void DestructController() override;
|
||||
void ActivateController(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void DeactivateController(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void NetworkAttach(Multiplayer::NetBindComponent* netBindComponent, Multiplayer::ReplicationRecord& currentEntityRecord, Multiplayer::ReplicationRecord& predictableEntityRecord) override;
|
||||
//! @}
|
||||
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Server', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Autonomous', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Autonomous', 'Authority', true)|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyGetters(Component, 'Authority', 'Client', true)|indent(8) -}}
|
||||
{{ DeclareRpcInvocations(Component, 'Server', 'Authority', true)|indent(8) -}}
|
||||
{{ AutoComponentMacros.DeclareRpcHandlers(Component, 'Authority', 'Client', false)|indent(8) }}
|
||||
{% for Service in Component.iter('ComponentRelation') %}
|
||||
{% if Service.attrib['Constraint'] != 'Incompatible' %}
|
||||
const {{ Service.attrib['Namespace'] }}::{{ Service.attrib['Name'] }}* Get{{ Service.attrib['Name'] }}() const;
|
||||
{{ Service.attrib['Namespace'] }}::{{ Service.attrib['Name'] }}* Get{{ Service.attrib['Name'] }}();
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
private:
|
||||
//! Authority to Client serializers
|
||||
bool SerializeAuthorityToClientProperties({{ RecordName }}& replicationRecord, AzNetworking::ISerializer& serializer);
|
||||
void NotifyChangesAuthorityToClientProperties(const {{ RecordName }}& replicationRecord) const;
|
||||
|
||||
//! Authority To Server serializers
|
||||
bool SerializeAuthorityToServerProperties({{ RecordName }}& replicationRecord, AzNetworking::ISerializer& serializer);
|
||||
void NotifyChangesAuthorityToServerProperties(const {{ RecordName }}& replicationRecord) const;
|
||||
|
||||
//! Authority To Autonomous serializers
|
||||
bool SerializeAuthorityToAutonomousProperties({{ RecordName }}& replicationRecord, AzNetworking::ISerializer& serializer);
|
||||
void NotifyChangesAuthorityToAutonomousProperties(const {{ RecordName }}& replicationRecord) const;
|
||||
|
||||
//! Autonomous To Authority serializers
|
||||
bool SerializeAutonomousToAuthorityProperties({{ RecordName }}& replicationRecord, AzNetworking::ISerializer& serializer);
|
||||
void NotifyChangesAutonomousToAuthorityProperties(const {{ RecordName }}& replicationRecord) const;
|
||||
|
||||
AZStd::unique_ptr<{{ RecordName }}> m_currentRecord;
|
||||
AZStd::unique_ptr<{{ ControllerName }}> m_controller;
|
||||
|
||||
//! Network Properties
|
||||
{{ DeclareNetworkPropertyVars(Component, 'Authority', 'Server')|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyVars(Component, 'Authority', 'Client')|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyVars(Component, 'Authority', 'Autonomous')|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyVars(Component, 'Autonomous', 'Authority')|indent(8) }}
|
||||
//! NetworkProperty Events
|
||||
{{ DeclareNetworkPropertyEvents(Component, 'Authority', 'Server')|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyEvents(Component, 'Authority', 'Client')|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyEvents(Component, 'Authority', 'Autonomous')|indent(8) -}}
|
||||
{{ DeclareNetworkPropertyEvents(Component, 'Autonomous', 'Authority')|indent(8) }}
|
||||
//! Archetype Properties
|
||||
{{ DeclareArchetypePropertyVars(Component)|indent(8) }}
|
||||
{% call(Type, Name) AutoComponentMacros.ParseComponentServiceTypeAndName(Component) %}
|
||||
{{ Type }}* {{ Name }} = nullptr;
|
||||
{% endcall %}
|
||||
};
|
||||
}
|
||||
{% endfor %}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,5 @@
|
||||
<Member Type="Multiplayer::NetEntityId" Name="entityId" Init="Multiplayer::InvalidNetEntityId" />
|
||||
<Member Type="Multiplayer::PrefabEntityId" Name="prefabEntityId" Init="" />
|
||||
<Member Type="AzNetworking::PacketEncodingBuffer" Name="propertyUpdateData" Init="" SuppressFromInitializerList="true" />
|
||||
<Member Type="AzNetworking::PacketEncodingBuffer" Name="migrationData" Init="" SuppressFromInitializerList="true" />
|
||||
</Packet>
|
||||
</PacketGroup>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<Component
|
||||
Name="NetworkTransformComponent"
|
||||
Namespace="Multiplayer"
|
||||
OverrideComponent="true"
|
||||
OverrideController="true"
|
||||
OverrideInclude="Source/Components/NetworkTransformComponent.h"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
|
||||
<ComponentRelation Constraint="Weak" HasController="false" Name="TransformComponent" Namespace="AzFramework" Include="AzFramework/Components/TransformComponent.h" />
|
||||
|
||||
<Include File="Source/MultiplayerTypes.h"/>
|
||||
|
||||
<NetworkProperty Type="AZ::Quaternion" Name="rotation" Init="AZ::Quaternion::CreateIdentity()" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="true" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="true" GenerateEventBindings="true" />
|
||||
<NetworkProperty Type="AZ::Vector3" Name="translation" Init="AZ::Vector3::CreateZero()" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="true" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="true" GenerateEventBindings="true" />
|
||||
<NetworkProperty Type="AZ::Vector3" Name="scale" Init="AZ::Vector3::CreateZero()" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="true" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="true" GenerateEventBindings="true" />
|
||||
<NetworkProperty Type="AZ::Vector3" Name="velocity" Init="AZ::Vector3::CreateZero()" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="true" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="true" GenerateEventBindings="true" />
|
||||
<NetworkProperty Type="uint8_t" Name="resetCount" Init="0" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="false" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="false" GenerateEventBindings="true" />
|
||||
<NetworkProperty Type="NetEntityId" Name="parentEntityId" Init="InvalidNetEntityId" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="true" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="false" GenerateEventBindings="true" />
|
||||
<NetworkProperty Type="int32_t" Name="parentAttachmentBoneId" Init="-1" ReplicateFrom="Authority" ReplicateTo="Client" IsRewindable="true" IsPredictable="true" IsPublic="true" Container="Object" ExposeToEditor="false" GenerateEventBindings="true" />
|
||||
|
||||
<ArchetypeProperty Type="bool" Name="snapToGround" Init="false" ExposeToEditor="true" />
|
||||
<ArchetypeProperty Type="bool" Name="useGroundNormal" Init="false" ExposeToEditor="true" />
|
||||
|
||||
<!--
|
||||
This is reference only, will be deleted when we make a better test component that exercizes all aspects of component autogen
|
||||
<RemoteProcedure Name="RPCServerToAuthorityPublic" InvokeFrom="Server" HandleOn="Authority" IsPublic="true" IsReliable="false" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RPCServerToAuthorityScriptProtected" InvokeFrom="Server" HandleOn="Authority" IsPublic="false" IsReliable="false" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RPCAutonomousToAuthorityPublic" InvokeFrom="Autonomous" HandleOn="Authority" IsPublic="true" IsReliable="false" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RPCAuthorityToAutonomousPublic" InvokeFrom="Authority" HandleOn="Autonomous" IsPublic="true" IsReliable="false" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RpcAuthorityToClientPublic" InvokeFrom="Authority" HandleOn="Client" IsPublic="true" IsReliable="false" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RpcAuthorityToClientProtected" InvokeFrom="Authority" HandleOn="Client" IsPublic="false" IsReliable="false" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RpcAuthorityToServerPublic" InvokeFrom="Authority" HandleOn="Server" IsPublic="true" IsReliable="true" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
<RemoteProcedure Name="RpcAuthorityToServerProtected" InvokeFrom="Authority" HandleOn="Server" IsPublic="false" IsReliable="true" Description="Description" >
|
||||
<Param Name="Test" Type="int" DefaultValue="0" Description="Description"/>
|
||||
</RemoteProcedure>
|
||||
-->
|
||||
</Component>
|
||||
@@ -58,4 +58,13 @@ namespace Multiplayer
|
||||
NetBindComponent* netBindComponent = GetNetBindComponent();
|
||||
return netBindComponent ? netBindComponent->GetEntityHandle() : NetworkEntityHandle();
|
||||
}
|
||||
|
||||
void MultiplayerComponent::MarkDirty()
|
||||
{
|
||||
NetBindComponent* netBindComponent = GetNetBindComponent();
|
||||
if (netBindComponent != nullptr)
|
||||
{
|
||||
netBindComponent->MarkDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,14 +14,15 @@
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzNetworking/Serialization/ISerializer.h>
|
||||
#include <AzNetworking/DataStructures/FixedSizeBitsetView.h>
|
||||
#include <Source/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Source/MultiplayerTypes.h>
|
||||
|
||||
//! Macro to declare bindings for a multiplayer component inheriting from MultiplayerComponent
|
||||
#define AZ_MULTIPLAYER_COMPONENT(ComponentClass, Guid) \
|
||||
AZ_RTTI(ComponentClass, Guid, AZ::Component) \
|
||||
AZ_COMPONENT_INTRUSIVE_DESCRIPTOR_TYPE(ComponentClass) \
|
||||
AZ_COMPONENT_BASE(ComponentClass, Guid, Multiplayer::MultiplayerComponent)
|
||||
#define AZ_MULTIPLAYER_COMPONENT(ComponentClass, Guid, Base) \
|
||||
AZ_RTTI(ComponentClass, Guid, AZ::Component) \
|
||||
AZ_COMPONENT_INTRUSIVE_DESCRIPTOR_TYPE(ComponentClass) \
|
||||
AZ_COMPONENT_BASE(ComponentClass, Guid, Base)
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
@@ -50,7 +51,7 @@ namespace Multiplayer
|
||||
NetBindComponent* GetNetBindComponent();
|
||||
//! @}
|
||||
|
||||
//! Linearly searches the components attached to the entity and returns the requested component. .
|
||||
//! Linearly searches the components attached to the entity and returns the requested component.
|
||||
//! @return the requested component, or nullptr if the component does not exist on the entity
|
||||
//! @{
|
||||
template <typename ComponentType>
|
||||
@@ -62,25 +63,22 @@ namespace Multiplayer
|
||||
NetEntityId GetNetEntityId() const;
|
||||
ConstNetworkEntityHandle GetEntityHandle() const;
|
||||
NetworkEntityHandle GetEntityHandle();
|
||||
void MarkDirty();
|
||||
|
||||
virtual NetComponentId GetNetComponentId() const = 0;
|
||||
|
||||
virtual bool HandleRpcMessage(NetEntityRole netEntityRole, NetworkEntityRpcMessage& rpcMessage) = 0;
|
||||
virtual bool SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer, ComponentSerializationType componentSerializationType) = 0;
|
||||
virtual void NotifyStateDeltaChanges(ReplicationRecord& replicationRecord, ComponentSerializationType componentSerializationType) = 0;
|
||||
virtual bool SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer) = 0;
|
||||
virtual void NotifyStateDeltaChanges(ReplicationRecord& replicationRecord) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool HasController() const = 0;
|
||||
virtual MultiplayerController* GetController() = 0;
|
||||
|
||||
virtual bool Migrate(AzNetworking::ISerializer& serializer) = 0;
|
||||
virtual void ConstructController() = 0;
|
||||
virtual void DestructController() = 0;
|
||||
virtual void ActivateController(EntityIsMigrating entityIsMigrating) = 0;
|
||||
virtual void DeactivateController(EntityIsMigrating entityIsMigrating) = 0;
|
||||
virtual void NetworkAttach(NetBindComponent& netBindComponent, ReplicationRecord& currentEntityRecord, ReplicationRecord& predictableEntityRecord) = 0;
|
||||
virtual void NetworkDetach() = 0;
|
||||
virtual void NetworkAttach(NetBindComponent* netBindComponent, ReplicationRecord& currentEntityRecord, ReplicationRecord& predictableEntityRecord) = 0;
|
||||
|
||||
mutable NetBindComponent* m_netBindComponent = nullptr;
|
||||
|
||||
@@ -100,4 +98,42 @@ namespace Multiplayer
|
||||
{
|
||||
return GetEntity()->FindComponent<ComponentType>();
|
||||
}
|
||||
|
||||
template <typename TYPE>
|
||||
inline void SerializeNetworkPropertyHelper
|
||||
(
|
||||
AzNetworking::ISerializer& serializer,
|
||||
bool modifyRecord,
|
||||
AzNetworking::FixedSizeBitsetView& bitset,
|
||||
int32_t bitIndex,
|
||||
TYPE& value,
|
||||
const char* name,
|
||||
[[maybe_unused]] NetComponentId componentId
|
||||
)
|
||||
{
|
||||
if (bitset.GetBit(bitIndex))
|
||||
{
|
||||
//uint32_t prevUpdateSize = serializer.GetSize();
|
||||
serializer.ClearTrackedChangesFlag();
|
||||
serializer.Serialize(value, name);
|
||||
if (modifyRecord && !serializer.GetTrackedChangesFlag())
|
||||
{
|
||||
bitset.SetBit(bitIndex, false);
|
||||
}
|
||||
//uint32_t postUpdateSize = serializer.GetSize();
|
||||
// Network Property metrics
|
||||
// uint32_t updateSize = (postUpdateSize - prevUpdateSize);
|
||||
// if (updateSize > 0)
|
||||
// {
|
||||
// if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
|
||||
// {
|
||||
// GetPacketHandlerMetricsInstance().LogRecvNetworkPropertyUpdates(componentType, name, updateSize);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GetPacketHandlerMetricsInstance().LogSentNetworkPropertyUpdates(componentType, name, updateSize);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,10 +52,19 @@ namespace Multiplayer
|
||||
return m_owner.GetNetBindComponent();
|
||||
}
|
||||
|
||||
const MultiplayerComponent& MultiplayerController::GetOwner() const
|
||||
{
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
MultiplayerComponent& MultiplayerController::GetOwner()
|
||||
{
|
||||
return m_owner;
|
||||
}
|
||||
|
||||
bool MultiplayerController::IsProcessingInput() const
|
||||
{
|
||||
//return m_owner.GetNetBindComponent()->IsProcessingInput();
|
||||
return false;
|
||||
return GetNetBindComponent()->IsProcessingInput();
|
||||
}
|
||||
|
||||
MultiplayerController* MultiplayerController::FindController(const AZ::Uuid& typeId, const NetworkEntityHandle& entityHandle) const
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Source/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
@@ -36,6 +37,12 @@ namespace Multiplayer
|
||||
MultiplayerController(MultiplayerComponent& owner);
|
||||
virtual ~MultiplayerController() = default;
|
||||
|
||||
//! Activates the controller.
|
||||
virtual void Activate(EntityIsMigrating entityIsMigrating) = 0;
|
||||
|
||||
//! Deactivates the controller.
|
||||
virtual void Deactivate(EntityIsMigrating entityIsMigrating) = 0;
|
||||
|
||||
//! Returns the networkId for the entity that owns this controller.
|
||||
//! @return the networkId for the entity that owns this controller
|
||||
NetEntityId GetNetEntityId() const;
|
||||
@@ -54,8 +61,18 @@ namespace Multiplayer
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns the NetBindComponent responsible for net binding for this controller
|
||||
//! @{
|
||||
const NetBindComponent* GetNetBindComponent() const;
|
||||
NetBindComponent* GetNetBindComponent();
|
||||
//! @}
|
||||
|
||||
//! Returns the MultiplayerComponent that owns this controller instance.
|
||||
//! @return the MultiplayerComponent that owns this controller instance
|
||||
//! @{
|
||||
const MultiplayerComponent& GetOwner() const;
|
||||
MultiplayerComponent& GetOwner();
|
||||
//! @}
|
||||
|
||||
//! Returns true if the owning entity is currently inside ProcessInput scope.
|
||||
bool IsProcessingInput() const;
|
||||
@@ -63,11 +80,11 @@ namespace Multiplayer
|
||||
//! Returns the input priority ordering for determining the order of ProcessInput or CreateInput functions.
|
||||
virtual InputPriorityOrder GetInputOrder() const = 0;
|
||||
|
||||
//! Hints the rewind system how close an entity should be in order to rewind, this can be very important for performance at scale.
|
||||
//! Queries the rewind system to determine what volume is relevent for a given input, this is very important for performance at scale.
|
||||
//! @param networkInput input structure to process
|
||||
//! @param deltaTime amount of time the provided input would be integrated over
|
||||
//! @return the maximum distance an entity should be for this component to interact with it given the provided input
|
||||
virtual float GetRewindDistanceForInput(const NetworkInput& networkInput, float deltaTime) const = 0;
|
||||
//! @return a world-space aabb representing the volume relevent to the provided input
|
||||
virtual AZ::Aabb GetRewindBoundsForInput(const NetworkInput& networkInput, float deltaTime) const = 0;
|
||||
|
||||
//! Base execution for ProcessInput packet, do not call directly.
|
||||
//! @param networkInput input structure to process
|
||||
|
||||
@@ -75,9 +75,9 @@ namespace Multiplayer
|
||||
void NetBindComponent::Activate()
|
||||
{
|
||||
m_needsToBeStopped = true;
|
||||
if (m_netEntityRole == NetEntityRole::ServerAuthority)
|
||||
if (m_netEntityRole == NetEntityRole::Authority)
|
||||
{
|
||||
m_handleLocalServerRpcMessageEventHandle.Connect(m_sendServerSimulationtoServerAuthorityRpcEvent);
|
||||
m_handleLocalServerRpcMessageEventHandle.Connect(m_sendServertoAuthorityRpcEvent);
|
||||
}
|
||||
if (NetworkRoleHasController(m_netEntityRole))
|
||||
{
|
||||
@@ -98,7 +98,6 @@ namespace Multiplayer
|
||||
{
|
||||
GetNetworkEntityManager()->NotifyControllersDeactivated(m_netEntityHandle, EntityIsMigrating::False);
|
||||
}
|
||||
NetworkDetach();
|
||||
}
|
||||
|
||||
NetEntityRole NetBindComponent::GetNetEntityRole() const
|
||||
@@ -108,13 +107,13 @@ namespace Multiplayer
|
||||
|
||||
bool NetBindComponent::IsAuthority() const
|
||||
{
|
||||
return (m_netEntityRole == NetEntityRole::ServerAuthority);
|
||||
return (m_netEntityRole == NetEntityRole::Authority);
|
||||
}
|
||||
|
||||
bool NetBindComponent::HasController() const
|
||||
{
|
||||
return (m_netEntityRole == NetEntityRole::ServerAuthority)
|
||||
|| (m_netEntityRole == NetEntityRole::ClientAutonomous);
|
||||
return (m_netEntityRole == NetEntityRole::Authority)
|
||||
|| (m_netEntityRole == NetEntityRole::Autonomous);
|
||||
}
|
||||
|
||||
NetEntityId NetBindComponent::GetNetEntityId() const
|
||||
@@ -160,7 +159,7 @@ namespace Multiplayer
|
||||
void NetBindComponent::CreateInput(NetworkInput& networkInput, float deltaTime)
|
||||
{
|
||||
// Only autonomous or authority runs this logic
|
||||
AZ_Assert(m_netEntityRole == NetEntityRole::ClientAutonomous || m_netEntityRole == NetEntityRole::ServerAuthority, "Incorrect network role for input creation");
|
||||
AZ_Assert(m_netEntityRole == NetEntityRole::Autonomous || m_netEntityRole == NetEntityRole::Authority, "Incorrect network role for input creation");
|
||||
for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector)
|
||||
{
|
||||
multiplayerComponent->GetController()->CreateInput(networkInput, deltaTime);
|
||||
@@ -177,15 +176,19 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
float NetBindComponent::GetRewindDistanceForInput(const NetworkInput& networkInput, float deltaTime) const
|
||||
AZ::Aabb NetBindComponent::GetRewindBoundsForInput(const NetworkInput& networkInput, float deltaTime) const
|
||||
{
|
||||
AZ_Assert(m_netEntityRole == NetEntityRole::ServerAuthority, "Incorrect network role for computing rewind distance");
|
||||
float rewindDistance = 0.0f;
|
||||
AZ_Assert(m_netEntityRole == NetEntityRole::Authority, "Incorrect network role for computing rewind bounds");
|
||||
AZ::Aabb bounds = AZ::Aabb::CreateNull();
|
||||
for (MultiplayerComponent* multiplayerComponent : m_multiplayerInputComponentVector)
|
||||
{
|
||||
rewindDistance = AZStd::max(rewindDistance, multiplayerComponent->GetController()->GetRewindDistanceForInput(networkInput, deltaTime));
|
||||
const AZ::Aabb componentBounds = multiplayerComponent->GetController()->GetRewindBoundsForInput(networkInput, deltaTime);
|
||||
if (componentBounds.IsValid())
|
||||
{
|
||||
bounds.AddAabb(componentBounds);
|
||||
}
|
||||
}
|
||||
return rewindDistance;
|
||||
return bounds;
|
||||
}
|
||||
|
||||
bool NetBindComponent::HandleRpcMessage(NetEntityRole remoteRole, NetworkEntityRpcMessage& message)
|
||||
@@ -203,25 +206,25 @@ namespace Multiplayer
|
||||
const NetEntityRole netEntityRole = m_netEntityRole;
|
||||
ReplicationRecord replicationRecord(netEntityRole);
|
||||
replicationRecord.Serialize(serializer);
|
||||
if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && (netEntityRole == NetEntityRole::ServerSimulation))
|
||||
if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && (netEntityRole == NetEntityRole::Server))
|
||||
{
|
||||
// Make sure to capture the entirety of the TotalRecord, before we clear out bits that haven't changed from our local state
|
||||
// If this entity migrates, we need to send all bits that might have changed from original baseline
|
||||
m_totalRecord.Append(replicationRecord);
|
||||
}
|
||||
// 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
|
||||
SerializeStateDeltaMessage(replicationRecord, serializer, ComponentSerializationType::Properties);
|
||||
SerializeStateDeltaMessage(replicationRecord, serializer);
|
||||
|
||||
if (serializer.IsValid())
|
||||
{
|
||||
replicationRecord.ResetConsumedBits();
|
||||
if (notifyChanges)
|
||||
{
|
||||
NotifyStateDeltaChanges(replicationRecord, ComponentSerializationType::Properties);
|
||||
NotifyStateDeltaChanges(replicationRecord);
|
||||
}
|
||||
|
||||
// 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
|
||||
if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && (netEntityRole == NetEntityRole::ServerSimulation))
|
||||
if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && (netEntityRole == NetEntityRole::Server))
|
||||
{
|
||||
m_currentRecord.Append(replicationRecord);
|
||||
MarkDirty();
|
||||
@@ -230,24 +233,24 @@ namespace Multiplayer
|
||||
return serializer.IsValid();
|
||||
}
|
||||
|
||||
RpcSendEvent& NetBindComponent::GetSendServerAuthorityToClientSimulationRpcEvent()
|
||||
RpcSendEvent& NetBindComponent::GetSendAuthorityToClientRpcEvent()
|
||||
{
|
||||
return m_sendServerAuthorityToClientSimulationRpcEvent;
|
||||
return m_sendAuthorityToClientRpcEvent;
|
||||
}
|
||||
|
||||
RpcSendEvent& NetBindComponent::GetSendServerAuthorityToClientAutonomousRpcEvent()
|
||||
RpcSendEvent& NetBindComponent::GetSendAuthorityToAutonomousRpcEvent()
|
||||
{
|
||||
return m_sendServerAuthorityToClientAutonomousRpcEvent;
|
||||
return m_sendAuthorityToAutonomousRpcEvent;
|
||||
}
|
||||
|
||||
RpcSendEvent& NetBindComponent::GetSendServerSimulationToServerAuthorityRpcEvent()
|
||||
RpcSendEvent& NetBindComponent::GetSendServerToAuthorityRpcEvent()
|
||||
{
|
||||
return m_sendServerSimulationtoServerAuthorityRpcEvent;
|
||||
return m_sendServertoAuthorityRpcEvent;
|
||||
}
|
||||
|
||||
RpcSendEvent& NetBindComponent::GetSendClientAutonomousToServerAuthorityRpcEvent()
|
||||
RpcSendEvent& NetBindComponent::GetSendAutonomousToAuthorityRpcEvent()
|
||||
{
|
||||
return m_sendClientAutonomousToServerAuthorityRpcEvent;
|
||||
return m_sendAutonomousToAuthorityRpcEvent;
|
||||
}
|
||||
|
||||
const ReplicationRecord& NetBindComponent::GetPredictableRecord() const
|
||||
@@ -266,7 +269,7 @@ namespace Multiplayer
|
||||
void NetBindComponent::NotifyLocalChanges()
|
||||
{
|
||||
m_localNotificationRecord.ResetConsumedBits(); // Make sure our consumed bits are reset so that we can run through the notifications
|
||||
NotifyStateDeltaChanges(m_localNotificationRecord, ComponentSerializationType::Properties);
|
||||
NotifyStateDeltaChanges(m_localNotificationRecord);
|
||||
m_localNotificationRecord.Clear();
|
||||
}
|
||||
|
||||
@@ -297,40 +300,31 @@ namespace Multiplayer
|
||||
// The m_predictableRecord is a record that that marks every NetworkProperty that has been set as Predictable
|
||||
// We copy this record and use a temporary so that SerializeStateDeltaMessage will not modify the m_predictableRecord
|
||||
// since SerializeStateDeltaMessage will clear the dirty bit for the NetworkProperty if it did not actually change
|
||||
const bool success = SerializeStateDeltaMessage(tmpRecord, serializer, ComponentSerializationType::Correction);
|
||||
const bool success = SerializeStateDeltaMessage(tmpRecord, serializer);
|
||||
if (serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject)
|
||||
{
|
||||
tmpRecord.ResetConsumedBits();
|
||||
NotifyStateDeltaChanges(tmpRecord, ComponentSerializationType::Correction);
|
||||
NotifyStateDeltaChanges(tmpRecord);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool NetBindComponent::SerializeStateDeltaMessage
|
||||
(
|
||||
ReplicationRecord& replicationRecord,
|
||||
AzNetworking::ISerializer& serializer,
|
||||
ComponentSerializationType componentSerializationType
|
||||
)
|
||||
bool NetBindComponent::SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer)
|
||||
{
|
||||
bool success = true;
|
||||
for (auto iter = m_multiplayerSerializationComponentVector.begin(); iter != m_multiplayerSerializationComponentVector.end(); ++iter)
|
||||
{
|
||||
success &= (*iter)->SerializeStateDeltaMessage(replicationRecord, serializer, componentSerializationType);
|
||||
success &= (*iter)->SerializeStateDeltaMessage(replicationRecord, serializer);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void NetBindComponent::NotifyStateDeltaChanges
|
||||
(
|
||||
ReplicationRecord& replicationRecord,
|
||||
ComponentSerializationType componentSerializationType
|
||||
)
|
||||
void NetBindComponent::NotifyStateDeltaChanges(ReplicationRecord& replicationRecord)
|
||||
{
|
||||
for (auto iter = m_multiplayerSerializationComponentVector.begin(); iter != m_multiplayerSerializationComponentVector.end(); ++iter)
|
||||
{
|
||||
(*iter)->NotifyStateDeltaChanges(replicationRecord, componentSerializationType);
|
||||
(*iter)->NotifyStateDeltaChanges(replicationRecord);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,27 +346,6 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
|
||||
bool NetBindComponent::IsMigrationDataValid() const
|
||||
{
|
||||
return m_isMigrationDataValid;
|
||||
}
|
||||
|
||||
void NetBindComponent::SetMigrationDataValid(bool migrationDataValid)
|
||||
{
|
||||
m_isMigrationDataValid = migrationDataValid;
|
||||
}
|
||||
|
||||
bool NetBindComponent::SerializeMigrationData(AzNetworking::ISerializer& serializer)
|
||||
{
|
||||
bool ret = true;
|
||||
// Purposefully not listed in reverse order, must match the order during construction
|
||||
for (auto iter = m_multiplayerSerializationComponentVector.begin(); iter != m_multiplayerSerializationComponentVector.end(); ++iter)
|
||||
{
|
||||
ret &= (*iter)->Migrate(serializer);
|
||||
}
|
||||
return ret && serializer.IsValid();
|
||||
}
|
||||
|
||||
void NetBindComponent::PreInit(AZ::Entity* entity, const PrefabEntityId& prefabEntityId, NetEntityId netEntityId, NetEntityRole netEntityRole)
|
||||
{
|
||||
AZ_Assert(entity != nullptr, "AZ::Entity is null");
|
||||
@@ -404,11 +377,11 @@ namespace Multiplayer
|
||||
{
|
||||
switch (m_netEntityRole)
|
||||
{
|
||||
case NetEntityRole::ClientSimulation:
|
||||
m_netEntityRole = NetEntityRole::ClientAutonomous;
|
||||
case NetEntityRole::Client:
|
||||
m_netEntityRole = NetEntityRole::Autonomous;
|
||||
break;
|
||||
case NetEntityRole::ServerSimulation:
|
||||
m_netEntityRole = NetEntityRole::ServerAuthority;
|
||||
case NetEntityRole::Server:
|
||||
m_netEntityRole = NetEntityRole::Authority;
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Controller already constructed");
|
||||
@@ -441,11 +414,11 @@ namespace Multiplayer
|
||||
|
||||
switch (m_netEntityRole)
|
||||
{
|
||||
case NetEntityRole::ClientAutonomous:
|
||||
m_netEntityRole = NetEntityRole::ClientSimulation;
|
||||
case NetEntityRole::Autonomous:
|
||||
m_netEntityRole = NetEntityRole::Client;
|
||||
break;
|
||||
case NetEntityRole::ServerAuthority:
|
||||
m_netEntityRole = NetEntityRole::ServerSimulation;
|
||||
case NetEntityRole::Authority:
|
||||
m_netEntityRole = NetEntityRole::Server;
|
||||
break;
|
||||
default:
|
||||
AZ_Assert(false, "Controllers already destructed");
|
||||
@@ -465,9 +438,9 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
DetermineInputOrdering();
|
||||
if (GetNetEntityRole() == NetEntityRole::ServerAuthority)
|
||||
if (GetNetEntityRole() == NetEntityRole::Authority)
|
||||
{
|
||||
m_handleLocalServerRpcMessageEventHandle.Connect(m_sendServerSimulationtoServerAuthorityRpcEvent);
|
||||
m_handleLocalServerRpcMessageEventHandle.Connect(m_sendServertoAuthorityRpcEvent);
|
||||
}
|
||||
GetNetworkEntityManager()->NotifyControllersActivated(m_netEntityHandle, entityIsMigrating);
|
||||
}
|
||||
@@ -502,19 +475,11 @@ namespace Multiplayer
|
||||
{
|
||||
for (auto* component : m_multiplayerSerializationComponentVector)
|
||||
{
|
||||
component->NetworkAttach(*this, m_currentRecord, m_predictableRecord);
|
||||
component->NetworkAttach(this, m_currentRecord, m_predictableRecord);
|
||||
}
|
||||
m_totalRecord = m_currentRecord;
|
||||
}
|
||||
|
||||
void NetBindComponent::NetworkDetach()
|
||||
{
|
||||
for (auto* component : m_multiplayerSerializationComponentVector)
|
||||
{
|
||||
component->NetworkDetach();
|
||||
}
|
||||
}
|
||||
|
||||
void NetBindComponent::HandleMarkedDirty()
|
||||
{
|
||||
m_dirtiedEvent.Signal();
|
||||
@@ -532,7 +497,7 @@ namespace Multiplayer
|
||||
|
||||
void NetBindComponent::HandleLocalServerRpcMessage(NetworkEntityRpcMessage& message)
|
||||
{
|
||||
message.SetRpcDeliveryType(RpcDeliveryType::ServerSimulationToServerAuthority);
|
||||
message.SetRpcDeliveryType(RpcDeliveryType::ServerToAuthority);
|
||||
GetNetworkEntityManager()->HandleLocalRpcMessage(message);
|
||||
}
|
||||
|
||||
@@ -574,8 +539,8 @@ namespace Multiplayer
|
||||
{
|
||||
switch (networkRole)
|
||||
{
|
||||
case NetEntityRole::ClientAutonomous: // Fall through
|
||||
case NetEntityRole::ServerAuthority:
|
||||
case NetEntityRole::Autonomous: // Fall through
|
||||
case NetEntityRole::Authority:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/Component/Component.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Math/Aabb.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
@@ -23,6 +24,7 @@
|
||||
#include <Source/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Source/NetworkInput/IMultiplayerComponentInput.h>
|
||||
#include <Source/MultiplayerTypes.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
@@ -68,15 +70,15 @@ namespace Multiplayer
|
||||
bool IsProcessingInput() const;
|
||||
void CreateInput(NetworkInput& networkInput, float deltaTime);
|
||||
void ProcessInput(NetworkInput& networkInput, float deltaTime);
|
||||
float GetRewindDistanceForInput(const NetworkInput& networkInput, float deltaTime) const;
|
||||
AZ::Aabb GetRewindBoundsForInput(const NetworkInput& networkInput, float deltaTime) const;
|
||||
|
||||
bool HandleRpcMessage(NetEntityRole remoteRole, NetworkEntityRpcMessage& message);
|
||||
bool HandlePropertyChangeMessage(AzNetworking::ISerializer& serializer, bool notifyChanges = true);
|
||||
|
||||
RpcSendEvent& GetSendServerAuthorityToClientSimulationRpcEvent();
|
||||
RpcSendEvent& GetSendServerAuthorityToClientAutonomousRpcEvent();
|
||||
RpcSendEvent& GetSendServerSimulationToServerAuthorityRpcEvent();
|
||||
RpcSendEvent& GetSendClientAutonomousToServerAuthorityRpcEvent();
|
||||
RpcSendEvent& GetSendAuthorityToClientRpcEvent();
|
||||
RpcSendEvent& GetSendAuthorityToAutonomousRpcEvent();
|
||||
RpcSendEvent& GetSendServerToAuthorityRpcEvent();
|
||||
RpcSendEvent& GetSendAutonomousToAuthorityRpcEvent();
|
||||
|
||||
const ReplicationRecord& GetPredictableRecord() const;
|
||||
|
||||
@@ -88,20 +90,15 @@ namespace Multiplayer
|
||||
void AddEntityDirtiedEventHandler(EntityDirtiedEvent::Handler& eventHandler);
|
||||
void AddEntityMigrationEventHandler(EntityMigrationEvent::Handler& eventHandler);
|
||||
|
||||
bool SerializeEntityCorrection(AzNetworking::ISerializer& a_Serializer);
|
||||
bool SerializeEntityCorrection(AzNetworking::ISerializer& serializer);
|
||||
|
||||
bool SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer, ComponentSerializationType componentSerializationType);
|
||||
void NotifyStateDeltaChanges(ReplicationRecord& replicationRecord, ComponentSerializationType componentSerializationType);
|
||||
bool SerializeStateDeltaMessage(ReplicationRecord& replicationRecord, AzNetworking::ISerializer& serializer);
|
||||
void NotifyStateDeltaChanges(ReplicationRecord& replicationRecord);
|
||||
|
||||
void FillReplicationRecord(ReplicationRecord& replicationRecord) const;
|
||||
void FillTotalReplicationRecord(ReplicationRecord& replicationRecord) const;
|
||||
|
||||
bool IsMigrationDataValid() const;
|
||||
|
||||
private:
|
||||
void SetMigrationDataValid(bool migrationDataValid);
|
||||
bool SerializeMigrationData(AzNetworking::ISerializer& serializer);
|
||||
|
||||
void PreInit(AZ::Entity* entity, const PrefabEntityId& prefabEntityId, NetEntityId netEntityId, NetEntityRole netEntityRole);
|
||||
|
||||
void ConstructControllers();
|
||||
@@ -112,7 +109,6 @@ namespace Multiplayer
|
||||
void OnEntityStateEvent(AZ::Entity::State oldState, AZ::Entity::State newState);
|
||||
|
||||
void NetworkAttach();
|
||||
void NetworkDetach();
|
||||
|
||||
void HandleMarkedDirty();
|
||||
void HandleLocalServerRpcMessage(NetworkEntityRpcMessage& message);
|
||||
@@ -130,10 +126,10 @@ namespace Multiplayer
|
||||
AZStd::vector<MultiplayerComponent*> m_multiplayerSerializationComponentVector;
|
||||
AZStd::vector<MultiplayerComponent*> m_multiplayerInputComponentVector;
|
||||
|
||||
RpcSendEvent m_sendServerAuthorityToClientSimulationRpcEvent;
|
||||
RpcSendEvent m_sendServerAuthorityToClientAutonomousRpcEvent;
|
||||
RpcSendEvent m_sendServerSimulationtoServerAuthorityRpcEvent;
|
||||
RpcSendEvent m_sendClientAutonomousToServerAuthorityRpcEvent;
|
||||
RpcSendEvent m_sendAuthorityToClientRpcEvent;
|
||||
RpcSendEvent m_sendAuthorityToAutonomousRpcEvent;
|
||||
RpcSendEvent m_sendServertoAuthorityRpcEvent;
|
||||
RpcSendEvent m_sendAutonomousToAuthorityRpcEvent;
|
||||
|
||||
EntityStopEvent m_entityStopEvent;
|
||||
EntityDirtiedEvent m_dirtiedEvent;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Source/Components/NetworkTransformComponent.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
void NetworkTransformComponent::NetworkTransformComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<NetworkTransformComponent, NetworkTransformComponentBase>()
|
||||
->Version(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Source/AutoGen/NetworkTransformComponent.AutoComponent.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class NetworkTransformComponent
|
||||
: public NetworkTransformComponentBase
|
||||
{
|
||||
public:
|
||||
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkTransformComponent, s_networkTransformComponentConcreteUuid, Multiplayer::NetworkTransformComponentBase);
|
||||
|
||||
static void Reflect([[maybe_unused]] AZ::ReflectContext* context);
|
||||
|
||||
void OnInit() override {}
|
||||
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
};
|
||||
|
||||
class NetworkTransformComponentController
|
||||
: public NetworkTransformComponentControllerBase
|
||||
{
|
||||
public:
|
||||
NetworkTransformComponentController(NetworkTransformComponent& parent) : NetworkTransformComponentControllerBase(parent) {}
|
||||
|
||||
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override {}
|
||||
};
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace Multiplayer
|
||||
{
|
||||
NetBindComponent* netBindComponent = m_controlledEntity.GetNetBindComponent();
|
||||
// potentially false if we just migrated the player, if that is the case, don't send any more updates
|
||||
if (netBindComponent != nullptr && (netBindComponent->GetNetEntityRole() == NetEntityRole::ServerAuthority))
|
||||
if (netBindComponent != nullptr && (netBindComponent->GetNetEntityRole() == NetEntityRole::Authority))
|
||||
{
|
||||
m_entityReplicationManager.SendUpdates(serverGameTimeMs);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Multiplayer
|
||||
, m_entityReplicationManager(*connection, connectionListener, EntityReplicationManager::Mode::LocalServerToRemoteServer)
|
||||
, m_connectEvent([this]() { OnConnectTimeout(); }, AZ::Name("Server to server connection timeout event"))
|
||||
{
|
||||
m_entityReplicationManager.SetRemoteHostId(InvalidHostId);// a_ServerAddrInfo.GetServerAddrInfo().GetShardId());
|
||||
m_entityReplicationManager.SetRemoteHostId(InvalidHostId);// serverAddrInfo.GetServerAddrInfo().GetShardId());
|
||||
m_entityReplicationManager.SetEntityActivationTimeSliceMs(sv_DefaultNetworkEntityActivationTimeSliceMs);
|
||||
m_entityReplicationManager.SetMaxRemoteEntitiesPendingCreationCount(sv_ServerMaxRemoteEntitiesPendingCreationCount);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Multiplayer
|
||||
AZ_CVAR(AZ::CVarFixedString, sv_map, "nolevel", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The map the server should load");
|
||||
AZ_CVAR(AZ::CVarFixedString, sv_gamerules, "norules", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "GameRules server works with");
|
||||
AZ_CVAR(ProtocolType, sv_protocol, ProtocolType::Udp, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "This flag controls whether we use TCP or UDP for game networking");
|
||||
AZ_CVAR(bool, sv_isdedicated, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Whether the host command creates an independent or client hosted server");
|
||||
AZ_CVAR(bool, sv_isDedicated, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Whether the host command creates an independent or client hosted server");
|
||||
|
||||
void MultiplayerSystemComponent::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
@@ -375,7 +375,6 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
m_agentType = multiplayerType;
|
||||
|
||||
}
|
||||
|
||||
void MultiplayerSystemComponent::AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler)
|
||||
@@ -430,7 +429,7 @@ namespace Multiplayer
|
||||
|
||||
void host([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
|
||||
{
|
||||
Multiplayer::MultiplayerAgentType serverType = sv_isdedicated ? MultiplayerAgentType::DedicatedServer : MultiplayerAgentType::ClientServer;
|
||||
Multiplayer::MultiplayerAgentType serverType = sv_isDedicated ? MultiplayerAgentType::DedicatedServer : MultiplayerAgentType::ClientServer;
|
||||
INetworkInterface* networkInterface = AZ::Interface<INetworking>::Get()->RetrieveNetworkInterface(AZ::Name(s_networkInterfaceName));
|
||||
networkInterface->Listen(sv_port);
|
||||
AZ::Interface<IMultiplayer>::Get()->InitializeMultiplayer(serverType);
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
//! The default number of rewindable samples for us to store.
|
||||
static constexpr uint32_t RewindHistorySize = 128;
|
||||
|
||||
AZ_TYPE_SAFE_INTEGRAL(HostId, uint32_t);
|
||||
static constexpr HostId InvalidHostId = static_cast<HostId>(-1);
|
||||
|
||||
@@ -39,19 +42,19 @@ namespace Multiplayer
|
||||
enum class RpcDeliveryType : uint8_t
|
||||
{
|
||||
None,
|
||||
ServerAuthorityToClientSimulation, // Invoked from ServerAuthority, handled on ClientSimulation
|
||||
ServerAuthorityToClientAutonomous, // Invoked from ServerAuthority, handled on ClientAutonomous
|
||||
ClientAutonomousToServerAuthority, // Invoked from ClientAutonomous, handled on ServerAuthority
|
||||
ServerSimulationToServerAuthority // Invoked from ServerSimulation, handled on ServerAuthority
|
||||
AuthorityToClient, // Invoked from Authority, handled on Client
|
||||
AuthorityToAutonomous, // Invoked from Authority, handled on Autonomous
|
||||
AutonomousToAuthority, // Invoked from Autonomous, handled on Authority
|
||||
ServerToAuthority // Invoked from Server, handled on Authority
|
||||
};
|
||||
|
||||
enum class NetEntityRole : uint8_t
|
||||
{
|
||||
InvalidRole, // No role
|
||||
ClientSimulation, // A simulated proxy on a client
|
||||
ClientAutonomous, // An autonomous proxy on a client (can execute local prediction)
|
||||
ServerSimulation, // A simulated proxy on a server
|
||||
ServerAuthority // An authoritative proxy on a server (full authority)
|
||||
InvalidRole, // No role
|
||||
Client, // A simulated proxy on a client
|
||||
Autonomous, // An autonomous proxy on a client (can execute local prediction)
|
||||
Server, // A simulated proxy on a server
|
||||
Authority // An authoritative proxy on a server (full authority)
|
||||
};
|
||||
|
||||
enum class ComponentSerializationType : uint8_t
|
||||
|
||||
+21
-34
@@ -216,7 +216,7 @@ namespace Multiplayer
|
||||
m_remoteEntitiesPendingCreation.insert(entityId);
|
||||
}
|
||||
|
||||
if (replicator->GetRemoteNetworkRole() == NetEntityRole::ClientAutonomous)
|
||||
if (replicator->GetRemoteNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
autonomousReplicators.push_back(replicator);
|
||||
}
|
||||
@@ -557,7 +557,7 @@ namespace Multiplayer
|
||||
const bool changeNetworkRole = (netBindComponent->GetNetEntityRole() != localNetworkRole);
|
||||
if (changeNetworkRole)
|
||||
{
|
||||
AZ_Assert(localNetworkRole != NetEntityRole::ServerAuthority, "UpdateMessage trying to set local role to ServerAuthority, this should only happen via migration");
|
||||
AZ_Assert(localNetworkRole != NetEntityRole::Authority, "UpdateMessage trying to set local role to Authority, this should only happen via migration");
|
||||
AZLOG_INFO
|
||||
(
|
||||
"EntityReplicationManager: Changing network role on entity %u, old role %u new role %u",
|
||||
@@ -590,14 +590,14 @@ namespace Multiplayer
|
||||
// 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.
|
||||
// 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.
|
||||
GetNetworkEntityManager()->ClearEntityFromRemovalList(replicatorEntity);
|
||||
entityReplicator = AddEntityReplicator(replicatorEntity, NetEntityRole::ServerAuthority);
|
||||
entityReplicator = AddEntityReplicator(replicatorEntity, NetEntityRole::Authority);
|
||||
//AZLOG(NET_RepUpdate, "EntityReplicationManager: Created from update entity id %u for type %s role %d", netEntityId, prefabEntityId.GetString(), localNetworkRole);
|
||||
}
|
||||
|
||||
// @nt: TODO - delete once dropped RPC problem fixed
|
||||
// This code is temporary to work around to the problem that RPC messages are silently lost during migration
|
||||
// Once this problem is solved, we can remove this code and associated event
|
||||
if (createReplicator && localNetworkRole == NetEntityRole::ClientAutonomous)
|
||||
if (createReplicator && localNetworkRole == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_autonomousEntityReplicatorCreated.Signal(netEntityId);
|
||||
}
|
||||
@@ -647,10 +647,10 @@ namespace Multiplayer
|
||||
// don't trust the client by default
|
||||
result = UpdateValidationResult::DropMessageAndDisconnect;
|
||||
// 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
|
||||
if (updateMessage.GetNetworkRole() == NetEntityRole::ServerAuthority && entityReplicator && !updateMessage.GetIsDelete())
|
||||
if (updateMessage.GetNetworkRole() == NetEntityRole::Authority && entityReplicator && !updateMessage.GetIsDelete())
|
||||
{
|
||||
// Make sure we our replicator is in the expected configuration
|
||||
if ((entityReplicator->GetRemoteNetworkRole() == NetEntityRole::ClientAutonomous) && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority))
|
||||
if ((entityReplicator->GetRemoteNetworkRole() == NetEntityRole::Autonomous) && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// If we're marked for removal, just drop the message - migration message is likely in flight
|
||||
if (entityReplicator->IsMarkedForRemoval())
|
||||
@@ -663,7 +663,7 @@ namespace Multiplayer
|
||||
result = UpdateValidationResult::HandleMessage;
|
||||
}
|
||||
} // If we've migrated the entity away from the server, but we get this late, just drop it
|
||||
else if ((entityReplicator->GetRemoteNetworkRole() == NetEntityRole::ClientSimulation) && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::ServerSimulation))
|
||||
else if ((entityReplicator->GetRemoteNetworkRole() == NetEntityRole::Client) && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Server))
|
||||
{
|
||||
result = UpdateValidationResult::DropMessage;
|
||||
}
|
||||
@@ -686,22 +686,22 @@ namespace Multiplayer
|
||||
break;
|
||||
case Mode::LocalServerToRemoteServer:
|
||||
{
|
||||
AZ_Assert(updateMessage.GetNetworkRole() == NetEntityRole::ServerSimulation || updateMessage.GetIsDelete(), "Unexpected update type coming from peer server");
|
||||
AZ_Assert(updateMessage.GetNetworkRole() == NetEntityRole::Server || updateMessage.GetIsDelete(), "Unexpected update type coming from peer server");
|
||||
// trust messages from a peer server by default
|
||||
result = UpdateValidationResult::HandleMessage;
|
||||
// If we have a replicator, make sure we're in the correct state
|
||||
if (entityReplicator)
|
||||
{
|
||||
if (!entityReplicator->IsMarkedForRemoval() && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority))
|
||||
if (!entityReplicator->IsMarkedForRemoval() && (entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// Likely an old message from a previous owner trying to delete the replicator it had, while we've received ownership
|
||||
// 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)
|
||||
result = UpdateValidationResult::DropMessage;
|
||||
}
|
||||
else if (entityReplicator->GetRemoteNetworkRole() != NetEntityRole::ServerAuthority)// we expect to the remote role to be e_ServerAuthority
|
||||
else if (entityReplicator->GetRemoteNetworkRole() != NetEntityRole::Authority)// we expect to the remote role to be e_Authority
|
||||
{
|
||||
// This entity has migrated previously, and we haven't heard back that the remove was successful, so we can accept the message
|
||||
AZ_Assert(entityReplicator->IsMarkedForRemoval() && entityReplicator->GetRemoteNetworkRole() == NetEntityRole::ServerSimulation, "Unexpected server message is not Authority or ServerSimulation");
|
||||
AZ_Assert(entityReplicator->IsMarkedForRemoval() && entityReplicator->GetRemoteNetworkRole() == NetEntityRole::Server, "Unexpected server message is not Authority or Server");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1018,9 +1018,9 @@ namespace Multiplayer
|
||||
AZ_Assert(netBindComponent, "No NetBindComponent");
|
||||
|
||||
const EntityReplicator* entityReplicator = GetEntityReplicator(entityHandle.GetNetEntityId());
|
||||
hasAuthority = (netBindComponent->GetNetEntityRole() == NetEntityRole::ServerAuthority); // Make sure someone hasn't migrated this already
|
||||
hasAuthority = (netBindComponent->GetNetEntityRole() == NetEntityRole::Authority); // Make sure someone hasn't migrated this already
|
||||
isInDomain = (m_remoteEntityDomain && m_remoteEntityDomain->IsInDomain(entityHandle)); // Make sure the remote side would want it
|
||||
if (entityReplicator && entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
if (entityReplicator && entityReplicator->GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
{
|
||||
isMarkedForRemoval = entityReplicator->IsMarkedForRemoval(); // Make sure we aren't telling the other side to remove the replicator
|
||||
const PropertyPublisher* propertyPublisher = entityReplicator->GetPropertyPublisher();
|
||||
@@ -1035,7 +1035,7 @@ namespace Multiplayer
|
||||
{
|
||||
if (const EntityReplicator* replicator = GetEntityReplicator(entityHandle.GetNetEntityId()))
|
||||
{
|
||||
return replicator->GetRemoteNetworkRole() == NetEntityRole::ServerAuthority;
|
||||
return replicator->GetRemoteNetworkRole() == NetEntityRole::Authority;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1073,9 +1073,9 @@ namespace Multiplayer
|
||||
NetBindComponent* netBindComponent = entityHandle.GetNetBindComponent();
|
||||
AZ_Assert(netBindComponent, "No NetBindComponent");
|
||||
|
||||
if (netBindComponent && netBindComponent->GetNetEntityRole() == NetEntityRole::ServerAuthority)
|
||||
if (netBindComponent && netBindComponent->GetNetEntityRole() == NetEntityRole::Authority)
|
||||
{
|
||||
EntityReplicator* replicator = AddEntityReplicator(entityHandle, NetEntityRole::ServerSimulation);
|
||||
EntityReplicator* replicator = AddEntityReplicator(entityHandle, NetEntityRole::Server);
|
||||
PropertyPublisher* propPublisher = replicator->GetPropertyPublisher();
|
||||
AZ_Assert(propPublisher, "Assumed we have a property publisher");
|
||||
|
||||
@@ -1092,15 +1092,11 @@ namespace Multiplayer
|
||||
if (localEnt->GetState() == AZ::Entity::State::Active)
|
||||
{
|
||||
netBindComponent->DeactivateControllers(EntityIsMigrating::True);
|
||||
AzNetworking::NetworkInputSerializer inputSerializer(message.ModifyMigrationData().GetBuffer(), message.ModifyMigrationData().GetCapacity());
|
||||
didSucceed = netBindComponent->SerializeMigrationData(inputSerializer);
|
||||
message.ModifyMigrationData().Resize(inputSerializer.GetSize());
|
||||
}
|
||||
|
||||
netBindComponent->DestructControllers();
|
||||
netBindComponent->SetMigrationDataValid(false);
|
||||
|
||||
// save off network properties after the migration data is saved to capture any changes that might have occurred during deactivate
|
||||
// Gather the most recent network property state, including authoritative only network properties for migration
|
||||
{
|
||||
// Send an update packet if it needs one
|
||||
propPublisher->GenerateRecord();
|
||||
@@ -1119,7 +1115,7 @@ namespace Multiplayer
|
||||
AZLOG(NET_RepDeletes, "Migration packet sent %u to remote manager id %d", netEntityId, aznumeric_cast<int32_t>(GetRemoteHostId()));
|
||||
|
||||
// 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
|
||||
AddEntityReplicator(entityHandle, NetEntityRole::ServerAuthority);
|
||||
AddEntityReplicator(entityHandle, NetEntityRole::Authority);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1135,7 +1131,7 @@ namespace Multiplayer
|
||||
replicator,
|
||||
AzNetworking::InvalidPacketId,
|
||||
message.GetEntityId(),
|
||||
NetEntityRole::ServerSimulation,
|
||||
NetEntityRole::Server,
|
||||
outputSerializer,
|
||||
message.GetPrefabEntityId()
|
||||
))
|
||||
@@ -1159,15 +1155,6 @@ namespace Multiplayer
|
||||
// Stop listening to the OnEntityNetworkRoleChange, since we are about to change it and we don't want that callback
|
||||
netBindComponent->ConstructControllers();
|
||||
|
||||
bool didSucceed = false;
|
||||
{
|
||||
AzNetworking::NetworkOutputSerializer outputSerializer(message.ModifyMigrationData().GetBuffer(), message.ModifyMigrationData().GetSize());
|
||||
didSucceed = netBindComponent->SerializeMigrationData(outputSerializer);
|
||||
AZ_Assert(didSucceed, "Failed to migrate entity to server");
|
||||
AZ_Assert(outputSerializer.IsValid() && outputSerializer.GetUnreadSize() == 0, "Bad migration");
|
||||
}
|
||||
netBindComponent->SetMigrationDataValid(true);
|
||||
|
||||
if (entityHandle.GetEntity()->GetState() == AZ::Entity::State::Active)
|
||||
{
|
||||
// Only activate controllers if the entity was previously activated, otherwise, wait for the normal entity activation flow
|
||||
@@ -1175,10 +1162,10 @@ namespace Multiplayer
|
||||
}
|
||||
|
||||
// change the role on the replicator
|
||||
AddEntityReplicator(entityHandle, NetEntityRole::ServerSimulation);
|
||||
AddEntityReplicator(entityHandle, NetEntityRole::Server);
|
||||
|
||||
AZLOG(NET_RepDeletes, "Handle Migration %u new authority from remote manager id %d", entityHandle.GetNetEntityId(), aznumeric_cast<int32_t>(GetRemoteHostId()));
|
||||
return didSucceed;
|
||||
return true;
|
||||
}
|
||||
|
||||
void EntityReplicationManager::OnEntityExitDomain(const ConstNetworkEntityHandle& entityHandle)
|
||||
|
||||
@@ -50,8 +50,8 @@ namespace Multiplayer
|
||||
, m_onEntityDirtiedHandler([this]() { OnEntityDirtiedEvent(); })
|
||||
, m_onSendRpcHandler([this](NetworkEntityRpcMessage& entityRpcMessage) { OnSendRpcEvent(entityRpcMessage); })
|
||||
, m_onForwardRpcHandler([this](NetworkEntityRpcMessage& entityRpcMessage) { OnSendRpcEvent(entityRpcMessage); })
|
||||
, m_onSendClientAutonomousRpcHandler([this](NetworkEntityRpcMessage& entityRpcMessage) { OnSendRpcEvent(entityRpcMessage); })
|
||||
, m_onForwardClientAutonomousRpcHandler([this](NetworkEntityRpcMessage& entityRpcMessage) { OnSendRpcEvent(entityRpcMessage); })
|
||||
, m_onSendAutonomousRpcHandler([this](NetworkEntityRpcMessage& entityRpcMessage) { OnSendRpcEvent(entityRpcMessage); })
|
||||
, m_onForwardAutonomousRpcHandler([this](NetworkEntityRpcMessage& entityRpcMessage) { OnSendRpcEvent(entityRpcMessage); })
|
||||
, m_onEntityStopHandler([this](const ConstNetworkEntityHandle &) { OnEntityRemovedEvent(); })
|
||||
, m_proxyRemovalEvent([this] { OnProxyRemovalTimedEvent(); }, AZ::Name("ProxyRemovalTimedEvent"))
|
||||
{
|
||||
@@ -73,11 +73,11 @@ namespace Multiplayer
|
||||
m_prefabEntityIdSet = true;
|
||||
}
|
||||
|
||||
void EntityReplicator::Reset(NetEntityRole a_RemoteNetworkRole)
|
||||
void EntityReplicator::Reset(NetEntityRole remoteNetworkRole)
|
||||
{
|
||||
AZ::EntityBus::Handler::BusDisconnect();
|
||||
|
||||
m_remoteNetworkRole = a_RemoteNetworkRole;
|
||||
m_remoteNetworkRole = remoteNetworkRole;
|
||||
|
||||
m_propertyPublisher = nullptr;
|
||||
m_propertySubscriber = nullptr;
|
||||
@@ -86,8 +86,8 @@ namespace Multiplayer
|
||||
|
||||
m_onSendRpcHandler.Disconnect();
|
||||
m_onForwardRpcHandler.Disconnect();
|
||||
m_onSendClientAutonomousRpcHandler.Disconnect();
|
||||
m_onForwardClientAutonomousRpcHandler.Disconnect();
|
||||
m_onSendAutonomousRpcHandler.Disconnect();
|
||||
m_onForwardAutonomousRpcHandler.Disconnect();
|
||||
m_onEntityStopHandler.Disconnect();
|
||||
}
|
||||
|
||||
@@ -136,8 +136,8 @@ namespace Multiplayer
|
||||
m_propertyPublisher = nullptr;
|
||||
}
|
||||
|
||||
if (m_remoteNetworkRole == NetEntityRole::ServerAuthority ||
|
||||
m_remoteNetworkRole == NetEntityRole::ClientAutonomous)
|
||||
if (m_remoteNetworkRole == NetEntityRole::Authority ||
|
||||
m_remoteNetworkRole == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_propertySubscriber = AZStd::make_unique<PropertySubscriber>(m_replicationManager, m_netBindComponent);
|
||||
}
|
||||
@@ -165,9 +165,9 @@ namespace Multiplayer
|
||||
{
|
||||
// Make sure all handlers are detached first
|
||||
m_onSendRpcHandler.Disconnect();
|
||||
m_onSendClientAutonomousRpcHandler.Disconnect();
|
||||
m_onSendAutonomousRpcHandler.Disconnect();
|
||||
m_onForwardRpcHandler.Disconnect();
|
||||
m_onForwardClientAutonomousRpcHandler.Disconnect();
|
||||
m_onForwardAutonomousRpcHandler.Disconnect();
|
||||
|
||||
if (auto localEntity = m_entityHandle.GetEntity())
|
||||
{
|
||||
@@ -176,49 +176,49 @@ namespace Multiplayer
|
||||
|
||||
switch (GetBoundLocalNetworkRole())
|
||||
{
|
||||
case NetEntityRole::ServerAuthority:
|
||||
case NetEntityRole::Authority:
|
||||
{
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::ClientSimulation || GetRemoteNetworkRole() == NetEntityRole::ClientAutonomous)
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Client || GetRemoteNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendServerAuthorityToClientSimulationRpcEvent());
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::ClientAutonomous)
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_onSendClientAutonomousRpcHandler.Connect(netBindComponent->GetSendServerAuthorityToClientAutonomousRpcEvent());
|
||||
m_onSendAutonomousRpcHandler.Connect(netBindComponent->GetSendAuthorityToAutonomousRpcEvent());
|
||||
}
|
||||
}
|
||||
else if (GetRemoteNetworkRole() == NetEntityRole::ServerSimulation)
|
||||
else if (GetRemoteNetworkRole() == NetEntityRole::Server)
|
||||
{
|
||||
m_onForwardRpcHandler.Connect(netBindComponent->GetSendServerAuthorityToClientSimulationRpcEvent());
|
||||
m_onForwardRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NetEntityRole::ServerSimulation:
|
||||
case NetEntityRole::Server:
|
||||
{
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Authority)
|
||||
{
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendServerSimulationToServerAuthorityRpcEvent());
|
||||
m_onForwardRpcHandler.Connect(netBindComponent->GetSendServerAuthorityToClientSimulationRpcEvent());
|
||||
m_onForwardClientAutonomousRpcHandler.Connect(netBindComponent->GetSendServerAuthorityToClientAutonomousRpcEvent());
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendServerToAuthorityRpcEvent());
|
||||
m_onForwardRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
m_onForwardAutonomousRpcHandler.Connect(netBindComponent->GetSendAuthorityToAutonomousRpcEvent());
|
||||
}
|
||||
else if (GetRemoteNetworkRole() == NetEntityRole::ClientSimulation)
|
||||
else if (GetRemoteNetworkRole() == NetEntityRole::Client)
|
||||
{
|
||||
// Listen for these to forward the rpc along to the other Client replicators
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendServerAuthorityToClientSimulationRpcEvent());
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendAuthorityToClientRpcEvent());
|
||||
}
|
||||
// NOTE: e_ClientAutonomous is not connected to e_ServerProxy, it is always connected to an e_ServerAuthority
|
||||
AZ_Assert(GetRemoteNetworkRole() != NetEntityRole::ClientAutonomous, "Unexpected autonomous remote role")
|
||||
// NOTE: e_Autonomous is not connected to e_ServerProxy, it is always connected to an e_Authority
|
||||
AZ_Assert(GetRemoteNetworkRole() != NetEntityRole::Autonomous, "Unexpected autonomous remote role")
|
||||
}
|
||||
break;
|
||||
case NetEntityRole::ClientSimulation:
|
||||
case NetEntityRole::Client:
|
||||
{
|
||||
// Nothing allowed, no ClientSimulation to Server communication
|
||||
// Nothing allowed, no Client to Server communication
|
||||
}
|
||||
break;
|
||||
case NetEntityRole::ClientAutonomous:
|
||||
case NetEntityRole::Autonomous:
|
||||
{
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
if (GetRemoteNetworkRole() == NetEntityRole::Authority)
|
||||
{
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendClientAutonomousToServerAuthorityRpcEvent());
|
||||
m_onSendRpcHandler.Connect(netBindComponent->GetSendAutonomousToAuthorityRpcEvent());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -282,11 +282,11 @@ namespace Multiplayer
|
||||
NetBindComponent* netBindComponent = m_netBindComponent;
|
||||
AZ_Assert(netBindComponent, "No Multiplayer::NetBindComponent");
|
||||
|
||||
bool isServerAuthority = (GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
bool isAuthority = (GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetBoundLocalNetworkRole() == netBindComponent->GetNetEntityRole());
|
||||
bool isClientSimulation = GetRemoteNetworkRole() == NetEntityRole::ClientSimulation;
|
||||
bool isClientAutonomous = GetBoundLocalNetworkRole() == NetEntityRole::ClientAutonomous;
|
||||
if (isServerAuthority || isClientSimulation || isClientAutonomous)
|
||||
bool isClient = GetRemoteNetworkRole() == NetEntityRole::Client;
|
||||
bool isAutonomous = GetBoundLocalNetworkRole() == NetEntityRole::Autonomous;
|
||||
if (isAuthority || isClient || isAutonomous)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
@@ -297,10 +297,10 @@ namespace Multiplayer
|
||||
bool EntityReplicator::OwnsReplicatorLifetime() const
|
||||
{
|
||||
bool ret(false);
|
||||
if (GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority
|
||||
|| (GetBoundLocalNetworkRole() == NetEntityRole::ServerSimulation
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ClientSimulation
|
||||
|| GetRemoteNetworkRole() == NetEntityRole::ClientAutonomous)))
|
||||
if (GetBoundLocalNetworkRole() == NetEntityRole::Authority
|
||||
|| (GetBoundLocalNetworkRole() == NetEntityRole::Server
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Client
|
||||
|| GetRemoteNetworkRole() == NetEntityRole::Autonomous)))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
@@ -310,11 +310,11 @@ namespace Multiplayer
|
||||
bool EntityReplicator::RemoteManagerOwnsEntityLifetime() const
|
||||
{
|
||||
bool ret(false);
|
||||
bool isServerSimulation = (GetBoundLocalNetworkRole() == NetEntityRole::ServerSimulation)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority);
|
||||
bool isClientSimulation = (GetBoundLocalNetworkRole() == NetEntityRole::ClientSimulation)
|
||||
|| (GetBoundLocalNetworkRole() == NetEntityRole::ClientAutonomous);
|
||||
if (isServerSimulation || isClientSimulation)
|
||||
bool isServer = (GetBoundLocalNetworkRole() == NetEntityRole::Server)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority);
|
||||
bool isClient = (GetBoundLocalNetworkRole() == NetEntityRole::Client)
|
||||
|| (GetBoundLocalNetworkRole() == NetEntityRole::Autonomous);
|
||||
if (isServer || isClient)
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
@@ -346,7 +346,7 @@ namespace Multiplayer
|
||||
m_replicationManager.AddReplicatorToPendingRemoval(*this);
|
||||
|
||||
m_onForwardRpcHandler.Disconnect();
|
||||
m_onForwardClientAutonomousRpcHandler.Disconnect();
|
||||
m_onForwardAutonomousRpcHandler.Disconnect();
|
||||
|
||||
m_onEntityStopHandler.Disconnect();
|
||||
}
|
||||
@@ -492,32 +492,32 @@ namespace Multiplayer
|
||||
RpcValidationResult result = RpcValidationResult::DropRpcAndDisconnect;
|
||||
switch (entityRpcMessage.GetRpcDeliveryType())
|
||||
{
|
||||
case RpcDeliveryType::ServerAuthorityToClientSimulation:
|
||||
case RpcDeliveryType::AuthorityToClient:
|
||||
{
|
||||
if (((GetBoundLocalNetworkRole() == NetEntityRole::ClientSimulation) || (GetBoundLocalNetworkRole() == NetEntityRole::ClientAutonomous))
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority))
|
||||
if (((GetBoundLocalNetworkRole() == NetEntityRole::Client) || (GetBoundLocalNetworkRole() == NetEntityRole::Autonomous))
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// We are a local client, and we are connected to server, aka AuthorityToClient
|
||||
result = RpcValidationResult::HandleRpc;
|
||||
}
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::ServerSimulation)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Server)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// We are on a server, and we received this message from another server, therefore we should forward this to any connected clients
|
||||
result = RpcValidationResult::ForwardToClient;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RpcDeliveryType::ServerAuthorityToClientAutonomous:
|
||||
case RpcDeliveryType::AuthorityToAutonomous:
|
||||
{
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::ClientAutonomous)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Autonomous)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Authority))
|
||||
{
|
||||
// We are an autonomous client, and we are connected to server, aka AuthorityToAutonomous
|
||||
result = RpcValidationResult::HandleRpc;
|
||||
}
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ServerSimulation))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Server))
|
||||
{
|
||||
// We are on a server, and we received this message from another server, therefore we should forward this to our autonomous player
|
||||
// This can occur if we've recently migrated
|
||||
@@ -525,10 +525,10 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RpcDeliveryType::ClientAutonomousToServerAuthority:
|
||||
case RpcDeliveryType::AutonomousToAuthority:
|
||||
{
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ClientAutonomous))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Autonomous))
|
||||
{
|
||||
if (IsMarkedForRemoval())
|
||||
{
|
||||
@@ -552,10 +552,10 @@ namespace Multiplayer
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RpcDeliveryType::ServerSimulationToServerAuthority:
|
||||
case RpcDeliveryType::ServerToAuthority:
|
||||
{
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::ServerSimulation))
|
||||
if ((GetBoundLocalNetworkRole() == NetEntityRole::Authority)
|
||||
&& (GetRemoteNetworkRole() == NetEntityRole::Server))
|
||||
{
|
||||
// if we're marked for removal, then we should forward to whomever now owns this entity
|
||||
if (IsMarkedForRemoval())
|
||||
@@ -583,8 +583,8 @@ namespace Multiplayer
|
||||
}
|
||||
if (result == RpcValidationResult::DropRpcAndDisconnect)
|
||||
{
|
||||
bool isLocalServer = (GetBoundLocalNetworkRole() == NetEntityRole::ServerAuthority) || (GetBoundLocalNetworkRole() == NetEntityRole::ServerSimulation);
|
||||
bool isRemoteServer = (GetRemoteNetworkRole() == NetEntityRole::ServerAuthority) || (GetRemoteNetworkRole() == NetEntityRole::ServerSimulation);
|
||||
bool isLocalServer = (GetBoundLocalNetworkRole() == NetEntityRole::Authority) || (GetBoundLocalNetworkRole() == NetEntityRole::Server);
|
||||
bool isRemoteServer = (GetRemoteNetworkRole() == NetEntityRole::Authority) || (GetRemoteNetworkRole() == NetEntityRole::Server);
|
||||
if (isLocalServer && isRemoteServer)
|
||||
{
|
||||
// Demote this to just a drop message, we didn't want to handle the message, but we don't want to drop the connection
|
||||
@@ -680,19 +680,19 @@ namespace Multiplayer
|
||||
case RpcValidationResult::ForwardToClient:
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendServerAuthorityToClientSimulationRpcEvent().Signal(entityRpcMessage);
|
||||
m_netBindComponent->GetSendAuthorityToClientRpcEvent().Signal(entityRpcMessage);
|
||||
return true;
|
||||
}
|
||||
case RpcValidationResult::ForwardToAutonomous:
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendServerAuthorityToClientAutonomousRpcEvent().Signal(entityRpcMessage);
|
||||
m_netBindComponent->GetSendAuthorityToAutonomousRpcEvent().Signal(entityRpcMessage);
|
||||
return true;
|
||||
}
|
||||
case RpcValidationResult::ForwardToAuthority:
|
||||
{
|
||||
ScopedForwardingMessage forwarding(*this);
|
||||
m_netBindComponent->GetSendServerSimulationToServerAuthorityRpcEvent().Signal(entityRpcMessage);
|
||||
m_netBindComponent->GetSendServerToAuthorityRpcEvent().Signal(entityRpcMessage);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -119,8 +119,8 @@ namespace Multiplayer
|
||||
// Events
|
||||
RpcSendEvent::Handler m_onSendRpcHandler;
|
||||
RpcSendEvent::Handler m_onForwardRpcHandler;
|
||||
RpcSendEvent::Handler m_onSendClientAutonomousRpcHandler;
|
||||
RpcSendEvent::Handler m_onForwardClientAutonomousRpcHandler;
|
||||
RpcSendEvent::Handler m_onSendAutonomousRpcHandler;
|
||||
RpcSendEvent::Handler m_onForwardAutonomousRpcHandler;
|
||||
EntityDirtiedEvent::Handler m_onEntityDirtiedHandler;
|
||||
EntityStopEvent::Handler m_onEntityStopHandler;
|
||||
AZ::ScheduledEvent m_proxyRemovalEvent;
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Multiplayer
|
||||
|
||||
void PropertyPublisher::SetRebasing()
|
||||
{
|
||||
AZ_Assert(m_pendingRecord.GetNetworkRole() == NetEntityRole::ClientAutonomous, "Expected to be rebasing on a ClientAutonomous entity");
|
||||
AZ_Assert(m_pendingRecord.GetNetworkRole() == NetEntityRole::Autonomous, "Expected to be rebasing on a Autonomous entity");
|
||||
m_replicatorState = EntityReplicatorState::Rebasing;
|
||||
}
|
||||
|
||||
@@ -117,8 +117,8 @@ namespace Multiplayer
|
||||
// This is basically an Add record, but we don't want to send back predictable values
|
||||
m_sentRecords.clear();
|
||||
m_netBindComponent->FillTotalReplicationRecord(m_pendingRecord);
|
||||
// Don't send predictable properties back to the ClientAutonomous unless we correct them
|
||||
if (m_pendingRecord.GetNetworkRole() == NetEntityRole::ClientAutonomous)
|
||||
// Don't send predictable properties back to the Autonomous unless we correct them
|
||||
if (m_pendingRecord.GetNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_pendingRecord.Subtract(m_netBindComponent->GetPredictableRecord());
|
||||
}
|
||||
@@ -144,8 +144,8 @@ namespace Multiplayer
|
||||
m_pendingRecord.Append(*iter);
|
||||
}
|
||||
|
||||
// Don't send predictable properties back to the ClientAutonomous unless we correct them
|
||||
if (m_pendingRecord.GetNetworkRole() == NetEntityRole::ClientAutonomous)
|
||||
// Don't send predictable properties back to the Autonomous unless we correct them
|
||||
if (m_pendingRecord.GetNetworkRole() == NetEntityRole::Autonomous)
|
||||
{
|
||||
m_pendingRecord.Subtract(m_netBindComponent->GetPredictableRecord());
|
||||
}
|
||||
@@ -165,7 +165,7 @@ namespace Multiplayer
|
||||
AZ_Assert(m_netBindComponent, "NetBindComponent is nullptr");
|
||||
m_pendingRecord.ResetConsumedBits();
|
||||
m_pendingRecord.Serialize(serializer);
|
||||
m_netBindComponent->SerializeStateDeltaMessage(m_pendingRecord, serializer, ComponentSerializationType::Properties);
|
||||
m_netBindComponent->SerializeStateDeltaMessage(m_pendingRecord, serializer);
|
||||
return serializer.IsValid();
|
||||
}
|
||||
|
||||
|
||||
+42
-42
@@ -67,10 +67,10 @@ namespace Multiplayer
|
||||
bool ReplicationRecord::AreAllBitsConsumed() const
|
||||
{
|
||||
bool ret = true;
|
||||
ret &= m_authorityToClientConsumedBits == m_authorityToClientRecord.GetSize();
|
||||
ret &= m_authorityToServerConsumedBits == m_authorityToServerRecord.GetSize();
|
||||
ret &= m_authorityToAutonomousConsumedBits == m_authorityToAutonomousRecord.GetSize();
|
||||
ret &= m_autonomousToAuthorityConsumedBits == m_autonomousToAuthorityRecord.GetSize();
|
||||
ret &= m_authorityToClientConsumedBits == m_authorityToClient.GetSize();
|
||||
ret &= m_authorityToServerConsumedBits == m_authorityToServer.GetSize();
|
||||
ret &= m_authorityToAutonomousConsumedBits == m_authorityToAutonomous.GetSize();
|
||||
ret &= m_autonomousToAuthorityConsumedBits == m_autonomousToAuthority.GetSize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -86,37 +86,37 @@ namespace Multiplayer
|
||||
{
|
||||
ResetConsumedBits();
|
||||
|
||||
uint32_t recordSize = m_authorityToClientRecord.GetSize();
|
||||
m_authorityToClientRecord.Clear();
|
||||
m_authorityToClientRecord.Resize(recordSize);
|
||||
uint32_t recordSize = m_authorityToClient.GetSize();
|
||||
m_authorityToClient.Clear();
|
||||
m_authorityToClient.Resize(recordSize);
|
||||
|
||||
recordSize = m_authorityToServerRecord.GetSize();
|
||||
m_authorityToServerRecord.Clear();
|
||||
m_authorityToServerRecord.Resize(recordSize);
|
||||
recordSize = m_authorityToServer.GetSize();
|
||||
m_authorityToServer.Clear();
|
||||
m_authorityToServer.Resize(recordSize);
|
||||
|
||||
recordSize = m_authorityToAutonomousRecord.GetSize();
|
||||
m_authorityToAutonomousRecord.Clear();
|
||||
m_authorityToAutonomousRecord.Resize(recordSize);
|
||||
recordSize = m_authorityToAutonomous.GetSize();
|
||||
m_authorityToAutonomous.Clear();
|
||||
m_authorityToAutonomous.Resize(recordSize);
|
||||
|
||||
recordSize = m_autonomousToAuthorityRecord.GetSize();
|
||||
m_autonomousToAuthorityRecord.Clear();
|
||||
m_autonomousToAuthorityRecord.Resize(recordSize);
|
||||
recordSize = m_autonomousToAuthority.GetSize();
|
||||
m_autonomousToAuthority.Clear();
|
||||
m_autonomousToAuthority.Resize(recordSize);
|
||||
}
|
||||
|
||||
void ReplicationRecord::Append(const ReplicationRecord &rhs)
|
||||
{
|
||||
m_authorityToClientRecord |= rhs.m_authorityToClientRecord;
|
||||
m_authorityToServerRecord |= rhs.m_authorityToServerRecord;
|
||||
m_authorityToAutonomousRecord |= rhs.m_authorityToAutonomousRecord;
|
||||
m_autonomousToAuthorityRecord |= rhs.m_autonomousToAuthorityRecord;
|
||||
m_authorityToClient |= rhs.m_authorityToClient;
|
||||
m_authorityToServer |= rhs.m_authorityToServer;
|
||||
m_authorityToAutonomous |= rhs.m_authorityToAutonomous;
|
||||
m_autonomousToAuthority |= rhs.m_autonomousToAuthority;
|
||||
}
|
||||
|
||||
void ReplicationRecord::Subtract(const ReplicationRecord &rhs)
|
||||
{
|
||||
m_authorityToClientRecord.Subtract(rhs.m_authorityToClientRecord);
|
||||
m_authorityToServerRecord.Subtract(rhs.m_authorityToServerRecord);
|
||||
m_authorityToAutonomousRecord.Subtract(rhs.m_authorityToAutonomousRecord);
|
||||
m_autonomousToAuthorityRecord.Subtract(rhs.m_autonomousToAuthorityRecord);
|
||||
m_authorityToClient.Subtract(rhs.m_authorityToClient);
|
||||
m_authorityToServer.Subtract(rhs.m_authorityToServer);
|
||||
m_authorityToAutonomous.Subtract(rhs.m_authorityToAutonomous);
|
||||
m_autonomousToAuthority.Subtract(rhs.m_autonomousToAuthority);
|
||||
}
|
||||
|
||||
bool ReplicationRecord::HasChanges() const
|
||||
@@ -124,42 +124,42 @@ namespace Multiplayer
|
||||
bool hasChanges(false);
|
||||
if (ContainsAuthorityToClientBits())
|
||||
{
|
||||
hasChanges = hasChanges ? hasChanges : m_authorityToClientRecord.AnySet();
|
||||
hasChanges = hasChanges ? hasChanges : m_authorityToClient.AnySet();
|
||||
}
|
||||
if (ContainsAuthorityToServerBits())
|
||||
{
|
||||
hasChanges = hasChanges ? hasChanges : m_authorityToServerRecord.AnySet();
|
||||
hasChanges = hasChanges ? hasChanges : m_authorityToServer.AnySet();
|
||||
}
|
||||
if (ContainsAuthorityToAutonomousBits())
|
||||
{
|
||||
hasChanges = hasChanges ? hasChanges : m_authorityToAutonomousRecord.AnySet();
|
||||
hasChanges = hasChanges ? hasChanges : m_authorityToAutonomous.AnySet();
|
||||
}
|
||||
if (ContainsAutonomousToAuthorityBits())
|
||||
{
|
||||
hasChanges = hasChanges ? hasChanges : m_autonomousToAuthorityRecord.AnySet();
|
||||
hasChanges = hasChanges ? hasChanges : m_autonomousToAuthority.AnySet();
|
||||
}
|
||||
return hasChanges;
|
||||
}
|
||||
|
||||
bool ReplicationRecord::Serialize(AzNetworking::ISerializer& a_Serializer)
|
||||
bool ReplicationRecord::Serialize(AzNetworking::ISerializer& serializer)
|
||||
{
|
||||
if (ContainsAuthorityToClientBits())
|
||||
{
|
||||
a_Serializer.Serialize(m_authorityToClientRecord, "ServerToClientsRecord");
|
||||
serializer.Serialize(m_authorityToClient, "ServerToClientsRecord");
|
||||
}
|
||||
if (ContainsAuthorityToServerBits())
|
||||
{
|
||||
a_Serializer.Serialize(m_authorityToServerRecord, "ServerToServersRecord");
|
||||
serializer.Serialize(m_authorityToServer, "ServerToServersRecord");
|
||||
}
|
||||
if (ContainsAuthorityToAutonomousBits())
|
||||
{
|
||||
a_Serializer.Serialize(m_authorityToAutonomousRecord, "ServerToClientAutonomousRecord");
|
||||
serializer.Serialize(m_authorityToAutonomous, "ServerToAutonomousRecord");
|
||||
}
|
||||
if (ContainsAutonomousToAuthorityBits())
|
||||
{
|
||||
a_Serializer.Serialize(m_autonomousToAuthorityRecord, "ClientToServersRecord");
|
||||
serializer.Serialize(m_autonomousToAuthority, "ClientToServersRecord");
|
||||
}
|
||||
return a_Serializer.IsValid();
|
||||
return serializer.IsValid();
|
||||
}
|
||||
|
||||
void ReplicationRecord::ConsumeAuthorityToClientBits(uint32_t consumedBits)
|
||||
@@ -196,46 +196,46 @@ namespace Multiplayer
|
||||
|
||||
bool ReplicationRecord::ContainsAuthorityToClientBits() const
|
||||
{
|
||||
return (m_netEntityRole != NetEntityRole::ServerAuthority)
|
||||
return (m_netEntityRole != NetEntityRole::Authority)
|
||||
|| (m_netEntityRole == NetEntityRole::InvalidRole);
|
||||
}
|
||||
|
||||
bool ReplicationRecord::ContainsAuthorityToServerBits() const
|
||||
{
|
||||
return (m_netEntityRole == NetEntityRole::ServerSimulation)
|
||||
return (m_netEntityRole == NetEntityRole::Server)
|
||||
|| (m_netEntityRole == NetEntityRole::InvalidRole);
|
||||
}
|
||||
|
||||
bool ReplicationRecord::ContainsAuthorityToAutonomousBits() const
|
||||
{
|
||||
return (m_netEntityRole == NetEntityRole::ClientAutonomous || m_netEntityRole == NetEntityRole::ServerSimulation)
|
||||
return (m_netEntityRole == NetEntityRole::Autonomous || m_netEntityRole == NetEntityRole::Server)
|
||||
|| (m_netEntityRole == NetEntityRole::InvalidRole);
|
||||
}
|
||||
|
||||
bool ReplicationRecord::ContainsAutonomousToAuthorityBits() const
|
||||
{
|
||||
return (m_netEntityRole == NetEntityRole::ServerAuthority)
|
||||
return (m_netEntityRole == NetEntityRole::Authority)
|
||||
|| (m_netEntityRole == NetEntityRole::InvalidRole);
|
||||
}
|
||||
|
||||
uint32_t ReplicationRecord::GetRemainingAuthorityToClientBits() const
|
||||
{
|
||||
return m_authorityToClientConsumedBits < m_authorityToClientRecord.GetValidBitCount() ? m_authorityToClientRecord.GetValidBitCount() - m_authorityToClientConsumedBits : 0;
|
||||
return m_authorityToClientConsumedBits < m_authorityToClient.GetValidBitCount() ? m_authorityToClient.GetValidBitCount() - m_authorityToClientConsumedBits : 0;
|
||||
}
|
||||
|
||||
uint32_t ReplicationRecord::GetRemainingAuthorityToServerBits() const
|
||||
{
|
||||
return m_authorityToServerConsumedBits < m_authorityToServerRecord.GetValidBitCount() ? m_authorityToServerRecord.GetValidBitCount() - m_authorityToServerConsumedBits : 0;
|
||||
return m_authorityToServerConsumedBits < m_authorityToServer.GetValidBitCount() ? m_authorityToServer.GetValidBitCount() - m_authorityToServerConsumedBits : 0;
|
||||
}
|
||||
|
||||
uint32_t ReplicationRecord::GetRemainingAuthorityToAutonomousBits() const
|
||||
{
|
||||
return m_authorityToAutonomousConsumedBits < m_authorityToAutonomousRecord.GetValidBitCount() ? m_authorityToAutonomousRecord.GetValidBitCount() - m_authorityToAutonomousConsumedBits : 0;
|
||||
return m_authorityToAutonomousConsumedBits < m_authorityToAutonomous.GetValidBitCount() ? m_authorityToAutonomous.GetValidBitCount() - m_authorityToAutonomousConsumedBits : 0;
|
||||
}
|
||||
|
||||
uint32_t ReplicationRecord::GetRemainingAutonomousToAuthorityBits() const
|
||||
{
|
||||
return m_autonomousToAuthorityConsumedBits < m_autonomousToAuthorityRecord.GetValidBitCount() ? m_autonomousToAuthorityRecord.GetValidBitCount() - m_autonomousToAuthorityConsumedBits : 0;
|
||||
return m_autonomousToAuthorityConsumedBits < m_autonomousToAuthority.GetValidBitCount() ? m_autonomousToAuthority.GetValidBitCount() - m_autonomousToAuthorityConsumedBits : 0;
|
||||
}
|
||||
|
||||
ReplicationRecordStats ReplicationRecord::GetStats() const
|
||||
|
||||
@@ -79,10 +79,10 @@ namespace Multiplayer
|
||||
ReplicationRecordStats GetStats() const;
|
||||
|
||||
using RecordBitset = AzNetworking::FixedSizeVectorBitset<MaxRecordBits>;
|
||||
RecordBitset m_authorityToClientRecord;
|
||||
RecordBitset m_authorityToServerRecord;
|
||||
RecordBitset m_authorityToAutonomousRecord;
|
||||
RecordBitset m_autonomousToAuthorityRecord;
|
||||
RecordBitset m_authorityToClient;
|
||||
RecordBitset m_authorityToServer;
|
||||
RecordBitset m_authorityToAutonomous;
|
||||
RecordBitset m_autonomousToAuthority;
|
||||
|
||||
uint32_t m_authorityToClientConsumedBits = 0;
|
||||
uint32_t m_authorityToServerConsumedBits = 0;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Multiplayer
|
||||
{
|
||||
networkRole = netBindComponent->GetNetEntityRole();
|
||||
}
|
||||
if (networkRole != NetEntityRole::ClientAutonomous)
|
||||
if (networkRole != NetEntityRole::Autonomous)
|
||||
{
|
||||
AZ_Assert
|
||||
(
|
||||
@@ -118,7 +118,7 @@ namespace Multiplayer
|
||||
}
|
||||
else
|
||||
{
|
||||
AZLOG(NET_AuthTracker, "AuthTracker: Skipping timeout for ClientAutonomous networkEntityId %u", aznumeric_cast<uint32_t>(entityHandle.GetNetEntityId()));
|
||||
AZLOG(NET_AuthTracker, "AuthTracker: Skipping timeout for Autonomous networkEntityId %u", aznumeric_cast<uint32_t>(entityHandle.GetNetEntityId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace Multiplayer
|
||||
{
|
||||
networkRole = netBindComponent->GetNetEntityRole();
|
||||
}
|
||||
if (networkRole == NetEntityRole::ServerAuthority)
|
||||
if (networkRole == NetEntityRole::Authority)
|
||||
{
|
||||
return m_networkEntityManager.GetHostId();
|
||||
}
|
||||
@@ -205,7 +205,7 @@ namespace Multiplayer
|
||||
{
|
||||
networkRole = netBindComponent->GetNetEntityRole();
|
||||
}
|
||||
if (networkRole != NetEntityRole::ServerAuthority)
|
||||
if (networkRole != NetEntityRole::Authority)
|
||||
{
|
||||
AZLOG_ERROR
|
||||
(
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace Multiplayer
|
||||
|
||||
void NetworkEntityManager::HandleLocalRpcMessage(NetworkEntityRpcMessage& message)
|
||||
{
|
||||
AZ_Assert(message.GetRpcDeliveryType() == RpcDeliveryType::ServerSimulationToServerAuthority, "Only ServerSimulationToServerAuthority rpc messages can be locally deferred");
|
||||
AZ_Assert(message.GetRpcDeliveryType() == RpcDeliveryType::ServerToAuthority, "Only ServerToAuthority rpc messages can be locally deferred");
|
||||
m_localDeferredRpcMessages.emplace_back(AZStd::move(message));
|
||||
}
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ namespace Multiplayer
|
||||
RpcDeliveryType GetRpcDeliveryType() const;
|
||||
|
||||
//! Sets the current value for RpcDeliveryType.
|
||||
//! @param a_Value the value to set RpcDeliveryType to
|
||||
void SetRpcDeliveryType(RpcDeliveryType a_Value);
|
||||
//! @param value the value to set RpcDeliveryType to
|
||||
void SetRpcDeliveryType(RpcDeliveryType value);
|
||||
|
||||
//! Gets the current value of EntityId.
|
||||
//! @return the current value of EntityId
|
||||
@@ -72,7 +72,7 @@ namespace Multiplayer
|
||||
uint8_t GetRpcMessageType() const;
|
||||
|
||||
//! Writes the data contained inside a_Params to this NetworkEntityRpcMessage's blob buffer.
|
||||
//! @param a_Params the parameters to save inside this NetworkEntityRpcMessage instance
|
||||
//! @param params the parameters to save inside this NetworkEntityRpcMessage instance
|
||||
bool SetRpcParams(IRpcParamStruct& params);
|
||||
|
||||
//! Reads the data contained inside this NetworkEntityRpcMessage's blob buffer and stores them in outParams.
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Multiplayer
|
||||
const NetworkInput& GetNetworkInput() const;
|
||||
NetworkInput& GetNetworkInput();
|
||||
|
||||
bool Serialize(AzNetworking::ISerializer& a_Serializer);
|
||||
bool Serialize(AzNetworking::ISerializer& serializer);
|
||||
private:
|
||||
ConstNetworkEntityHandle m_owner;
|
||||
NetworkInput m_networkInput;
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Multiplayer
|
||||
|
||||
//! Constructor.
|
||||
//! @param connectionId the connectionId of the connection that owns the object.
|
||||
RewindableObject(AzNetworking::ConnectionId owningConnectionId);
|
||||
RewindableObject(const BASE_TYPE& value);
|
||||
|
||||
//! Copy construct from underlying base type.
|
||||
//! @param value base type value to construct from
|
||||
@@ -52,6 +52,10 @@ namespace Multiplayer
|
||||
//! @param rhs rewindable history buffer to assign from
|
||||
RewindableObject& operator = (const RewindableObject& rhs);
|
||||
|
||||
//! Sets the owning connectionId for the given rewindable object instance.
|
||||
//! @param owningConnectionId the new connectionId to use as the owning connectionId.
|
||||
void SetOwningConnectionId(AzNetworking::ConnectionId owningConnectionId);
|
||||
|
||||
//! Const base type operator.
|
||||
//! @return value in const base type form
|
||||
operator const BASE_TYPE&() const;
|
||||
@@ -106,4 +110,9 @@ namespace Multiplayer
|
||||
};
|
||||
}
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_TEMPLATE(Multiplayer::RewindableObject, "{B2937B44-FEE1-4277-B1E0-863DE76D363F}", AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_AUTO);
|
||||
}
|
||||
|
||||
#include <Source/NetworkTime/RewindableObject.inl>
|
||||
|
||||
@@ -15,10 +15,9 @@
|
||||
namespace Multiplayer
|
||||
{
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
inline RewindableObject<BASE_TYPE, REWIND_SIZE>::RewindableObject(AzNetworking::ConnectionId owningConnectionId)
|
||||
: m_owningConnectionId(owningConnectionId)
|
||||
inline RewindableObject<BASE_TYPE, REWIND_SIZE>::RewindableObject(const BASE_TYPE& value)
|
||||
{
|
||||
m_history.fill(BASE_TYPE());
|
||||
m_history.fill(value);
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
@@ -53,6 +52,12 @@ namespace Multiplayer
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
inline void RewindableObject<BASE_TYPE, REWIND_SIZE>::SetOwningConnectionId(AzNetworking::ConnectionId owningConnectionId)
|
||||
{
|
||||
m_owningConnectionId = owningConnectionId;
|
||||
}
|
||||
|
||||
template <typename BASE_TYPE, AZStd::size_t REWIND_SIZE>
|
||||
inline RewindableObject<BASE_TYPE, REWIND_SIZE>::operator const BASE_TYPE& () const
|
||||
{
|
||||
|
||||
+11
-11
@@ -165,8 +165,8 @@ namespace Multiplayer
|
||||
}
|
||||
|
||||
// Add in Autonomous Entities
|
||||
// Note: Do not add any ClientSimulation entities after this point, otherwise you stomp over the ClientAutonomous mode
|
||||
m_replicationSet[m_controlledEntity] = { NetEntityRole::ClientAutonomous, 1.0f }; // Always replicate autonomous entities
|
||||
// Note: Do not add any Client entities after this point, otherwise you stomp over the Autonomous mode
|
||||
m_replicationSet[m_controlledEntity] = { NetEntityRole::Autonomous, 1.0f }; // Always replicate autonomous entities
|
||||
|
||||
//auto hierarchyController = FindController<EntityHierarchyComponent::Authority>(m_ControlledEntity);
|
||||
//if (hierarchyController != nullptr)
|
||||
@@ -277,7 +277,7 @@ namespace Multiplayer
|
||||
if (!sv_ReplicateServerProxies)
|
||||
{
|
||||
NetBindComponent* netBindComponent = entityHandle.GetNetBindComponent();
|
||||
if ((netBindComponent != nullptr) && (netBindComponent->GetNetEntityRole() == NetEntityRole::ServerSimulation))
|
||||
if ((netBindComponent != nullptr) && (netBindComponent->GetNetEntityRole() == NetEntityRole::Server))
|
||||
{
|
||||
// Proxy replication disabled
|
||||
return;
|
||||
@@ -296,28 +296,28 @@ namespace Multiplayer
|
||||
m_replicationSet.erase(removeEnt);
|
||||
}
|
||||
m_candidateQueue.push(PrioritizedReplicationCandidate(entityHandle, priority));
|
||||
m_replicationSet[entityHandle] = { NetEntityRole::ClientSimulation, priority };
|
||||
m_replicationSet[entityHandle] = { NetEntityRole::Client, priority };
|
||||
}
|
||||
}
|
||||
|
||||
//void ServerToClientReplicationWindow::CollectControlledEntitiesRecursive(ReplicationSet& a_ReplicationSet, EntityHierarchyComponent::Authority& a_HierarchyController)
|
||||
//void ServerToClientReplicationWindow::CollectControlledEntitiesRecursive(ReplicationSet& replicationSet, EntityHierarchyComponent::Authority& hierarchyController)
|
||||
//{
|
||||
// auto controlledEnts = a_HierarchyController.GetChildrenRelatedEntities();
|
||||
// auto controlledEnts = hierarchyController.GetChildrenRelatedEntities();
|
||||
// for (auto& controlledEnt : controlledEnts)
|
||||
// {
|
||||
// AZ_Assert(controlledEnt != nullptr, "We have lost a controlled entity unexpectedly");
|
||||
// a_ReplicationSet[controlledEnt.GetConstEntity()] = EntityReplicationData(EntityNetworkRoleT::e_ClientAutonomous, EntityPrioritySystem::k_MaxPriority); // Always replicate controlled entities
|
||||
// replicationSet[controlledEnt.GetConstEntity()] = EntityReplicationData(EntityNetworkRoleT::e_Autonomous, EntityPrioritySystem::k_MaxPriority); // Always replicate controlled entities
|
||||
// auto hierarchyController = controlledEnt.FindController<EntityHierarchyComponent::Authority>();
|
||||
// if (hierarchyController != nullptr)
|
||||
// {
|
||||
// CollectControlledEntitiesRecursive(a_ReplicationSet, *hierarchyController);
|
||||
// CollectControlledEntitiesRecursive(replicationSet, *hierarchyController);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//void ServerToClientReplicationWindow::OnAddFilteredEntity(NetEntityId a_FitleredEntityId)
|
||||
//void ServerToClientReplicationWindow::OnAddFilteredEntity(NetEntityId filteredEntityId)
|
||||
//{
|
||||
// ConstEntityPtr filteredEntity = gNovaGame->GetEntityManager().GetEntity(a_FitleredEntityId);
|
||||
// m_replicationSet.erase(filteredEntity);
|
||||
// ConstEntityPtr filteredEntity = gNovaGame->GetEntityManager().GetEntity(filteredEntityId);
|
||||
// m_replicationSet.erase(filteredEntityId);
|
||||
//}
|
||||
}
|
||||
|
||||
@@ -62,26 +62,26 @@ namespace Multiplayer
|
||||
void OnEntityDeactivated(const AZ::EntityId&) override;
|
||||
//! @}
|
||||
|
||||
//void CollectControlledEntitiesRecursive(ReplicationSet& a_ReplicationSet, EntityHierarchyComponent::Authority& a_HierarchyController);
|
||||
//void OnAddFilteredEntity(EntityIdT a_FitleredEntityId);
|
||||
//void CollectControlledEntitiesRecursive(ReplicationSet& replicationSet, EntityHierarchyComponent::Authority& hierarchyController);
|
||||
//void OnAddFilteredEntity(NetEntityId filteredEntityId);
|
||||
|
||||
void EvaluateConnection();
|
||||
void AddEntityToReplicationSet(ConstNetworkEntityHandle& entityHandle, float priority, float distanceSquared);
|
||||
|
||||
ServerToClientReplicationWindow& operator=(const ServerToClientReplicationWindow&) = delete;
|
||||
|
||||
NetworkEntityHandle m_controlledEntity;
|
||||
AZ::TransformInterface* m_controlledEntityTransform = nullptr;
|
||||
|
||||
//FilteredEntityComponent::Authority* mp_ControlledFilteredEntityComponent = nullptr;
|
||||
//NetSystemComponent* mp_ControlledNetSystemComponent = nullptr;
|
||||
|
||||
// sorted in reverse, lowest priority is the top()
|
||||
ReplicationCandidateQueue m_candidateQueue;
|
||||
ReplicationSet m_replicationSet;
|
||||
|
||||
AZ::ScheduledEvent m_updateWindowEvent;
|
||||
|
||||
NetworkEntityHandle m_controlledEntity;
|
||||
AZ::TransformInterface* m_controlledEntityTransform = nullptr;
|
||||
|
||||
//FilteredEntityComponent::Authority* m_controlledFilteredEntityComponent = nullptr;
|
||||
//NetBindComponent* m_controlledNetBindComponent = nullptr;
|
||||
|
||||
const AzNetworking::IConnection* m_connection = nullptr;
|
||||
float m_minPriorityReplicated = 0.0f; ///< Lowest replicated entity priority in last update
|
||||
|
||||
|
||||
@@ -55,14 +55,14 @@ namespace Multiplayer
|
||||
if (netBindComponent != nullptr)
|
||||
{
|
||||
NetEntityRole networkRole = netBindComponent->GetNetEntityRole();
|
||||
if (networkRole == NetEntityRole::ServerAuthority)
|
||||
if (networkRole == NetEntityRole::Authority)
|
||||
{
|
||||
const AZ::Entity* entity = entityHandle.GetEntity();
|
||||
AZ::TransformInterface* transformInterface = entity->GetTransform();
|
||||
AZ::Vector3 entityPosition = transformInterface->GetWorldTranslation();
|
||||
if (m_aabb.Contains(entityPosition))
|
||||
{
|
||||
outNetworkRole = Multiplayer::NetEntityRole::ServerSimulation;
|
||||
outNetworkRole = Multiplayer::NetEntityRole::Server;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -88,9 +88,9 @@ namespace Multiplayer
|
||||
if (netBindComponent != nullptr)
|
||||
{
|
||||
NetEntityRole networkRole = netBindComponent->GetNetEntityRole();
|
||||
if (networkRole == NetEntityRole::ServerAuthority)
|
||||
if (networkRole == NetEntityRole::Authority)
|
||||
{
|
||||
m_replicationSet[entityHandle] = { NetEntityRole::ServerSimulation, 0.0f }; // Note, server replication does not use priority
|
||||
m_replicationSet[entityHandle] = { NetEntityRole::Server, 0.0f }; // Note, server replication does not use priority
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,7 +130,7 @@ namespace Multiplayer
|
||||
NetEntityRole networkRole = NetEntityRole::InvalidRole;
|
||||
if (IsInWindow(entityHandle, networkRole))
|
||||
{
|
||||
m_replicationSet[entityHandle] = { NetEntityRole::ServerSimulation, 0.0f };
|
||||
m_replicationSet[entityHandle] = { NetEntityRole::Server, 0.0f };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user