/* * 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. * */ #ifndef INCLUDE_NETWORKGRIDMATE_HEADER #define INCLUDE_NETWORKGRIDMATE_HEADER #pragma once #include "NetworkGridMateCommon.h" #include "NetworkGridMateSessionEvents.h" #include "NetworkGridMateSystemEvents.h" #include "NetworkGridMateProfiling.h" #include "Replicas/EntityReplicaSpawnParams.h" #include namespace GridMate { class SecureSocketDriver; /*! * Implementation of INetwork interface for GridMate-backed network. */ class Network : public INetwork , public IEntitySystemSink , public ILevelSystemListener , private NetSerialize::ILegacySerializeProvider { public: friend class SessionEvents; friend class NetworkSystemEvents; static Network& Get(); Network(); virtual ~Network(); public: typedef AZStd::unordered_map> EntityReplicaMap; public: // INetwork implementation. IGridMate* GetGridMate() override { return m_gridMate; } //! Helper for grabbing the channel id corresponding to a particular session member. ChannelId GetChannelIdForSessionMember(GridMate::GridMember* member) const override; //! Stores a pointer of the active game context to the network layer for internal use. void SetGameContext(IGameContext* gameContext) override; //! Main module initialization, called by engine. bool Init(int ncpu); //! Legacy cleanup functions invoked by the engine. void Release() override; //! Main update routine invoked by the engine. void SyncWithGame(ENetworkGameSync syncType) override; //! Marks an aspect dirty. This will trigger a NetSerialize invocation, after which //! we'll determine if a re-send is necessary. void ChangedAspects(EntityId id, NetworkAspectType aspectBits) override; //! Retrieve the local user's channel Id. ChannelId GetLocalChannelId() const override; //! Retrieve the channel Id of the server we're connected to. //! If we are the server, we simply return our own channel Id. ChannelId GetServerChannelId() const override; //! Convert a local entity Id to the server side Id, since they can vary across //! systems. //! Before dispatching messages or events to the server or other clients, local //! Ids should be converted to server Ids so they can be properly deciphered. EntityId LocalEntityIdToServerEntityId(EntityId localId) const override; //! Convert a server entity Id to a local entity Id so we can dispatch messages //! to local objects. EntityId ServerEntityIdToLocalEntityId(EntityId serverId, bool allowForcedEstablishment = false) const override; //! Gets the synchronized network time as milliseconds since session creation time. virtual CTimeValue GetSessionTime() override; //////////////////////////////////////////////////////////////// //! Compatibility "Shim" interfaces. //! Invoke a legacy game object RMI through GridMate RPCs. void InvokeRMI(IGameObject* gameObject, IRMIRep& rep, void* params, ChannelId targetChannelFilter, uint32 where) override; //! Invoke a GameCore actor RMI through GridMate RPCs. void InvokeActorRMI(EntityId entityId, uint8 actorExtensionId, ChannelId targetChannelFilter, IActorRMIRep& rep) override; //! Invoke a lua script RMI through GridMate RPCs. void InvokeScriptRMI(ISerializable* serializable, bool isServerRMI, ChannelId toChannelId = kInvalidChannelId, ChannelId avoidChannelId = kInvalidChannelId) override; //! Registers an actor RMI rep; required for dispatching to the game upon receipt. void RegisterActorRMI(IActorRMIRep* rep) override; void UnregisterActorRMI(IActorRMIRep* rep) override; //! Sets mask describing which aspects are globally delegatable. void SetDelegatableAspectMask(NetworkAspectType aspectBits) override; //! Sets mask on a given obejct describing which aspect that object has delegated to the controlling client. void SetObjectDelegatedAspectMask(EntityId entityId, NetworkAspectType aspects, bool set) override; //! Request authority for entityId be delegated to client at clientChannelId. void DelegateAuthorityToClient(EntityId entityId, ChannelId clientChannelId) override; //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //! Currently unused INetwork APIs. void GetMemoryStatistics(ICrySizer* pSizer) override { (void)pSizer; }; const char* GetHostName() override { return ""; } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //! Other INetwork API functions still applicable to GridMate. void GetBandwidthStatistics(SBandwidthStats* const pStats) override; void GetPerformanceStatistics(SNetworkPerformance* pSizer) override; void GetProfilingStatistics(SNetworkProfilingStats* const pStats) override; //////////////////////////////////////////////////////////////// bool IsInMinimalUpdate() const; public: // GridMate-integration-specific APIs //! Returns true if it's safe to spawn replicated entities at this time. //! An example of a time during which this is not safe would be during a local level load. bool AllowEntityCreation() const; //! Set the current game context replica, which represents current level and game rules per the server. void SetGameContextReplica(GameContextReplica* replica); //! Retrieve the current game context replica, which represents current level and game rules per the server. GameContextReplica* GetGameContextReplica() const { return m_gameContextReplica; } //! Returns the active client or server session. GridSession* GetCurrentSession() { return m_session; } //! Locate the replica for a service-side entity Id. EntityReplica* FindEntityReplica(EntityId id) const; //! Retrieves the global replica registration, mapped by server-side entity Id. EntityReplicaMap& GetEntityReplicaMap() { return m_activeEntityReplicaMap; } //! Retrieves new proxy registrations, mapped by server-side entity Id. EntityReplicaMap& GetNewProxyEntityMap() { return m_newProxyEntities; } //////////////////////////////////////////////////////////////// //! IEntitySystemSink callbacks. void OnSpawn(IEntity* pEntity, SEntitySpawnParams& params) override; bool OnRemove(IEntity* pEntity) override; bool OnBeforeSpawn(SEntitySpawnParams& params) override { (void)params; return true; } void OnReused(IEntity* pEntity, SEntitySpawnParams& params) override { (void)pEntity; (void)params; } void OnEvent(IEntity* pEntity, SEntityEvent& event) override { (void)pEntity; (void)event; } void GetMemoryUsage(class ICrySizer* pSizer) const override { (void)pSizer; } //////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// //! ILevelSystemListener callbacks. void OnLoadingComplete(ILevel* level) override; void OnUnloadComplete(ILevel* level) override; //////////////////////////////////////////////////////////////// GameStatistics& GetGameStatistics(); CarrierStatistics GetCarrierStatistics(); //! Pumps GridMate instance. void UpdateGridMate(ENetworkGameSync syncType); //! Instantiates GridMate instance. //! Create replicas for newly-spawned entities (server only). void BindNewEntitiesToNetwork(); //! Execute deferred tasks. void FlushPostFrameTasks(); //! Bandwidth statistics and profiling. void UpdateNetworkStatistics(); void ClearNetworkStatistics(); void DumpNetworkStatistics(); void DebugDraw(); void SetLegacySerializeProvider(NetSerialize::ILegacySerializeProvider* provider) { m_legacySerializeProvider = provider; } NetSerialize::ILegacySerializeProvider* GetLegacySerializeProvider() { return m_legacySerializeProvider; } private: // ILegacySerializeProvider implementation void AcquireSerializer(WriteBuffer& wb, NetSerialize::AcquireSerializeCallback callback) override; void AcquireDeserializer(ReadBuffer& rb, NetSerialize::AcquireSerializeCallback callback) override; //! Instantiates GridMate void StartGridMate(); //! Shuts down GridMate instance. void ShutdownGridMate(); //! Sets globals and context flags appropriate for an active server hosting a session. void MarkAsConnectedServer(); //! Sets globals and context flags for a client connected to a hosted session. void MarkAsConnectedClient(); //! Sets globals and context flags for a single-player instance. void MarkAsLocalOnly(); typedef std::map CarrierStatisticsMap; typedef std__hash_map NewEntitiesMap; //! Connection statistics for each outgoing channel. CarrierStatisticsMap m_statisticsPerChannel; //! Statistics for incoming/outgoing RMIs and aspects (global and per-entity). GameStatistics m_gameStatistics; //! The local "channel id", required by CryEngine to know which //! client owns which actor. ChannelId m_localChannelId; //! Pointer to game context (CryEngine). IGameContext* m_gameContext; //! Pointer to GridMate instance. GridMate::IGridMate* m_gridMate; //! Pointer to MP session GridMate::GridSession* m_session; //! Pointer to game session replica. GameContextReplica* m_gameContextReplica; //! Maintain a map of entity replicas per their server-side entity Id. EntityReplicaMap m_activeEntityReplicaMap; EntityReplicaMap m_newProxyEntities; //! Stores a map of entities spawned this frame, so we can instantiate replicas //! once it's safe to do so. NewEntitiesMap m_newServerEntities; //! EBus handlers for GridMate sessions. SessionEvents m_sessionEvents; //! EBus handlers for various system events. NetworkSystemEvents m_systemEvents; //! Used so areas of the network can be aware that we're loading a level. enum LevelLoadState { LevelLoadState_None, LevelLoadState_Loading, LevelLoadState_Loaded }; AZStd::atomic m_levelLoadState; //! Set if we're currently in a GridMate update. AZStd::mutex m_mutexUpdatingGridMate; //! Inherited from CryNetwork, this is sent by the NetworkStallTicker mechanism //! to tell us it's unsafe to process minimal network updates (loading updates). AZStd::atomic m_allowMinimalUpdate; typedef AZStd::function Task; std::vector m_postFrameTasks; NetSerialize::ILegacySerializeProvider* m_legacySerializeProvider; static Network* s_instance; public: // Profiler settings. static int s_StatsIntervalMS; static int s_DumpStatsEnabled; static FILE* s_DumpStatsFile; }; } // namespace GridMate /// External systems expect the type 'CNetwork' in the global namespace. typedef GridMate::Network CNetwork; #endif // INCLUDE_NETWORKGRIDMATE_HEADER