Files
MinecraftConsoles/Minecraft.Client/PS3/Network/SQRNetworkManager_PS3.h
2026-03-01 12:16:08 +08:00

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;
};