/* * 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. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Message definition to id management #pragma once #include #define NUM_ASPECTS 32 // Number of GameObject aspects supported. #define MAXIMUM_NUMBER_OF_CONNECTIONS 64 // Maximum number of connections supported. #if defined(AZ_RESTRICTED_PLATFORM) #if defined(AZ_PLATFORM_XENIA) #include "Xenia/INetwork_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/INetwork_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/INetwork_h_salem.inl" #endif #endif #if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED) #undef AZ_RESTRICTED_SECTION_IMPLEMENTED #else #define LOBBY_DEFAULT_PORT 30090 // Default local UDP port. #endif #define SERVER_DEFAULT_PORT LOBBY_DEFAULT_PORT #define SERVER_DEFAULT_PORT_STRING #SERVER_DEFAULT_PORT static const int NumAspects = NUM_ASPECTS; #define _CRYNETWORK_CONCAT(x, y) x ## y #define CRYNETWORK_CONCAT(x, y) _CRYNETWORK_CONCAT(x, y) #define ASPECT_TYPE CRYNETWORK_CONCAT(uint, NUM_ASPECTS) typedef ASPECT_TYPE NetworkAspectType; typedef uint8 NetworkAspectID; #define NET_ASPECT_ALL (NetworkAspectType(0xFFFFFFFF)) typedef uint32 CryLobbyTaskID; typedef uint32 ECryLobbyError; struct ISerializableInfo : public CMultiThreadRefCount , public ISerializable {}; typedef _smart_ptr ISerializableInfoPtr; typedef uint32 ChannelId; // Network channel id (derived from GridMember) static const ChannelId kInvalidChannelId = ChannelId(0); static const ChannelId kOfflineChannelId = ChannelId(1); static const EntityId kInvalidEntityId = (EntityId)0; #define NET_PROFILE_COUNT_READ_BITS(count) #define NET_PROFILE_BEGIN(string, read) #define NET_PROFILE_BEGIN_BUDGET(string, read, budget) #define NET_PROFILE_BEGIN_RMI(string, read) #define NET_PROFILE_END() #define NET_PROFILE_SCOPE(string, read) #define NET_PROFILE_SCOPE_RMI(string, read) #define NET_PROFILE_SCOPE_BUDGET(string, read, budget) enum ENetReliabilityType { eNRT_ReliableOrdered, eNRT_ReliableUnordered, eNRT_UnreliableOrdered, eNRT_UnreliableUnordered, // Must be last. eNRT_NumReliabilityTypes }; // Description: // Implementation of CContextView relies on the first two values being // as they are. enum ERMIAttachmentType { eRAT_PreAttach = 0, eRAT_PostAttach = 1, eRAT_NoAttach, // Must be last. eRAT_NumAttachmentTypes }; struct SNetworkPerformance { uint64 m_nNetworkSync; float m_threadTime; }; enum ENetworkGameSync { eNGS_FrameStart = 0, eNGS_FrameEnd, eNGS_Shutdown_Clear, eNGS_Shutdown, eNGS_MinimalUpdateForLoading, // Internal use - workaround for sync loading problems eNGS_AllowMinimalUpdate, eNGS_DenyMinimalUpdate, // must be last eNGS_NUM_ITEMS }; #define STATS_MAX_MESSAGEQUEUE_ACCOUNTING_GROUPS (64) struct SAccountingGroupStats { SAccountingGroupStats() : m_sends(0) , m_bandwidthUsed(0.0f) , m_totalBandwidthUsed(0.0f) , m_priority(0) , m_maxLatency(0.0f) , m_discardLatency(0.0f) , m_inUse(false) { memset(m_name, 0, sizeof(m_name)); } char m_name[8]; uint32 m_sends; float m_bandwidthUsed; float m_totalBandwidthUsed; uint32 m_priority; float m_maxLatency; float m_discardLatency; bool m_inUse; }; struct SMessageQueueStats { SMessageQueueStats() : m_usedPacketSize(0) , m_sentMessages(0) , m_unsentMessages(0) { } SAccountingGroupStats m_accountingGroup[STATS_MAX_MESSAGEQUEUE_ACCOUNTING_GROUPS]; uint32 m_usedPacketSize; uint16 m_sentMessages; uint16 m_unsentMessages; }; #define STATS_MAX_NUMBER_OF_CHANNELS (MAXIMUM_NUMBER_OF_CONNECTIONS + 1) #define STATS_MAX_NAME_SIZE (32) struct SNetChannelStats { SNetChannelStats() : m_ping(0) , m_pingSmoothed(0) , m_bandwidthInbound(0.0f) , m_bandwidthOutbound(0.0f) , m_bandwidthShares(0) , m_desiredPacketRate(0) , m_currentPacketRate(0.0f) , m_packetLossRate(0.0f) , m_maxPacketSize(0) , m_idealPacketSize(0) , m_sparePacketSize(0) , m_idle(false) , m_inUse(false) { memset(m_name, 0, sizeof(m_name)); } SMessageQueueStats m_messageQueue; char m_name[STATS_MAX_NAME_SIZE]; uint32 m_ping; uint32 m_pingSmoothed; float m_bandwidthInbound; float m_bandwidthOutbound; uint32 m_bandwidthShares; uint32 m_desiredPacketRate; float m_currentPacketRate; float m_packetLossRate; uint32 m_maxPacketSize; uint32 m_idealPacketSize; uint32 m_sparePacketSize; bool m_idle; bool m_inUse; }; struct SBandwidthStatsSubset { SBandwidthStatsSubset() : m_totalBandwidthSent(0) , m_lobbyBandwidthSent(0) , m_fragmentBandwidthSent(0) , m_aspectPayloadBitsSent(0) , m_rmiPayloadBitsSent(0) , m_totalBandwidthRecvd(0) , m_totalPacketsSent(0) , m_totalPacketsDropped(0) , m_lobbyPacketsSent(0) , m_fragmentPacketsSent(0) , m_totalPacketsRecvd(0) { } uint64 m_totalBandwidthSent; uint64 m_lobbyBandwidthSent; uint64 m_fragmentBandwidthSent; uint64 m_aspectPayloadBitsSent; uint64 m_rmiPayloadBitsSent; uint64 m_totalBandwidthRecvd; int m_totalPacketsSent; uint64 m_totalPacketsDropped; int m_lobbyPacketsSent; int m_fragmentPacketsSent; int m_totalPacketsRecvd; }; struct SBandwidthStats { SBandwidthStats() : m_total() , m_prev() , m_1secAvg() , m_10secAvg() { } SBandwidthStatsSubset TickDelta() { SBandwidthStatsSubset ret; ret.m_totalBandwidthSent = m_total.m_totalBandwidthSent - m_prev.m_totalBandwidthSent; ret.m_lobbyBandwidthSent = m_total.m_lobbyBandwidthSent - m_prev.m_lobbyBandwidthSent; ret.m_fragmentBandwidthSent = m_total.m_fragmentBandwidthSent - m_prev.m_fragmentBandwidthSent; ret.m_aspectPayloadBitsSent = m_total.m_aspectPayloadBitsSent - m_prev.m_aspectPayloadBitsSent; ret.m_rmiPayloadBitsSent = m_total.m_rmiPayloadBitsSent - m_prev.m_rmiPayloadBitsSent; ret.m_totalBandwidthRecvd = m_total.m_totalBandwidthRecvd - m_prev.m_totalBandwidthRecvd; ret.m_totalPacketsSent = m_total.m_totalPacketsSent - m_prev.m_totalPacketsSent; ret.m_lobbyPacketsSent = m_total.m_lobbyPacketsSent - m_prev.m_lobbyPacketsSent; ret.m_fragmentPacketsSent = m_total.m_fragmentPacketsSent - m_prev.m_fragmentPacketsSent; ret.m_totalPacketsRecvd = m_total.m_totalPacketsRecvd - m_prev.m_totalPacketsRecvd; ret.m_totalPacketsDropped = m_total.m_totalPacketsDropped - m_prev.m_totalPacketsDropped; return ret; } SBandwidthStatsSubset m_total; SBandwidthStatsSubset m_prev; SBandwidthStatsSubset m_1secAvg; SBandwidthStatsSubset m_10secAvg; SNetChannelStats m_channel[STATS_MAX_NUMBER_OF_CHANNELS]; uint32 m_numChannels; }; struct SProfileInfoStat { SProfileInfoStat() : m_name("") , m_totalBits(0) , m_calls(0) , m_rmi(false) { } string m_name; uint32 m_totalBits; uint32 m_calls; bool m_rmi; }; typedef DynArray ProfileLeafList; struct SNetworkProfilingStats { SNetworkProfilingStats() : m_ProfileInfoStats() , m_numBoundObjects(0) , m_maxBoundObjects(0) { } ProfileLeafList m_ProfileInfoStats; uint m_numBoundObjects; uint m_maxBoundObjects; }; enum EDisconnectionCause { // This cause must be first! - timeout occurred. eDC_Timeout = 0, // Incompatible protocols. eDC_ProtocolError, // Failed to resolve an address. eDC_ResolveFailed, // Versions mismatch. eDC_VersionMismatch, // Server is full. eDC_ServerFull, // User initiated kick. eDC_Kicked, // Teamkill ban/ admin ban. eDC_Banned, // Context database mismatch. eDC_ContextCorruption, // Password mismatch, cdkey bad, etc. eDC_AuthenticationFailed, // Misc. game error. eDC_GameError, // DX11 not found. eDC_NotDX11Capable, // The nub has been destroyed. eDC_NubDestroyed, // Icmp reported error. eDC_ICMPError, // NAT negotiation error. eDC_NatNegError, // Demo playback finished. eDC_DemoPlaybackFinished, // Demo playback file not found. eDC_DemoPlaybackFileNotFound, // User decided to stop playing. eDC_UserRequested, // User should have controller connected. eDC_NoController, // Unable to connect to server. eDC_CantConnect, // Arbitration failed in a live arbitrated session. eDC_ArbitrationFailed, // Failed to successfully join migrated game eDC_FailedToMigrateToNewHost, // The session has just been deleted eDC_SessionDeleted, // Kicked due to having a high ping eDC_KickedHighPing, // Kicked due to reserved user joining eDC_KickedReservedUser, // Class registry mismatch eDC_ClassRegistryMismatch, // Global ban eDC_GloballyBanned, // Global ban stage 1 messaging eDC_Global_Ban1, // Global ban stage 2 messaging eDC_Global_Ban2, // This cause must be last! - unknown cause. eDC_Unknown }; enum EAspectFlags { // aspect will not be sent to clients that don't control the entity eAF_ServerControllerOnly = 0x04, // aspect is serialized without using compression manager (useful for data that is allready well quantised/compressed) eAF_NoCompression = 0x08, // aspect can be client controlled (delegated to the client) eAF_Delegatable = 0x10, // aspect has more than one profile (serialization format) eAF_ServerManagedProfile = 0x20, // client should periodically send a hash of what it thinks the current state of an aspect is // this hash is compared to the server hash and forces a server update if there's a mismatch eAF_HashState = 0x40, // aspect needs a timestamp to make sense (i.e. physics) eAF_TimestampState = 0x80, }; struct IGameObjectExtension; /*! * Crytek RMI representation. RMI declaration/impl macros subclass this, allowing * the network layer to callback for param serialization and invocation. * The derived classes are created statically by RMI impl macros, and assigned a * unique Id for lookup on the receiving end. */ class IRMIRep { public: IRMIRep() : m_uniqueId(0) {} virtual ~IRMIRep() {} virtual const char* GetDebugName() const = 0; virtual void SerializeParamsToBuffer(TSerialize ser, void* params) = 0; virtual void* SerializeParamsFromBuffer(TSerialize ser) = 0; virtual bool IsServerRMI() const = 0; virtual void Invoke(IGameObjectExtension* extension, void* params) = 0; void SetUniqueId(uint32 uniqueId) { m_uniqueId = uniqueId; } uint32 GetUniqueId() const { return m_uniqueId; } bool operator == (const size_t compareId) const { return GetUniqueId() == compareId; } private: uint32 m_uniqueId; }; /*! * Actor (GameCore) RMI representation. RMI declaration/impl macros subclass this, * allowing the network layer to callback for param serialization and invocation. * A unique ID is also maintained to enable lookup on the receiving end. IDs are * assigned when the rep is 'registered' via RegisterActorRMI(). */ class IActorRMIRep { public: IActorRMIRep() : m_uniqueId(0) {} virtual ~IActorRMIRep() {} virtual uint32 GetReliability() const = 0; virtual uint32 GetWhere() const = 0; virtual void SerializeParams(TSerialize ser) = 0; virtual void Invoke(EntityId entityId, uint8 actorExtensionId) = 0; virtual const char* GetDebugName() const = 0; void SetUniqueId(uint32 uniqueId) { m_uniqueId = uniqueId; } uint32 GetUniqueId() const { return m_uniqueId; } bool operator == (const size_t compareId) const { return GetUniqueId() == compareId; } bool operator < (const size_t compareId) const { return GetUniqueId() <= compareId; } private: uint32 m_uniqueId; }; struct SGameStartParams; // Description: // Interface for a channel to call in order to create/destroy objects, and when changing // context, to properly configure that context. struct IGameContext { // virtual ~IGameContext() {} virtual void SetGameStarted(bool started) = 0; virtual void PlayerIdSet(EntityId id) = 0; virtual const SGameStartParams& GetAppliedParams() const = 0; virtual void SetContextFlags(unsigned flags) = 0; virtual uint32 GetContextFlags() = 0; virtual int GetPlayerCount() = 0; virtual void GetMemoryStatistics(ICrySizer* pSizer) {}; // }; // GridMate forwards namespace GridMate { class IGridMate; class Replica; class GridSearch; class GridMember; class GridSession; struct SessionParams; struct SearchInfo; struct InviteInfo; struct SearchParams; struct CarrierDesc; } // namespace GridMate struct INetwork { public: // Description: // Releases the interface (and delete the object that implements it). virtual void Release() = 0; // Description: // Gathers memory statistics for the network module. virtual void GetMemoryStatistics(ICrySizer* pSizer) = 0; // Description: // Gets the socket level bandwidth statistics virtual void GetBandwidthStatistics(SBandwidthStats* const pStats) = 0; // Description: // Gathers performance statistics for the network module. virtual void GetPerformanceStatistics(SNetworkPerformance* pSizer) = 0; // Description: // Gets debug and profiling statistics from network members virtual void GetProfilingStatistics(SNetworkProfilingStats* const pStats) = 0; // Description: // Updates all nubs and contexts. // Arguments: // blocking - time to block for network input (zero to not block). virtual void SyncWithGame(ENetworkGameSync syncType) = 0; // Description: // Gets the local host name. virtual const char* GetHostName() = 0; // New virtual GridMate::IGridMate* GetGridMate() = 0; virtual ChannelId GetChannelIdForSessionMember(GridMate::GridMember* member) const = 0; virtual ChannelId GetServerChannelId() const = 0; virtual ChannelId GetLocalChannelId() const = 0; //! Gets the synchronized network time as milliseconds since session creation time. virtual CTimeValue GetSessionTime() = 0; virtual void SetGameContext(IGameContext* gameContext) = 0; virtual void ChangedAspects(EntityId id, NetworkAspectType aspectBits) = 0; //////// Client-delegatable aspect shim. //! Sets mask describing which aspects are globally delegatable. virtual void SetDelegatableAspectMask(NetworkAspectType aspectBits) = 0; //! Sets mask on a given obejct describing which aspect that object has delegated to the controlling client. virtual void SetObjectDelegatedAspectMask(EntityId entityId, NetworkAspectType aspects, bool set) = 0; //! Request authority for entityId be delegated to client at clientChannelId. virtual void DelegateAuthorityToClient(EntityId entityId, ChannelId clientChannelId) = 0; //////// virtual void InvokeRMI(IGameObject* gameObject, IRMIRep& rep, void* params, ChannelId targetChannelFilter, uint32 where) = 0; virtual void InvokeActorRMI(EntityId entityId, uint8 actorExtensionId, ChannelId targetChannelFilter, IActorRMIRep& rep) = 0; virtual void InvokeScriptRMI(ISerializable* serializable, bool isServerRMI, ChannelId toChannelId = kInvalidChannelId, ChannelId avoidChannelId = kInvalidChannelId) = 0; virtual void RegisterActorRMI(IActorRMIRep* rep) = 0; virtual void UnregisterActorRMI(IActorRMIRep* rep) = 0; virtual EntityId LocalEntityIdToServerEntityId(EntityId localId) const = 0; virtual EntityId ServerEntityIdToLocalEntityId(EntityId serverId, bool allowForcedEstablishment = false) const = 0; };