#pragma once #include #include #include #include #include #include // #include "SonyVoiceChat_Orbis.h" #include "..\..\Common\Network\Sony\SQRNetworkManager.h" class SQRNetworkPlayer; class ISQRNetworkManagerListener; class SonyVoiceChat_Orbis; class SQRVoiceConnection; class C4JThread; // This is the lowest level manager for providing network functionality on Sony platforms. This manages various network activities including the players within a gaming session. // The game shouldn't directly use this class, it is here to provide functionality required by PlatformNetworkManagerSony. class SQRNetworkManager_Orbis : public SQRNetworkManager { friend class SonyVoiceChat_Orbis; friend class SQRNetworkPlayer; static const eSQRNetworkManagerState m_INTtoEXTStateMappings[SNM_INT_STATE_COUNT]; public: SQRNetworkManager_Orbis(ISQRNetworkManagerListener *listener); // General void Tick(); void Initialise(); void Terminate(); eSQRNetworkManagerState GetState(); bool IsHost(); bool IsReadyToPlayOrIdle(); bool IsInSession(); // Session management void CreateAndJoinRoom(int hostIndex, int localPlayerMask, void *extData, int extDataSize, bool offline); void UpdateExternalRoomData(); bool FriendRoomManagerIsBusy(); bool FriendRoomManagerSearch(); bool FriendRoomManagerSearch2(); int FriendRoomManagerGetCount(); void FriendRoomManagerGetRoomInfo(int idx, SessionSearchResult *searchResult); bool JoinRoom(SessionSearchResult *searchResult, int localPlayerMask); bool JoinRoom(SceNpMatching2RoomId roomId, SceNpMatching2ServerId serverId, int localPlayerMask, const SQRNetworkManager_Orbis::PresenceSyncInfo *presence); void StartGame(); void LeaveRoom(bool bActuallyLeaveRoom); void EndGame(); bool SessionHasSpace(int spaceRequired); bool AddLocalPlayerByUserIndex(int idx); bool RemoveLocalPlayerByUserIndex(int idx); void SendInviteGUI(); static void RecvInviteGUI(); void TickInviteGUI(); // Remote play void UpdateRemotePlay(); // void GetInviteDataAndProcess(SceNpBasicAttachmentDataId id); // static bool UpdateInviteData(SQRNetworkManager_Orbis::PresenceSyncInfo *invite); void GetExtDataForRoom( SceNpMatching2RoomId roomId, void *extData, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam ); // Player retrieval int GetPlayerCount(); int GetOnlinePlayerCount(); SQRNetworkPlayer *GetPlayerByIndex(int idx); SQRNetworkPlayer *GetPlayerBySmallId(int idx); SQRNetworkPlayer *GetPlayerByXuid(PlayerUID xuid); SQRNetworkPlayer *GetLocalPlayerByUserIndex(int idx); SQRNetworkPlayer *GetHostPlayer(); void removePlayerFromVoiceChat(SQRNetworkPlayer* pPlayer); // Communication parameter storage static const SceNpCommunicationId* GetSceNpCommsId(); static const SceNpCommunicationSignature* GetSceNpCommsSig(); static const SceNpTitleId* GetSceNpTitleId(); static const SceNpTitleSecret* GetSceNpTitleSecret(); static void GetInviteDataAndProcess(sce::Toolkit::NP::MessageAttachment* pInvite); private: void InitialiseAfterOnline(); void ErrorHandlingTick(); void UpdateOnlineStatus(int status) { m_onlineStatus = status; } int GetOnlineStatus() { return m_onlineStatus; } ISQRNetworkManagerListener *m_listener; SQRNetworkPlayer *GetPlayerIfReady(SQRNetworkPlayer *player); // Internal state void SetState(eSQRNetworkManagerInternalState state); void ResetToIdle(); eSQRNetworkManagerInternalState m_state; eSQRNetworkManagerState m_stateExternal; bool m_nextIdleReasonIsFull; bool m_isHosting; SceNpMatching2RoomMemberId m_localMemberId; SceNpMatching2RoomMemberId m_hostMemberId; // if we're not the host int m_localPlayerCount; int m_localPlayerJoined; // Client only, keep a count of how many local players we have confirmed as joined to the application SceNpMatching2RoomId m_room; unsigned char m_currentSmallId; int m_soc; bool m_offlineGame; bool m_offlineSQR; int m_resendExternalRoomDataCountdown; bool m_matching2initialised; PresenceSyncInfo m_inviteReceived[MAX_SIMULTANEOUS_INVITES]; int m_inviteIndex; static PresenceSyncInfo *m_gameBootInvite; static PresenceSyncInfo m_gameBootInvite_data; bool m_doBootInviteCheck; bool m_isInSession; // static SceNpBasicAttachmentDataId s_lastInviteIdToRetry; int m_onlineStatus; bool m_bLinkDisconnected; private: CRITICAL_SECTION m_csRoomSyncData; RoomSyncData m_roomSyncData; void *m_joinExtData; int m_joinExtDataSize; std::vector m_vecTempPlayers; SQRNetworkPlayer *m_aRoomSlotPlayers[MAX_ONLINE_PLAYER_COUNT]; // Maps from the players in m_roomSyncData, to SQRNetworkPlayers void FindOrCreateNonNetworkPlayer(int slot, int playerType, SceNpMatching2RoomMemberId memberId, int localPlayerIdx, int smallId); void MapRoomSlotPlayers(int roomSlotPlayerCount =-1); void UpdateRoomSyncUIDsFromPlayers(); void UpdatePlayersFromRoomSyncUIDs(); void LocalDataSend(SQRNetworkPlayer *playerFrom, SQRNetworkPlayer *playerTo, const void *data, unsigned int dataSize); int GetSessionIndex(SQRNetworkPlayer *player); bool AddRemotePlayersAndSync( SceNpMatching2RoomMemberId memberId, int playerMask, bool *isFull = NULL ); void RemoveRemotePlayersAndSync( SceNpMatching2RoomMemberId memberId, int mask ); void RemoveNetworkPlayers( int mask ); void SetLocalPlayersAndSync(); void SyncRoomData(); SceNpMatching2RequestId m_setRoomDataRequestId; SceNpMatching2RequestId m_setRoomIntDataRequestId; SceNpMatching2RequestId m_roomExtDataRequestId; // Server context management bool GetMatchingContext(eSQRNetworkManagerInternalState asyncState); bool GetServerContext(); bool GetServerContext2(); bool GetServerContext(SceNpMatching2ServerId serverId); void DeleteServerContext(); bool SelectRandomServer(); void ServerContextTick(); int m_totalServerCount; int m_serverCount; SceNpMatching2ServerId *m_aServerId; SceNpMatching2ServerId m_serverId; bool m_serverContextValid; SceNpMatching2RequestId m_serverSearchRequestId; SceNpMatching2RequestId m_serverContextRequestId; // Room creation management SceNpMatching2RequestId m_getWorldRequestId; SceNpMatching2RequestId m_createRoomRequestId; SceNpMatching2WorldId m_worldId; void RoomCreateTick(); // Room joining management SceNpMatching2RoomId m_roomToJoin; int m_localPlayerJoinMask; SceNpMatching2RequestId m_joinRoomRequestId; SceNpMatching2RequestId m_kickRequestId; // Room leaving management SceNpMatching2RequestId m_leaveRoomRequestId; // Adding extra network players management SceNpMatching2RequestId m_setRoomMemberInternalDataRequestId; // Player state management void NetworkPlayerConnectionComplete(SQRNetworkPlayer *player); void NetworkPlayerSmallIdAllocated(SQRNetworkPlayer *player, unsigned char smallId); void NetworkPlayerInitialDataReceived(SQRNetworkPlayer *player,void *data); void NonNetworkPlayerComplete(SQRNetworkPlayer *player, unsigned char smallId); void HandlePlayerJoined(SQRNetworkPlayer *player); CRITICAL_SECTION m_csPlayerState; // State and thread for managing basic event type messages C4JThread *m_basicEventThread; SceKernelEqueue m_basicEventQueue; static int BasicEventThreadProc( void *lpParameter); // State and storage for managing search for friends' games eSQRNetworkManagerFriendSearchState m_friendSearchState; SceNpMatching2ContextId m_matchingContext; bool m_matchingContextValid; SceNpMatching2RequestId m_friendSearchRequestId; unsigned int m_friendCount; C4JThread *m_getFriendCountThread; static int GetFriendsThreadProc( void* lpParameter ); void FriendSearchTick(); SceNpMatching2RequestId m_roomDataExternalListRequestId; void (* m_FriendSessionUpdatedFn)(bool success, void *pParam); void *m_pParamFriendSessionUpdated; void *m_pExtDataToUpdate; // Results from searching for rooms that friends are playing in - 5 matched arrays to store their NpIds, rooms, servers, whether a room was found, and whether the external data had been received for the room. Also a count of how many elements are used in this array. class FriendSearchResult { public: SceNpId m_NpId; SceNpMatching2RoomId m_RoomId; SceNpMatching2ServerId m_ServerId; bool m_RoomFound; void *m_RoomExtDataReceived; }; std::vector m_aFriendSearchResults; // Rudp management and local players std::unordered_map m_RudpCtxToPlayerMap; std::unordered_map m_NetAddrToVoiceConnectionMap; bool CreateRudpConnections(SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, int playerMask, SceNpMatching2RoomMemberId playersPeerMemberId); bool CreateVoiceRudpConnections(SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, int playerMask); bool CreateSocket(); SQRNetworkPlayer *GetPlayerFromRudpCtx(int rudpCtx); SQRVoiceConnection* GetVoiceConnectionFromRudpCtx(int rudpCtx); SQRNetworkPlayer *GetPlayerFromRoomMemberAndLocalIdx(int roomMember, int localIdx); SceNpMatching2RequestId m_roomMemberDataRequestId; // Callbacks (for matching) bool RegisterCallbacks(); static void ContextCallback(SceNpMatching2ContextId id, SceNpMatching2Event event, SceNpMatching2EventCause eventCause, int errorCode, void *arg); static void DefaultRequestCallback(SceNpMatching2ContextId id, SceNpMatching2RequestId reqId, SceNpMatching2Event event, int errorCode, const void *data, void *arg); static void RoomEventCallback(SceNpMatching2ContextId id, SceNpMatching2RoomId roomId, SceNpMatching2Event event, const void *data, void *arg); // MGH - changed this to queue up the signalling events from the callback and process them later on the server thread class SignallingEvent { public: SceNpMatching2ContextId ctxId; SceNpMatching2RoomId roomId; SceNpMatching2RoomMemberId peerMemberId; SceNpMatching2Event event; int error_code; }; std::vector m_signallingEventList; CRITICAL_SECTION m_signallingEventListCS; static void SignallingCallback(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, SceNpMatching2Event event, int error_code, void *arg); void ProcessSignallingEvent(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, SceNpMatching2Event event, int error_code); void SignallingEventsTick(); // Callback for NpBasic static int BasicEventCallback(int event, int retCode, uint32_t reqId, void *arg); // Callback for NpManager static void ManagerCallback(int event, int result, void *arg); // Callback for sys util static void SysUtilCallback(uint64_t status, uint64_t param, void *userdata); // Callbacks for rudp static void RudpContextCallback(int ctx_id, int event_id, int error_code, void *arg); static int RudpEventCallback(int event_id, int soc, uint8_t const *data, size_t datalen, struct SceNetSockaddr const *addr, SceNetSocklen_t addrlen, void *arg); // Callback for netctl static void NetCtlCallback(int eventType, void *arg); // Methods to be called when the server context has been created void ServerContextValid_CreateRoom(); void ServerContextValid_JoinRoom(); // Mask utilities int GetOldMask(SceNpMatching2RoomMemberId memberId); int GetAddedMask(int newMask, int oldMask); int GetRemovedMask(int newMask, int oldMask); #ifndef _CONTENT_PACKAGE static bool aForceError[SNM_FORCE_ERROR_COUNT]; #endif bool ForceErrorPoint(eSQRForceError err); public: static void AttemptPSNSignIn(int (*SignInCompleteCallbackFn)(void *pParam, bool bContinue, int pad), void *pParam, bool callIfFailed = false, int iPad = -1); //static void CallSignInCompleteCallback(); static int (*s_SignInCompleteCallbackFn)(void *pParam, bool bContinue, int pad); static bool s_signInCompleteCallbackIfFailed; static bool s_signInCompleteCallbackFAIL; static void *s_SignInCompleteParam; static bool s_SignInCompleteCallbackPending; static long long s_errorDialogClosed; static long long s_systemDialogClosed; static int s_SignInCompleteCallbackPad; // Time to wait for system UI before we check result #define SYSTEM_UI_WAIT_TIME 1000 static int SetRichPresence(const void *data); void SetPresenceDataStartHostingGame(); int GetJoiningReadyPercentage(); static void SetPresenceFailedCallback(); // 4J-PB - so we can stop the crash when Iggy's LoadMovie is called from the ContextCallback static bool m_bCallPSNSignInCallback; private: static void UpdateRichPresenceCustomData(void *data, unsigned int dataBytes); static void TickRichPresence(); static void SendLastPresenceInfo(); void OnlineCheck(); void tickErrorDialog(); static sce::Toolkit::NP::PresenceDetails s_lastPresenceInfo; static const int MIN_PRESENCE_RESEND_TIME = 30 * 1000; // Minimum presence send rate - doesn't seem possible to find out what this actually should be static __int64 s_lastPresenceTime; static __int64 s_resendPresenceTime; static bool s_presenceStatusDirty; static bool s_presenceDataDirty; static PresenceSyncInfo s_lastPresenceSyncInfo; static PresenceSyncInfo c_presenceSyncInfoNULL; static bool b_inviteRecvGUIRunning; // Debug static long long s_roomStartTime; // Error dialog static bool s_errorDialogRunning; // NP Notify void TickNotify(); void NotifyRealtimePlusFeature(int iQuadrant); long long m_lastNotifyTime; static void RefreshChatAndContentRestrictionsReturned_HandleInvite(void *pParam); bool m_bRefreshingRestrictionsForInvite; public: static bool s_bInviteDialogRunning; };