301 lines
14 KiB
C++
301 lines
14 KiB
C++
#pragma once
|
|
#include <np.h>
|
|
#ifdef __PS3__
|
|
#include <netex\libnetctl.h>
|
|
#include <netex\net.h>
|
|
#else
|
|
#include <libnetctl.h>
|
|
#include <net.h>
|
|
#endif
|
|
#include <queue>
|
|
|
|
#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<SQRNetworkPlayer *> 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<int,SQRNetworkPlayer *> 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;
|
|
};
|