#pragma once #include #ifdef __PS3__ #include #include #else #include #include #endif #include #include "..\..\Common\Network\Sony\SQRNetworkManager.h" class SQRNetworkPlayer; class ISQRNetworkManagerListener; class SonyVoiceChat; 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_PS3 : public SQRNetworkManager { friend class SonyVoiceChat; friend class SQRNetworkPlayer; static const eSQRNetworkManagerState m_INTtoEXTStateMappings[SNM_INT_STATE_COUNT]; public: SQRNetworkManager_PS3(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_PS3::PresenceSyncInfo *presence); void StartGame(); void LeaveRoom(bool bActuallyLeaveRoom); void EndGame(); bool SessionHasSpace(int spaceRequired); bool AddLocalPlayerByUserIndex(int idx); bool RemoveLocalPlayerByUserIndex(int idx); void SendInviteGUI(); void GetInviteDataAndProcess(SceNpBasicAttachmentDataId id); static bool UpdateInviteData(SQRNetworkManager_PS3::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(); // Communication parameter storage static const SceNpCommunicationId* GetSceNpCommsId(); static const SceNpCommunicationSignature* GetSceNpCommsSig(); 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; 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; PresenceSyncInfo *m_gameBootInvite; 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; sys_event_port_t m_basicEventPort; sys_event_queue_t 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. SceNpId m_aSearchResultNpId[MAX_FRIENDS]; SceNpMatching2RoomId m_aSearchResultRoomId[MAX_FRIENDS]; SceNpMatching2ServerId m_aSearchResultServerId[MAX_FRIENDS]; bool m_aSearchResultRoomFound[MAX_FRIENDS]; void *m_aSearchResultRoomExtDataReceived[MAX_FRIENDS]; unsigned int m_searchResultCount; // Rudp management and local players unordered_map m_RudpCtxToPlayerMap; bool CreateRudpConnections(SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, int playerMask, SceNpMatching2RoomMemberId playersPeerMemberId); SQRNetworkPlayer *GetPlayerFromRudpCtx(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); #ifdef __PS3__ static void DefaultRequestCallback(SceNpMatching2ContextId id, SceNpMatching2RequestId reqId, SceNpMatching2Event event, SceNpMatching2EventKey eventKey, int errorCode, size_t dataSize, void *arg); static void RoomEventCallback(SceNpMatching2ContextId id, SceNpMatching2RoomId roomId, SceNpMatching2Event event, SceNpMatching2EventKey eventKey, int errorCode, size_t dataSize, void *arg); #else 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, int errorCode, const void *data, void *arg); #endif static void SignallingCallback(SceNpMatching2ContextId ctxId, SceNpMatching2RoomId roomId, SceNpMatching2RoomMemberId peerMemberId, SceNpMatching2Event event, int errorCode, void *arg); // 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); #ifdef __PS3__ static int RudpEventCallback(int event_id, int soc, uint8_t const *data, size_t datalen, struct sockaddr const *addr, socklen_t addrlen, void *arg); #else static int RudpEventCallback(int event_id, int soc, uint8_t const *data, size_t datalen, struct SceNetSockaddr const *addr, SceNetSocklen_t addrlen, void *arg); #endif // Callback for netctl static void NetCtlCallback(int prev_state, int new_state, int event, int error_code, 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); #ifdef __PS3__ // Response storage char cUserInfoListStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetUserInfoList] __attribute__((__aligned__(4))); char cServerInfoStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetServerInfo] __attribute__((__aligned__(4))); char cWorldListStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetWorldInfoList] __attribute__((__aligned__(4))); char cCreateJoinRoomStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_CreateJoinRoom] __attribute__((__aligned__(4))); char cJoinRoomStorage[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_JoinRoom] __attribute__((__aligned__(4))); char cRoomMemberDataInternal[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomMemberDataInternal] __attribute__((__aligned__(4))); char cRoomDataInternal[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_RoomDataInternalUpdateInfo] __attribute__((__aligned__(4))); char cRoomDataExternalList[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_GetRoomDataExternalList] __attribute__((__aligned__(4))); char cRoomMemberDataInternalUpdate[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_RoomMemberDataInternalUpdateInfo] __attribute__((__aligned__(4))); char cRoomDataUpdateInfo[SCE_NP_MATCHING2_EVENT_DATA_MAX_SIZE_RoomUpdateInfo] __attribute__((__aligned__(4))); #endif #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); static int (*s_SignInCompleteCallbackFn)(void *pParam, bool bContinue, int pad); static bool s_signInCompleteCallbackIfFailed; static void *s_SignInCompleteParam; static int SetRichPresence(const void *data, unsigned int options); void SetPresenceDataStartHostingGame(); int GetJoiningReadyPercentage(); private: static void UpdateRichPresenceCustomData(void *data, unsigned int dataBytes); static void TickRichPresence(); static void SendLastPresenceInfo(); static SceNpBasicPresenceDetails2 s_lastPresenceInfo; static int s_resendPresenceCountdown; static bool s_presenceStatusDirty; static bool s_presenceDataDirty; static PresenceSyncInfo s_lastPresenceSyncInfo; static PresenceSyncInfo c_presenceSyncInfoNULL; // 4J-PB - so we can stop the crash on PS3 when Iggy's LoadMovie is called from the ContextCallback static bool m_bCallPSNSignInCallback; // Debug static long long s_roomStartTime; };