aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.Client/Common/Network/GameNetworkManager.h
blob: 1bb532dab197c9ae0b433fb2e68b397fd7997a81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#pragma once
using namespace std;
#include <vector>
#include <qnet.h>
#include "..\..\..\Minecraft.World\C4JThread.h"
#include "NetworkPlayerInterface.h"
#ifdef _XBOX
#include "..\..\Xbox\Network\PlatformNetworkManagerXbox.h"
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
#include "..\..\Common\Network\Sony\PlatformNetworkManagerSony.h"
#elif defined _DURANGO
#include "..\..\Durango\Network\PlatformNetworkManagerDurango.h"
#else
#include "PlatformNetworkManagerStub.h"
#endif
#include "SessionInfo.h"

#ifdef __ORBIS__
#include "..\..\Orbis\Network\PsPlusUpsellWrapper_Orbis.h"
#endif

class ClientConnection;
class Minecraft;


// This class implements the game-side interface to the networking system. As such, it is platform independent and may contain bits of game-side code where appropriate.
// It shouldn't ever reference any platform specifics of the network implementation (eg QNET), rather it should interface with an implementation of PlatformNetworkManager to
// provide this functionality.

class CGameNetworkManager
{
#ifdef _XBOX
	friend class CPlatformNetworkManagerXbox;
#elif defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
	friend class CPlatformNetworkManagerSony;
#elif defined _DURANGO
	friend class CPlatformNetworkManagerDurango;
#else
	friend class CPlatformNetworkManagerStub;
#endif
public:
	CGameNetworkManager();
	// Misc high level flow

	typedef enum
	{
		JOINGAME_SUCCESS,
		JOINGAME_FAIL_GENERAL,
		JOINGAME_FAIL_SERVER_FULL
	} eJoinGameResult;

	void			Initialise();
	void			Terminate();
	void			DoWork();
	bool			_RunNetworkGame(LPVOID lpParameter);
	bool			StartNetworkGame(Minecraft *minecraft, LPVOID lpParameter);
	int				CorrectErrorIDS(int IDS);

	// Player management

	static int		GetLocalPlayerMask(int playerIndex);
	int				GetPlayerCount();
	int				GetOnlinePlayerCount();
	bool			AddLocalPlayerByUserIndex( int userIndex );
	bool			RemoveLocalPlayerByUserIndex( int userIndex );
	INetworkPlayer	*GetLocalPlayerByUserIndex(int userIndex );
	INetworkPlayer	*GetPlayerByIndex(int playerIndex);
	INetworkPlayer	*GetPlayerByXuid(PlayerUID xuid);
	INetworkPlayer	*GetPlayerBySmallId(unsigned char smallId);
	wstring			GetDisplayNameByGamertag(wstring gamertag);
	INetworkPlayer	*GetHostPlayer();
	void			RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam);
	void			UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam);
	void			HandleSignInChange();
	bool			ShouldMessageForFullSession();

	// State management

	bool			IsInSession();
	bool			IsInGameplay();
	bool			IsLeavingGame();
	bool			IsReadyToPlayOrIdle();

	// Hosting and game type

	bool			SetLocalGame(bool isLocal);
	bool			IsLocalGame();
	void			SetPrivateGame(bool isPrivate);
	bool			IsPrivateGame();
	void			HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots = MINECRAFT_NET_MAX_PLAYERS, unsigned char privateSlots = 0);
	bool			IsHost();
	bool			IsInStatsEnabledSession();

	// Client session discovery

	bool			SessionHasSpace(unsigned int spaceRequired = 1);
	vector<FriendSessionInfo *>	*GetSessionList(int iPad, int localPlayers, bool partyOnly);
	bool			GetGameSessionInfo(int iPad, SessionID sessionId,FriendSessionInfo *foundSession);
	void			SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam );
	void			GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam );
	void			ForceFriendsSessionRefresh();
	
	// Session joining and leaving

	bool			JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo);
	eJoinGameResult	JoinGame(FriendSessionInfo *searchResult, int localUsersMask);	
	static void		CancelJoinGame(LPVOID lpParam); // Not part of the shared interface
	bool			LeaveGame(bool bMigrateHost);
	static int		JoinFromInvite_SignInReturned(void *pParam,bool bContinue, int iPad);
	void			UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving = NULL);
	void			SendInviteGUI(int iPad);
	void			ResetLeavingGame();

	// Threads
	
	bool			IsNetworkThreadRunning();
	static int		RunNetworkGameThreadProc( void* lpParameter );
	static int		ServerThreadProc( void* lpParameter );
	static int		ExitAndJoinFromInviteThreadProc( void* lpParam );

#if (defined __PS3__) || (defined __ORBIS__) || (defined __PSVITA__) 
	static int		MustSignInReturned_0(void *pParam,int iPad,C4JStorage::EMessageResult result);
	static int		PSNSignInReturned_0(void* pParam, bool bContinue, int iPad);

	static int		MustSignInReturned_1(void *pParam,int iPad,C4JStorage::EMessageResult result);
	static int		PSNSignInReturned_1(void* pParam, bool bContinue, int iPad);
#endif

	static void		_LeaveGame();
	static int		ChangeSessionTypeThreadProc( void* lpParam );

	// System flags	

	void SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index);
	bool SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index);

	// Events

	void ServerReadyCreate(bool create);	// Create the signal (or set to NULL)
	void ServerReady();						// Signal that we are ready
	void ServerReadyWait();					// Wait for the signal
	void ServerReadyDestroy();				// Destroy signal
	bool ServerReadyValid();				// Is non-NULL

	void ServerStoppedCreate(bool create);	// Create the signal
	void ServerStopped();					// Signal that we are ready
	void ServerStoppedWait();				// Wait for the signal	
	void ServerStoppedDestroy();			// Destroy signal	
	bool ServerStoppedValid();				// Is non-NULL

#ifdef __PSVITA__
	static bool usingAdhocMode();
	static void setAdhocMode(bool bAdhoc);
	static void startAdhocMatching();
#endif
	// Debug output

	wstring GatherStats();
	void renderQueueMeter();
	wstring GatherRTTStats();

	// GUI debug output

	// Used for debugging output
	static const int messageQueue_length = 512;
	static __int64 messageQueue[messageQueue_length];
	static const int byteQueue_length = 512;
    static __int64 byteQueue[byteQueue_length];
	static int messageQueuePos;

	// Methods called from PlatformNetworkManager
private:
	void StateChange_AnyToHosting();
	void StateChange_AnyToJoining();
	void StateChange_JoiningToIdle(CPlatformNetworkManager::eJoinFailedReason reason);
	void StateChange_AnyToStarting();
	void StateChange_AnyToEnding(bool bStateWasPlaying);
	void StateChange_AnyToIdle();
	void CreateSocket( INetworkPlayer *pNetworkPlayer, bool localPlayer );
	void CloseConnection( INetworkPlayer *pNetworkPlayer );
	void PlayerJoining( INetworkPlayer *pNetworkPlayer );
	void PlayerLeaving( INetworkPlayer *pNetworkPlayer );
	void HostChanged();
	void WriteStats( INetworkPlayer *pNetworkPlayer );
	void GameInviteReceived( int userIndex, const INVITE_INFO *pInviteInfo);
	void HandleInviteWhenInMenus( int userIndex, const INVITE_INFO *pInviteInfo);
	void AddLocalPlayerFailed(int idx, bool serverFull = false);
#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__
	void HandleDisconnect(bool bLostRoomOnly,bool bPSNSignOut);
#else
	void HandleDisconnect(bool bLostRoomOnly);
#endif

	int  GetPrimaryPad();
	int  GetLockedProfile();
	bool IsSignedInLive(int playerIdx);
	bool AllowedToPlayMultiplayer(int playerIdx);
	char *GetOnlineName(int playerIdx);

	C4JThread::Event*	m_hServerStoppedEvent;
	C4JThread::Event*	m_hServerReadyEvent;
	bool m_bInitialised;

#ifdef _XBOX_ONE
public:
	void SetFullSessionMessageOnNextSessionChange() { m_bFullSessionMessageOnNextSessionChange = true; }
#endif
private:
	float m_lastPlayerEventTimeStart;			// For telemetry
	static CPlatformNetworkManager *s_pPlatformNetworkManager;
	bool			m_bNetworkThreadRunning;
	int GetJoiningReadyPercentage();
	bool m_bLastDisconnectWasLostRoomOnly;
	bool m_bFullSessionMessageOnNextSessionChange;
#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__
	bool m_bSignedOutofPSN;
#endif

#ifdef __ORBIS__
	PsPlusUpsellWrapper	*m_pUpsell;
	INVITE_INFO			*m_pInviteInfo;
	int					 m_iPlayerInvited;
#endif

public:
#ifndef _XBOX
	void FakeLocalPlayerJoined();		// Temporary method whilst we don't have real networking to make this happen
#endif
};

extern CGameNetworkManager g_NetworkManager;

#ifdef __PS3__
#undef __in
#define __out
#endif