the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "..\..\..\Minecraft.World\Socket.h"
3#include "..\..\..\Minecraft.World\StringHelpers.h"
4#include "PlatformNetworkManagerSony.h"
5#include "NetworkPlayerSony.h"
6#include "..\..\Common\Network\GameNetworkManager.h"
7
8CPlatformNetworkManagerSony *g_pPlatformNetworkManager;
9
10bool CPlatformNetworkManagerSony::IsLocalGame()
11{
12 return m_bIsOfflineGame;
13}
14bool CPlatformNetworkManagerSony::IsPrivateGame()
15{
16 return m_bIsPrivateGame;
17}
18bool CPlatformNetworkManagerSony::IsLeavingGame()
19{
20 return m_bLeavingGame;
21}
22void CPlatformNetworkManagerSony::ResetLeavingGame()
23{
24 m_bLeavingGame = false;
25}
26
27
28void CPlatformNetworkManagerSony::HandleStateChange(SQRNetworkManager::eSQRNetworkManagerState oldState, SQRNetworkManager::eSQRNetworkManagerState newState, bool idleReasonIsSessionFull)
29{
30 static const char * c_apszStateNames[] =
31 {
32 "SNM_STATE_INITIALISING",
33 "SNM_STATE_INITIALISE_FAILED",
34 "SNM_STATE_IDLE",
35 "SNM_STATE_HOSTING",
36 "SNM_STATE_JOINING",
37 "SNM_STATE_STARTING",
38 "SNM_STATE_PLAYING",
39 "SNM_STATE_LEAVING",
40 "SNM_STATE_ENDING",
41 };
42
43 app.DebugPrintf( "Network State: %s ==> %s\n",
44 c_apszStateNames[ oldState ],
45 c_apszStateNames[ newState ] );
46
47 if( newState == SQRNetworkManager::SNM_STATE_HOSTING )
48 {
49 m_bLeavingGame = false;
50 m_bLeaveGameOnTick = false;
51 m_bHostChanged = false;
52 g_NetworkManager.StateChange_AnyToHosting();
53 }
54 else if( newState == SQRNetworkManager::SNM_STATE_JOINING )
55 {
56 // 4J Stu - We may be accepting an invite from the DLC menu, so hide the icon
57#if defined __ORBIS__ || defined __PSVITA__
58 app.GetCommerce()->HidePsStoreIcon();
59#endif
60 m_bLeavingGame = false;
61 m_bLeaveGameOnTick = false;
62 m_bHostChanged = false;
63 g_NetworkManager.StateChange_AnyToJoining();
64 }
65 else if( newState == SQRNetworkManager::SNM_STATE_IDLE && oldState == SQRNetworkManager::SNM_STATE_JOINING )
66 {
67 if( idleReasonIsSessionFull )
68 {
69 g_NetworkManager.StateChange_JoiningToIdle(JOIN_FAILED_SERVER_FULL);
70 }
71 else
72 {
73 g_NetworkManager.StateChange_JoiningToIdle(JOIN_FAILED_NONSPECIFIC);
74 }
75 }
76 else if( newState == SQRNetworkManager::SNM_STATE_IDLE && oldState == SQRNetworkManager::SNM_STATE_HOSTING )
77 {
78 m_bLeavingGame = true;
79 }
80 else if( newState == SQRNetworkManager::SNM_STATE_STARTING )
81 {
82 m_lastPlayerEventTimeStart = app.getAppTime();
83
84 g_NetworkManager.StateChange_AnyToStarting();
85 }
86 // Fix for #93148 - TCR 001: BAS Game Stability: Title will crash for the multiplayer client if host of the game will exit during the clients loading to created world.
87 // 4J Stu - If the client joins just as the host is exiting, then they can skip to leaving without passing through ending
88 else if( newState == SQRNetworkManager::SNM_STATE_ENDING )
89 {
90 g_NetworkManager.StateChange_AnyToEnding( oldState == SQRNetworkManager::SNM_STATE_PLAYING );
91
92 // 4J-PB - Only the host can leave here - the clients will hang if m_bLeavingGame is set to true here
93 if( m_pSQRNet->IsHost() )
94 {
95 m_bLeavingGame = true;
96 }
97 }
98
99 if( newState == SQRNetworkManager::SNM_STATE_IDLE )
100 {
101 // On PS3, sometimes we're getting a SNM_STATE_ENDING transition to SNM_STATE_IDLE on joining, because the server context being deleted sets the state away from SNM_STATE_JOINING before we detect
102 // the cause for the disconnection. This means we don't pick up on the joining->idle transition. Set disconnection reason here too for this case.
103 if( idleReasonIsSessionFull )
104 {
105 app.SetDisconnectReason( DisconnectPacket::eDisconnect_ServerFull );
106 }
107 g_NetworkManager.StateChange_AnyToIdle();
108 }
109}
110
111void CPlatformNetworkManagerSony::HandleDataReceived(SQRNetworkPlayer *playerFrom, SQRNetworkPlayer *playerTo, unsigned char *data, unsigned int dataSize)
112{
113 if(m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_ENDING)
114 {
115 return;
116 }
117
118 if( playerTo->IsHost() )
119 {
120 // If we are the host we care who this came from
121 //app.DebugPrintf( "Pushing data into host read queue for user \"%ls\"\n", pPlayerFrom->GetGamertag());
122 // Push this data into the read queue for the player that sent it
123 INetworkPlayer *pPlayerFrom = getNetworkPlayer(playerFrom);
124 Socket *socket = pPlayerFrom->GetSocket();
125
126 if(socket != NULL)
127 socket->pushDataToQueue(data, dataSize, false);
128 }
129 else
130 {
131 // If we are not the host the message must have come from the host, so we care more about who it is addressed to
132 INetworkPlayer *pPlayerTo = getNetworkPlayer(playerTo);
133 Socket *socket = pPlayerTo->GetSocket();
134 //app.DebugPrintf( "Pushing data into read queue for user \"%ls\"\n", apPlayersTo[dwPlayer]->GetGamertag());
135 if(socket != NULL)
136 socket->pushDataToQueue(data, dataSize);
137 }
138}
139
140void CPlatformNetworkManagerSony::HandlePlayerJoined(SQRNetworkPlayer * pSQRPlayer)
141{
142 const char * pszDescription;
143
144 // 4J Stu - We create a fake socket for every where that we need an INBOUND queue of game data. Outbound
145 // is all handled by QNet so we don't need that. Therefore each client player has one, and the host has one
146 // for each client player.
147 bool createFakeSocket = false;
148 bool localPlayer = false;
149
150 NetworkPlayerSony *networkPlayer = (NetworkPlayerSony *)addNetworkPlayer(pSQRPlayer);
151
152 if( pSQRPlayer->IsLocal() )
153 {
154 localPlayer = true;
155 if( pSQRPlayer->IsHost() )
156 {
157 pszDescription = "local host";
158 // 4J Stu - No socket for the localhost as it uses a special loopback queue
159
160 m_machineSQRPrimaryPlayers.push_back( pSQRPlayer );
161 }
162 else
163 {
164 pszDescription = "local";
165
166 // We need an inbound queue on all local players to receive data from the host
167 createFakeSocket = true;
168 }
169 }
170 else
171 {
172 if( pSQRPlayer->IsHost() )
173 {
174 pszDescription = "remote host";
175 }
176 else
177 {
178 pszDescription = "remote";
179
180 // If we are the host, then create a fake socket for every remote player
181 if( m_pSQRNet->IsHost() )
182 {
183 createFakeSocket = true;
184 }
185 }
186
187 if( m_pSQRNet->IsHost() && !m_bHostChanged )
188 {
189 // Do we already have a primary player for this system?
190 bool systemHasPrimaryPlayer = false;
191 for(AUTO_VAR(it, m_machineSQRPrimaryPlayers.begin()); it < m_machineSQRPrimaryPlayers.end(); ++it)
192 {
193 SQRNetworkPlayer *pQNetPrimaryPlayer = *it;
194 if( pSQRPlayer->IsSameSystem(pQNetPrimaryPlayer) )
195 {
196 systemHasPrimaryPlayer = true;
197 break;
198 }
199 }
200 if( !systemHasPrimaryPlayer )
201 m_machineSQRPrimaryPlayers.push_back( pSQRPlayer );
202 }
203 }
204 g_NetworkManager.PlayerJoining( networkPlayer );
205
206 if( createFakeSocket == true && !m_bHostChanged )
207 {
208 g_NetworkManager.CreateSocket( networkPlayer, localPlayer );
209 }
210
211#if 0
212 app.DebugPrintf( "Player 0x%p \"%ls\" joined; %s; voice %i; camera %i.\n",
213 pSQRPlayer,
214 pSQRPlayer->GetGamertag(),
215 pszDescription,
216 (int) pSQRPlayer->HasVoice(),
217 (int) pSQRPlayer->HasCamera() );
218#endif
219
220
221 if( m_pSQRNet->IsHost() )
222 {
223 // 4J-PB - only the host should do this
224 g_NetworkManager.UpdateAndSetGameSessionData();
225 SystemFlagAddPlayer( networkPlayer );
226 }
227
228 for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
229 {
230 if(playerChangedCallback[idx] != NULL)
231 playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, false );
232 }
233
234 if(true) // TODO m_pSQRNet->GetState() == QNET_STATE_GAME_PLAY)
235 {
236 int localPlayerCount = 0;
237 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
238 {
239 if( m_pSQRNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount;
240 }
241
242 float appTime = app.getAppTime();
243
244 // Only record stats for the primary player here
245 m_lastPlayerEventTimeStart = appTime;
246 }
247}
248
249void CPlatformNetworkManagerSony::HandlePlayerLeaving(SQRNetworkPlayer *pSQRPlayer)
250{
251 //__debugbreak();
252
253 app.DebugPrintf( "Player 0x%p leaving.\n",
254 pSQRPlayer );
255
256 INetworkPlayer *networkPlayer = getNetworkPlayer(pSQRPlayer);
257
258 if( networkPlayer )
259 {
260 // Get our wrapper object associated with this player.
261 Socket *socket = networkPlayer->GetSocket();
262 if( socket != NULL )
263 {
264 // If we are in game then remove this player from the game as well.
265 // We may get here either from the player requesting to exit the game,
266 // in which case we they will already have left the game server, or from a disconnection
267 // where we then have to remove them from the game server
268 if( m_pSQRNet->IsHost() && !m_bHostChanged )
269 {
270 g_NetworkManager.CloseConnection(networkPlayer);
271 }
272
273 // Free the wrapper object memory.
274 // TODO 4J Stu - We may still be using this at the point that the player leaves the session.
275 // We need this as long as the game server still needs to communicate with the player
276 //delete socket;
277
278 networkPlayer->SetSocket( NULL );
279 }
280
281 if( m_pSQRNet->IsHost() && !m_bHostChanged )
282 {
283 if( isSystemPrimaryPlayer(pSQRPlayer) )
284 {
285 SQRNetworkPlayer *pNewSQRPrimaryPlayer = NULL;
286 for(unsigned int i = 0; i < m_pSQRNet->GetPlayerCount(); ++i )
287 {
288 SQRNetworkPlayer *pSQRPlayer2 = m_pSQRNet->GetPlayerByIndex( i );
289
290 if ( pSQRPlayer2 != NULL && pSQRPlayer2 != pSQRPlayer && pSQRPlayer2->IsSameSystem( pSQRPlayer ) )
291 {
292 pNewSQRPrimaryPlayer = pSQRPlayer2;
293 break;
294 }
295 }
296 AUTO_VAR(it, find( m_machineSQRPrimaryPlayers.begin(), m_machineSQRPrimaryPlayers.end(), pSQRPlayer));
297 if( it != m_machineSQRPrimaryPlayers.end() )
298 {
299 m_machineSQRPrimaryPlayers.erase( it );
300 }
301
302 if( pNewSQRPrimaryPlayer != NULL )
303 m_machineSQRPrimaryPlayers.push_back( pNewSQRPrimaryPlayer );
304 }
305
306 g_NetworkManager.UpdateAndSetGameSessionData( networkPlayer );
307 SystemFlagRemovePlayer( networkPlayer );
308
309 }
310
311 g_NetworkManager.PlayerLeaving( networkPlayer );
312
313 for( int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
314 {
315 if(playerChangedCallback[idx] != NULL)
316 playerChangedCallback[idx]( playerChangedCallbackParam[idx], networkPlayer, true );
317 }
318
319 if(m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_PLAYING)
320 {
321 int localPlayerCount = 0;
322 for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
323 {
324 if( m_pSQRNet->GetLocalPlayerByUserIndex(idx) != NULL ) ++localPlayerCount;
325 }
326
327 float appTime = app.getAppTime();
328 m_lastPlayerEventTimeStart = appTime;
329 }
330
331 removeNetworkPlayer(pSQRPlayer);
332 }
333}
334
335// Update our external data to match the current internal player slots, and resync back out (host only)
336void CPlatformNetworkManagerSony::HandleResyncPlayerRequest(SQRNetworkPlayer **aPlayers)
337{
338 m_hostGameSessionData.playerCount = 0;
339 for(int i = 0; i < SQRNetworkManager::MAX_ONLINE_PLAYER_COUNT; i++ )
340 {
341 if( aPlayers[i] )
342 {
343 m_hostGameSessionData.players[i] = aPlayers[i]->GetUID();
344 m_hostGameSessionData.playerCount++;
345 }
346 else
347 {
348 memset(&m_hostGameSessionData.players[i],0,sizeof(m_hostGameSessionData.players[i]));
349 }
350 }
351 m_pSQRNet->UpdateExternalRoomData();
352}
353
354void CPlatformNetworkManagerSony::HandleAddLocalPlayerFailed(int idx)
355{
356 g_NetworkManager.AddLocalPlayerFailed(idx);
357}
358
359void CPlatformNetworkManagerSony::HandleDisconnect(bool bLostRoomOnly,bool bPSNSignOut)
360{
361 g_NetworkManager.HandleDisconnect(bLostRoomOnly,bPSNSignOut);
362}
363
364void CPlatformNetworkManagerSony::HandleInviteReceived( int userIndex, const SQRNetworkManager::PresenceSyncInfo *pInviteInfo)
365{
366 g_NetworkManager.GameInviteReceived( userIndex, pInviteInfo );
367}
368
369extern SQRNetworkManager *testSQRNetworkManager;
370
371bool CPlatformNetworkManagerSony::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize)
372{
373 // Create a sony network manager, and go online
374#ifdef __ORBIS__
375 m_pSQRNet = new SQRNetworkManager_Orbis(this);
376 m_pSQRNet->Initialise();
377#elif defined __PS3__
378 m_pSQRNet = new SQRNetworkManager_PS3(this);
379 m_pSQRNet->Initialise();
380#else // __PSVITA__
381 // m_pSQRNet = new SQRNetworkManager_Vita(this);
382 m_bUsingAdhocMode = false;
383 m_pSQRNet_Vita_Adhoc = new SQRNetworkManager_AdHoc_Vita(this);
384 m_pSQRNet_Vita = new SQRNetworkManager_Vita(this);
385
386 m_pSQRNet = m_pSQRNet_Vita;
387
388 // 4J-PB - seems we can't initialise both adhoc and psn comms - from Rohan - "having adhoc matching and matching2 library initialised together results in undesired behaviour", but probably having other parts initialised also is 'undesirable'
389
390 m_pSQRNet_Vita->Initialise();
391
392 if(ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad()))
393 {
394 // we're signed into the PSN, but we won't be online yet, force a sign-in online here
395 m_pSQRNet_Vita->AttemptPSNSignIn(NULL, NULL);
396 }
397
398
399#endif
400
401 m_pGameNetworkManager = pGameNetworkManager;
402 m_flagIndexSize = flagIndexSize;
403 g_pPlatformNetworkManager = this;
404 for( int i = 0; i < XUSER_MAX_COUNT; i++ )
405 {
406 playerChangedCallback[ i ] = NULL;
407 }
408
409 m_bLeavingGame = false;
410 m_bLeaveGameOnTick = false;
411 m_bHostChanged = false;
412 m_bLeaveRoomWhenLeavingGame = true;
413
414 m_bSearchPending = false;
415
416 m_bIsOfflineGame = false;
417 m_pSearchParam = NULL;
418 m_SessionsUpdatedCallback = NULL;
419
420 m_searchResultsCount = 0;
421 m_pSearchResults = NULL;
422
423 m_lastSearchStartTime = 0;
424
425 // Success!
426 return true;
427}
428
429void CPlatformNetworkManagerSony::Terminate()
430{
431 m_pSQRNet->Terminate();
432}
433
434int CPlatformNetworkManagerSony::GetJoiningReadyPercentage()
435{
436 return m_pSQRNet->GetJoiningReadyPercentage();
437}
438
439int CPlatformNetworkManagerSony::CorrectErrorIDS(int IDS)
440{
441 // Attempts to remap the following messages to provide something that PS3 TCRs are happier with
442 //
443 // IDS_CONNECTION_LOST - "Connection lost"
444 // IDS_CONNECTION_FAILED - "Connection failed"
445 // IDS_CONNECTION_LOST_LIVE - "Connection to "PSN" was lost. Exiting to the main menu."
446 // IDS_CONNECTION_LOST_LIVE_NO_EXIT - "Connection to "PSN" was lost."
447 // IDS_CONNECTION_LOST_SERVER - "Connection to the server was lost. Exiting to the main menu."
448 //
449 // Map to:
450 //
451 // IDS_ERROR_NETWORK - "A network error has occurred"
452 // IDS_ERROR_NETWORK_TITLE - "Network Error"
453 // IDS_ERROR_NETWORK_EXIT - "A network error has occurred. Exiting to Main Menu."
454 // IDS_ERROR_PSN_SIGN_OUT - You have been signed out from the "PSN".
455 // IDS_ERROR_PSN_SIGN_OUT_EXIT - You have been signed out from the "PSN". Exiting to Main Menu
456
457 // Determine if we'd prefer to present errors as a signing out issue, rather than a network issue, based on whether we have a network connection at all or not
458 bool preferSignoutError = false;
459 int state;
460
461#if defined __PSVITA__ // MGH - to fix devtrack #6258
462 if(!ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad()))
463 preferSignoutError = true;
464#elif defined __ORBIS__
465 if(!ProfileManager.isSignedInPSN(ProfileManager.GetPrimaryPad()))
466 preferSignoutError = true;
467#elif defined __PS3__
468 int ret = cellNetCtlGetState( &state );
469 int IPObtainedState = CELL_NET_CTL_STATE_IPObtained;
470 if( ret == 0 )
471 {
472 if( state == IPObtainedState )
473 {
474 preferSignoutError = true;
475 }
476 }
477#endif
478
479#ifdef __PSVITA__
480 // If we're in ad-hoc mode this problem definitely wasn't PSN related
481 if (usingAdhocMode()) preferSignoutError = false;
482#endif
483
484 // If we're the host we haven't lost connection to the server
485 if (IDS == IDS_CONNECTION_LOST_SERVER && g_NetworkManager.IsHost())
486 {
487 IDS = IDS_CONNECTION_LOST_LIVE;
488 }
489
490 switch(IDS)
491 {
492 case IDS_CONNECTION_LOST:
493 case IDS_CONNECTION_FAILED:
494 return IDS_ERROR_NETWORK_TITLE;
495 case IDS_CONNECTION_LOST_LIVE:
496 if( preferSignoutError )
497 {
498 return IDS_ERROR_PSN_SIGN_OUT_EXIT;
499 }
500 else
501 {
502 return IDS_ERROR_NETWORK_EXIT;
503 }
504 case IDS_CONNECTION_LOST_LIVE_NO_EXIT:
505 if( preferSignoutError )
506 {
507 return IDS_ERROR_PSN_SIGN_OUT;
508 }
509 else
510 {
511 return IDS_ERROR_NETWORK_TITLE;
512 }
513 break;
514#ifdef __PSVITA__
515 case IDS_CONNECTION_LOST_SERVER:
516 if(preferSignoutError)
517 {
518 if(ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad()) == false)
519 return IDS_ERROR_PSN_SIGN_OUT_EXIT;
520 }
521#endif
522 default:
523 return IDS;
524 }
525
526
527}
528
529bool CPlatformNetworkManagerSony::isSystemPrimaryPlayer(SQRNetworkPlayer *pSQRPlayer)
530{
531 bool playerIsSystemPrimary = false;
532 for(AUTO_VAR(it, m_machineSQRPrimaryPlayers.begin()); it < m_machineSQRPrimaryPlayers.end(); ++it)
533 {
534 SQRNetworkPlayer *pSQRPrimaryPlayer = *it;
535 if( pSQRPrimaryPlayer == pSQRPlayer )
536 {
537 playerIsSystemPrimary = true;
538 break;
539 }
540 }
541 return playerIsSystemPrimary;
542}
543
544// We call this twice a frame, either side of the render call so is a good place to "tick" things
545void CPlatformNetworkManagerSony::DoWork()
546{
547#if 0
548 DWORD dwNotifyId;
549 ULONG_PTR ulpNotifyParam;
550
551 while( XNotifyGetNext(
552 m_notificationListener,
553 0, // Any notification
554 &dwNotifyId,
555 &ulpNotifyParam)
556 )
557 {
558
559 switch(dwNotifyId)
560 {
561
562 case XN_SYS_SIGNINCHANGED:
563 app.DebugPrintf("Signinchanged - %d\n", ulpNotifyParam);
564 break;
565 case XN_LIVE_INVITE_ACCEPTED:
566 // ignore these - we're catching them from the game listener, so we can get the one from the dashboard
567 break;
568 default:
569 m_pIQNet->Notify(dwNotifyId,ulpNotifyParam);
570 break;
571 }
572
573 }
574
575 TickSearch();
576
577 if( m_bLeaveGameOnTick )
578 {
579 m_pIQNet->LeaveGame(m_migrateHostOnLeave);
580 m_bLeaveGameOnTick = false;
581 }
582
583 m_pIQNet->DoWork();
584#else
585 TickSearch();
586
587 if( m_bLeaveGameOnTick )
588 {
589 m_pSQRNet->LeaveRoom(m_bLeaveRoomWhenLeavingGame);
590 m_bLeaveGameOnTick = false;
591 }
592
593 m_pSQRNet->Tick();
594#endif
595}
596
597int CPlatformNetworkManagerSony::GetPlayerCount()
598{
599 return m_pSQRNet->GetPlayerCount();
600}
601
602bool CPlatformNetworkManagerSony::ShouldMessageForFullSession()
603{
604 return false;
605}
606
607int CPlatformNetworkManagerSony::GetOnlinePlayerCount()
608{
609 return m_pSQRNet->GetOnlinePlayerCount();
610}
611
612int CPlatformNetworkManagerSony::GetLocalPlayerMask(int playerIndex)
613{
614 return 1 << playerIndex;
615}
616
617bool CPlatformNetworkManagerSony::AddLocalPlayerByUserIndex( int userIndex )
618{
619 return m_pSQRNet->AddLocalPlayerByUserIndex(userIndex);
620}
621
622bool CPlatformNetworkManagerSony::RemoveLocalPlayerByUserIndex( int userIndex )
623{
624 SQRNetworkPlayer *pSQRPlayer = m_pSQRNet->GetLocalPlayerByUserIndex(userIndex);
625 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pSQRPlayer);
626
627 if(pNetworkPlayer != NULL)
628 {
629 Socket *socket = pNetworkPlayer->GetSocket();
630
631 if( socket != NULL )
632 {
633 // We can't remove the player from qnet until we have stopped using it to communicate
634 C4JThread* thread = new C4JThread(&CPlatformNetworkManagerSony::RemovePlayerOnSocketClosedThreadProc, pNetworkPlayer, "RemovePlayerOnSocketClosed");
635 thread->SetProcessor( CPU_CORE_REMOVE_PLAYER );
636 thread->Run();
637 }
638 else
639 {
640 // Safe to remove the player straight away
641 return m_pSQRNet->RemoveLocalPlayerByUserIndex(userIndex);
642 }
643 }
644 return true;
645}
646
647bool CPlatformNetworkManagerSony::IsInStatsEnabledSession()
648{
649#if 0
650 DWORD dataSize = sizeof(QNET_LIVE_STATS_MODE);
651 QNET_LIVE_STATS_MODE statsMode;
652 m_pIQNet->GetOpt(QNET_OPTION_LIVE_STATS_MODE, &statsMode , &dataSize );
653
654 // Use QNET_LIVE_STATS_MODE_AUTO if there is another way to check if stats are enabled or not
655 bool statsEnabled = statsMode == QNET_LIVE_STATS_MODE_ENABLED;
656 return m_pIQNet->GetState() != QNET_STATE_IDLE && statsEnabled;
657#endif
658 return true;
659}
660
661bool CPlatformNetworkManagerSony::SessionHasSpace(unsigned int spaceRequired /*= 1*/)
662{
663 return m_pSQRNet->SessionHasSpace(spaceRequired);
664#if 0
665 // This function is used while a session is running, so all players trying to join
666 // should use public slots,
667 DWORD publicSlots = 0;
668 DWORD filledPublicSlots = 0;
669 DWORD privateSlots = 0;
670 DWORD filledPrivateSlots = 0;
671
672 DWORD dataSize = sizeof(DWORD);
673 m_pIQNet->GetOpt(QNET_OPTION_TOTAL_PUBLIC_SLOTS, &publicSlots, &dataSize );
674 m_pIQNet->GetOpt(QNET_OPTION_FILLED_PUBLIC_SLOTS, &filledPublicSlots, &dataSize );
675 m_pIQNet->GetOpt(QNET_OPTION_TOTAL_PRIVATE_SLOTS, &privateSlots, &dataSize );
676 m_pIQNet->GetOpt(QNET_OPTION_FILLED_PRIVATE_SLOTS, &filledPrivateSlots, &dataSize );
677
678 DWORD spaceLeft = (publicSlots - filledPublicSlots) + (privateSlots - filledPrivateSlots);
679
680 return spaceLeft >= spaceRequired;
681#else
682 return true;
683#endif
684}
685
686void CPlatformNetworkManagerSony::SendInviteGUI(int quadrant)
687{
688 m_pSQRNet->SendInviteGUI();
689}
690
691bool CPlatformNetworkManagerSony::IsAddingPlayer()
692{
693 return false;
694}
695
696bool CPlatformNetworkManagerSony::LeaveGame(bool bMigrateHost)
697{
698 if( m_bLeavingGame ) return true;
699
700 m_bLeavingGame = true;
701
702 // If we are a client, wait for all client connections to close
703 // TODO Possibly need to do multiple objects depending on how split screen online works
704 SQRNetworkPlayer *pSQRPlayer = m_pSQRNet->GetLocalPlayerByUserIndex(g_NetworkManager.GetPrimaryPad());
705 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pSQRPlayer);
706
707 if(pNetworkPlayer != NULL)
708 {
709 Socket *socket = pNetworkPlayer->GetSocket();
710
711 if( socket != NULL )
712 {
713 //printf("Waiting for socket closed event\n");
714 DWORD result = socket->m_socketClosedEvent->WaitForSignal(INFINITE);
715
716 // The session might be gone once the socket releases
717 if( IsInSession() )
718 {
719 //printf("Socket closed event has fired\n");
720 // 4J Stu - Clear our reference to this socket
721 pSQRPlayer = m_pSQRNet->GetLocalPlayerByUserIndex(g_NetworkManager.GetPrimaryPad());
722 pNetworkPlayer = getNetworkPlayer(pSQRPlayer);
723 pNetworkPlayer->SetSocket( NULL );
724 }
725 delete socket;
726 }
727 else
728 {
729 //printf("Socket is already NULL\n");
730 }
731 }
732
733 // If we are the host wait for the game server to end
734 if(m_pSQRNet->IsHost() && g_NetworkManager.ServerStoppedValid())
735 {
736 m_pSQRNet->EndGame();
737 g_NetworkManager.ServerStoppedWait();
738 g_NetworkManager.ServerStoppedDestroy();
739 }
740
741 return _LeaveGame(bMigrateHost, true);
742}
743
744bool CPlatformNetworkManagerSony::_LeaveGame(bool bMigrateHost, bool bLeaveRoom)
745{
746 // 4J Stu - Fix for #10490 - TCR 001 BAS Game Stability: When a party of four players leave a world to join another world without saving the title will crash.
747 // Changed this to make it threadsafe
748 m_bLeavingGame = true; // Added for Sony platforms but unsure why the 360 doesn't need it - without this, the leaving triggered by this causes the game to respond by leaving again when it transitions to the SNM_STATE_ENDING state
749 m_bLeaveRoomWhenLeavingGame = bLeaveRoom;
750 m_bLeaveGameOnTick = true;
751 m_migrateHostOnLeave = bMigrateHost;
752
753 return true;
754}
755
756void CPlatformNetworkManagerSony::HostGame(int localUsersMask, bool bOnlineGame, bool bIsPrivate, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/)
757{
758// #ifdef _XBOX
759 // 4J Stu - We probably did this earlier as well, but just to be sure!
760 SetLocalGame( !bOnlineGame );
761 SetPrivateGame( bIsPrivate );
762 SystemFlagReset();
763
764 // Make sure that the Primary Pad is in by default
765 localUsersMask |= GetLocalPlayerMask( g_NetworkManager.GetPrimaryPad() );
766
767 _HostGame( localUsersMask, publicSlots, privateSlots );
768//#endif
769}
770
771void CPlatformNetworkManagerSony::_HostGame(int usersMask, unsigned char publicSlots /*= MINECRAFT_NET_MAX_PLAYERS*/, unsigned char privateSlots /*= 0*/)
772{
773 // Start hosting a new game
774
775 memset(&m_hostGameSessionData,0,sizeof(m_hostGameSessionData));
776 m_hostGameSessionData.netVersion = MINECRAFT_NET_VERSION;
777 m_hostGameSessionData.isJoinable = !IsPrivateGame();
778 m_hostGameSessionData.isReadyToJoin = false;
779 m_hostGameSessionData.playerCount = 0;
780 m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All);
781 for( int i = 0; i < SQRNetworkManager::MAX_LOCAL_PLAYER_COUNT; i++ )
782 {
783 if( usersMask & ( 1 << i ) )
784 {
785 m_hostGameSessionData.playerCount++;
786 }
787 }
788
789 m_pSQRNet->CreateAndJoinRoom(g_NetworkManager.GetPrimaryPad(),usersMask, &m_hostGameSessionData, sizeof(m_hostGameSessionData), IsLocalGame()); // Should be using: g_NetworkManager.GetLockedProfile() but that isn't being set currently
790}
791
792bool CPlatformNetworkManagerSony::_StartGame()
793{
794#if 0
795 // Set the options that now allow players to join this game
796 BOOL enableJip = TRUE; // Must always be true othewise nobody can join the game while in the PLAY state
797 m_pIQNet->SetOpt( QNET_OPTION_JOIN_IN_PROGRESS_ALLOWED, &enableJip, sizeof BOOL );
798 BOOL enableInv = !IsLocalGame();
799 m_pIQNet->SetOpt( QNET_OPTION_INVITES_ALLOWED, &enableInv, sizeof BOOL );
800 BOOL enablePres = !IsPrivateGame() && !IsLocalGame();
801 m_pIQNet->SetOpt( QNET_OPTION_PRESENCE_JOIN_MODE, &enablePres, sizeof BOOL );
802
803 return ( m_pIQNet->StartGame() == S_OK );
804#else
805 m_pSQRNet->StartGame();
806 return true;
807#endif
808}
809
810int CPlatformNetworkManagerSony::JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex)
811{
812 int joinPlayerCount = 0;
813 for( int i = 0; i < SQRNetworkManager::MAX_LOCAL_PLAYER_COUNT; i++ )
814 {
815 if( localUsersMask & ( 1 << i ) )
816 {
817 joinPlayerCount++;
818 }
819 }
820 GameSessionData *gameSession = (GameSessionData *)(&searchResult->data);
821 if( ( gameSession->playerCount + joinPlayerCount ) > SQRNetworkManager::MAX_ONLINE_PLAYER_COUNT )
822 {
823 return CGameNetworkManager::JOINGAME_FAIL_SERVER_FULL;
824 }
825
826 if( m_pSQRNet->JoinRoom(&searchResult->searchResult, localUsersMask) )
827 {
828 return CGameNetworkManager::JOINGAME_SUCCESS;
829 }
830 else
831 {
832 return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
833 }
834}
835
836bool CPlatformNetworkManagerSony::SetLocalGame(bool isLocal)
837{
838 if( m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_IDLE)
839 {
840#if 0
841 QNET_SESSIONTYPE sessionType = isLocal ? QNET_SESSIONTYPE_LOCAL : QNET_SESSIONTYPE_LIVE_STANDARD;
842 m_pIQNet->SetOpt(QNET_OPTION_TYPE_SESSIONTYPE, &sessionType , sizeof QNET_SESSIONTYPE);
843
844 // The default value for this is QNET_LIVE_STATS_MODE_AUTO, but that decides based on the players
845 // in when the game starts. As we may want a non-live player to join the game we cannot have stats enabled
846 // when we create the sessions. As a result of this, the NotifyWriteStats callback will not be called for
847 // LIVE players that are connected to LIVE so we write their stats data on a state change.
848 QNET_LIVE_STATS_MODE statsMode = isLocal ? QNET_LIVE_STATS_MODE_DISABLED : QNET_LIVE_STATS_MODE_ENABLED;
849 m_pIQNet->SetOpt(QNET_OPTION_LIVE_STATS_MODE, &statsMode , sizeof QNET_LIVE_STATS_MODE);
850
851 // Also has a default of QNET_LIVE_PRESENCE_MODE_AUTO as above, although the effects are less of an issue
852 QNET_LIVE_PRESENCE_MODE presenceMode = isLocal ? QNET_LIVE_PRESENCE_MODE_NOT_ADVERTISED : QNET_LIVE_PRESENCE_MODE_ADVERTISED;
853 m_pIQNet->SetOpt(QNET_OPTION_LIVE_PRESENCE_MODE, &presenceMode , sizeof QNET_LIVE_PRESENCE_MODE);
854#endif
855
856 m_bIsOfflineGame = isLocal;
857 app.DebugPrintf("Setting as local game: %s\n", isLocal ? "yes" : "no" );
858 }
859 else
860 {
861 app.DebugPrintf("Tried to change session type while not in idle or offline state\n");
862 }
863
864 return true;
865}
866
867void CPlatformNetworkManagerSony::SetPrivateGame(bool isPrivate)
868{
869 app.DebugPrintf("Setting as private game: %s\n", isPrivate ? "yes" : "no" );
870 m_bIsPrivateGame = isPrivate;
871}
872
873void CPlatformNetworkManagerSony::RegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam)
874{
875 playerChangedCallback[iPad] = callback;
876 playerChangedCallbackParam[iPad] = callbackParam;
877}
878
879void CPlatformNetworkManagerSony::UnRegisterPlayerChangedCallback(int iPad, void (*callback)(void *callbackParam, INetworkPlayer *pPlayer, bool leaving), void *callbackParam)
880{
881 if(playerChangedCallbackParam[iPad] == callbackParam)
882 {
883 playerChangedCallback[iPad] = NULL;
884 playerChangedCallbackParam[iPad] = NULL;
885 }
886}
887
888void CPlatformNetworkManagerSony::HandleSignInChange()
889{
890 return;
891}
892
893bool CPlatformNetworkManagerSony::_RunNetworkGame()
894{
895#if 0
896 // We delay actually starting the session so that we know the game server is running by the time the clients try to join
897 // This does result in a host advantage
898 HRESULT hr = m_pIQNet->StartGame();
899 if(FAILED(hr)) return false;
900
901 // Set the options that now allow players to join this game
902 BOOL enableJip = TRUE; // Must always be true othewise nobody can join the game while in the PLAY state
903 m_pIQNet->SetOpt( QNET_OPTION_JOIN_IN_PROGRESS_ALLOWED, &enableJip, sizeof BOOL );
904 BOOL enableInv = !IsLocalGame();
905 m_pIQNet->SetOpt( QNET_OPTION_INVITES_ALLOWED, &enableInv, sizeof BOOL );
906 BOOL enablePres = !IsPrivateGame() && !IsLocalGame();
907 m_pIQNet->SetOpt( QNET_OPTION_PRESENCE_JOIN_MODE, &enablePres, sizeof BOOL );
908#endif
909 if( IsHost() )
910 {
911 m_pSQRNet->StartGame();
912 m_hostGameSessionData.isReadyToJoin = true;
913 m_pSQRNet->UpdateExternalRoomData();
914 m_pSQRNet->SetPresenceDataStartHostingGame();
915 }
916
917 return true;
918}
919
920// Note that this does less than the xbox equivalent as we have HandleResyncPlayerRequest that is called by the underlying SQRNetworkManager when players are added/removed etc., so this
921// call is only used to update the game host settings & then do the final push out of the data.
922void CPlatformNetworkManagerSony::UpdateAndSetGameSessionData(INetworkPlayer *pNetworkPlayerLeaving /*= NULL*/)
923{
924 if( this->m_bLeavingGame )
925 return;
926
927 m_hostGameSessionData.hostPlayerUID = GetHostPlayer()->GetUID();
928#ifdef __PSVITA__
929 if(usingAdhocMode())
930 {
931 m_hostGameSessionData.hostPlayerUID.setForAdhoc();
932 }
933#endif
934
935 m_hostGameSessionData.m_uiGameHostSettings = app.GetGameHostOption(eGameHostOption_All);
936
937 // If this is called With a pNetworkPlayerLeaving, then the call has ultimately started within SQRNetworkManager::RemoveRemotePlayersAndSync, so we don't need to sync each change
938 // as that function does a sync at the end of all changes.
939 if( pNetworkPlayerLeaving == NULL )
940 {
941 m_pSQRNet->UpdateExternalRoomData();
942 }
943}
944
945int CPlatformNetworkManagerSony::RemovePlayerOnSocketClosedThreadProc( void* lpParam )
946{
947 INetworkPlayer *pNetworkPlayer = (INetworkPlayer *)lpParam;
948
949 Socket *socket = pNetworkPlayer->GetSocket();
950
951 if( socket != NULL )
952 {
953 //printf("Waiting for socket closed event\n");
954 socket->m_socketClosedEvent->WaitForSignal(INFINITE);
955
956 //printf("Socket closed event has fired\n");
957 // 4J Stu - Clear our reference to this socket
958 pNetworkPlayer->SetSocket( NULL );
959 delete socket;
960 }
961
962 return g_pPlatformNetworkManager->RemoveLocalPlayer( pNetworkPlayer );
963}
964
965bool CPlatformNetworkManagerSony::RemoveLocalPlayer( INetworkPlayer *pNetworkPlayer )
966{
967 if( pNetworkPlayer->IsLocal() )
968 {
969 return m_pSQRNet->RemoveLocalPlayerByUserIndex( pNetworkPlayer->GetUserIndex() );
970 }
971
972 return true;
973}
974
975CPlatformNetworkManagerSony::PlayerFlags::PlayerFlags(INetworkPlayer *pNetworkPlayer, unsigned int count)
976{
977 // 4J Stu - Don't assert, just make it a multiple of 8! This count is calculated from a load of separate values,
978 // and makes tweaking world/render sizes a pain if we hit an assert here
979 count = (count + 8 - 1) & ~(8 - 1);
980 //assert( ( count % 8 ) == 0 );
981 this->m_pNetworkPlayer = pNetworkPlayer;
982 this->flags = new unsigned char [ count / 8 ];
983 memset( this->flags, 0, count / 8 );
984 this->count = count;
985}
986CPlatformNetworkManagerSony::PlayerFlags::~PlayerFlags()
987{
988 delete [] flags;
989}
990
991// Add a player to the per system flag storage - if we've already got a player from that system, copy its flags over
992void CPlatformNetworkManagerSony::SystemFlagAddPlayer(INetworkPlayer *pNetworkPlayer)
993{
994 PlayerFlags *newPlayerFlags = new PlayerFlags( pNetworkPlayer, m_flagIndexSize);
995 // If any of our existing players are on the same system, then copy over flags from that one
996 for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
997 {
998 if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) )
999 {
1000 memcpy( newPlayerFlags->flags, m_playerFlags[i]->flags, m_playerFlags[i]->count / 8 );
1001 break;
1002 }
1003 }
1004 m_playerFlags.push_back(newPlayerFlags);
1005}
1006
1007// Remove a player from the per system flag storage - just maintains the m_playerFlags vector without any gaps in it
1008void CPlatformNetworkManagerSony::SystemFlagRemovePlayer(INetworkPlayer *pNetworkPlayer)
1009{
1010 for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
1011 {
1012 if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer )
1013 {
1014 delete m_playerFlags[i];
1015 m_playerFlags[i] = m_playerFlags.back();
1016 m_playerFlags.pop_back();
1017 return;
1018 }
1019 }
1020}
1021
1022void CPlatformNetworkManagerSony::SystemFlagReset()
1023{
1024 for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
1025 {
1026 delete m_playerFlags[i];
1027 }
1028 m_playerFlags.clear();
1029}
1030
1031// Set a per system flag - this is done by setting the flag on every player that shares that system
1032void CPlatformNetworkManagerSony::SystemFlagSet(INetworkPlayer *pNetworkPlayer, int index)
1033{
1034 if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return;
1035 if( pNetworkPlayer == NULL ) return;
1036
1037 for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
1038 {
1039 if( pNetworkPlayer->IsSameSystem(m_playerFlags[i]->m_pNetworkPlayer) )
1040 {
1041 m_playerFlags[i]->flags[ index / 8 ] |= ( 128 >> ( index % 8 ) );
1042 }
1043 }
1044}
1045
1046// Get value of a per system flag - can be read from the flags of the passed in player as anything else sent to that
1047// system should also have been duplicated here
1048bool CPlatformNetworkManagerSony::SystemFlagGet(INetworkPlayer *pNetworkPlayer, int index)
1049{
1050 if( ( index < 0 ) || ( index >= m_flagIndexSize ) ) return false;
1051 if( pNetworkPlayer == NULL )
1052 {
1053 return false;
1054 }
1055
1056 for( unsigned int i = 0; i < m_playerFlags.size(); i++ )
1057 {
1058 if( m_playerFlags[i]->m_pNetworkPlayer == pNetworkPlayer )
1059 {
1060 return ( ( m_playerFlags[i]->flags[ index / 8 ] & ( 128 >> ( index % 8 ) ) ) != 0 );
1061 }
1062 }
1063 return false;
1064}
1065
1066wstring CPlatformNetworkManagerSony::GatherStats()
1067{
1068#if 0
1069 return L"Queue messages: " + _toString(((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetSendQueueSize( NULL, QNET_GETSENDQUEUESIZE_MESSAGES ) )
1070 + L" Queue bytes: " + _toString( ((NetworkPlayerXbox *)GetHostPlayer())->GetQNetPlayer()->GetSendQueueSize( NULL, QNET_GETSENDQUEUESIZE_BYTES ) );
1071#else
1072 return L"";
1073#endif
1074}
1075
1076wstring CPlatformNetworkManagerSony::GatherRTTStats()
1077{
1078#if 0
1079 wstring stats(L"Rtt: ");
1080
1081 wchar_t stat[32];
1082
1083 for(unsigned int i = 0; i < GetPlayerCount(); ++i)
1084 {
1085 SQRNetworkPlayer *pSQRPlayer = ((NetworkPlayerXbox *)GetPlayerByIndex( i ))->GetQNetPlayer();
1086
1087 if(!pSQRPlayer->IsLocal())
1088 {
1089 ZeroMemory(stat,32);
1090 swprintf(stat, 32, L"%d: %d/", i, pSQRPlayer->GetCurrentRtt() );
1091 stats.append(stat);
1092 }
1093 }
1094 return stats;
1095#else
1096 return L"";
1097#endif
1098}
1099
1100void CPlatformNetworkManagerSony::TickSearch()
1101{
1102 if( m_bSearchPending )
1103 {
1104 if( !m_pSQRNet->FriendRoomManagerIsBusy() )
1105 {
1106 m_searchResultsCount = m_pSQRNet->FriendRoomManagerGetCount();
1107 delete m_pSearchResults;
1108 m_pSearchResults = new SQRNetworkManager::SessionSearchResult[m_searchResultsCount];
1109
1110 for( int i = 0; i < m_searchResultsCount; i++ )
1111 {
1112 m_pSQRNet->FriendRoomManagerGetRoomInfo(i, &m_pSearchResults[i] );
1113 }
1114 m_bSearchPending = false;
1115
1116 if( m_SessionsUpdatedCallback != NULL ) m_SessionsUpdatedCallback(m_pSearchParam);
1117 }
1118 }
1119 else
1120 {
1121 if( !m_pSQRNet->FriendRoomManagerIsBusy() )
1122 {
1123 // Don't start searches unless we have registered a callback
1124 int searchDelay = MINECRAFT_PS3ROOM_SEARCH_DELAY_MILLISECONDS;
1125#ifdef __PSVITA__
1126 // in adhoc mode we can keep searching, as the friend list is populated in callbacks
1127 // 4J Stu - Every second seems a bit much as it makes the friend list flash every time it updates. Changed this to 5 seconds.
1128 if( usingAdhocMode())
1129 searchDelay = 5000;
1130#endif
1131 if( m_SessionsUpdatedCallback != NULL && (m_lastSearchStartTime + searchDelay) < GetTickCount() )
1132 {
1133 if( m_pSQRNet->FriendRoomManagerSearch() )
1134 {
1135 m_bSearchPending = true;
1136 m_lastSearchStartTime = GetTickCount();
1137 }
1138 }
1139 }
1140 }
1141}
1142
1143vector<FriendSessionInfo *> *CPlatformNetworkManagerSony::GetSessionList(int iPad, int localPlayers, bool partyOnly)
1144{
1145 vector<FriendSessionInfo *> *filteredList = new vector<FriendSessionInfo *>();
1146 for( int i = 0; i < m_searchResultsCount; i++ )
1147 {
1148 if( m_pSearchResults[i].m_extData )
1149 {
1150 FriendSessionInfo *newInfo = new FriendSessionInfo();
1151 newInfo->displayLabel = new wchar_t[17];
1152 ZeroMemory(newInfo->displayLabel, sizeof(wchar_t)*17);
1153 // TODO - this mbstowcs shouldn't encounter any non-ascii characters, but I imagine we'll want to actually use the online name here which is UTF-8
1154 mbstowcs(newInfo->displayLabel, m_pSearchResults[i].m_NpId.handle.data, 17);
1155 newInfo->displayLabelLength = strlen(m_pSearchResults[i].m_NpId.handle.data);
1156 newInfo->hasPartyMember = false;
1157 newInfo->searchResult = m_pSearchResults[i];
1158 newInfo->sessionId = m_pSearchResults[i].m_sessionId;
1159 memcpy(&newInfo->data, m_pSearchResults[i].m_extData, sizeof(GameSessionData));
1160 if( ( newInfo->data.isReadyToJoin ) &&
1161 ( newInfo->data.isJoinable ) &&
1162 ( newInfo->data.netVersion == MINECRAFT_NET_VERSION ) )
1163 {
1164 filteredList->push_back(newInfo);
1165 }
1166 else
1167 {
1168 delete newInfo;
1169 }
1170 }
1171 }
1172
1173 return filteredList;
1174}
1175
1176bool CPlatformNetworkManagerSony::GetGameSessionInfo(int iPad, SessionID sessionId, FriendSessionInfo *foundSessionInfo)
1177{
1178#if 0
1179 HRESULT hr = E_FAIL;
1180
1181 const XSESSION_SEARCHRESULT *pSearchResult;
1182 const XNQOSINFO * pxnqi;
1183
1184 if( m_currentSearchResultsCount[iPad] > 0 )
1185 {
1186 // Loop through all the results.
1187 for( DWORD dwResult = 0; dwResult < m_currentSearchResultsCount[iPad]; dwResult++ )
1188 {
1189 pSearchResult = &m_pCurrentSearchResults[iPad]->pResults[dwResult];
1190
1191 if(memcmp( &pSearchResult->info.sessionID, &sessionId, sizeof(SessionID) ) != 0) continue;
1192
1193 bool foundSession = false;
1194 FriendSessionInfo *sessionInfo = NULL;
1195 AUTO_VAR(itFriendSession, friendsSessions[iPad].begin());
1196 for(itFriendSession = friendsSessions[iPad].begin(); itFriendSession < friendsSessions[iPad].end(); ++itFriendSession)
1197 {
1198 sessionInfo = *itFriendSession;
1199 if(memcmp( &pSearchResult->info.sessionID, &sessionInfo->sessionId, sizeof(SessionID) ) == 0)
1200 {
1201 sessionInfo->searchResult = *pSearchResult;
1202 sessionInfo->displayLabel = new wchar_t[100];
1203 ZeroMemory( sessionInfo->displayLabel, 100 * sizeof(wchar_t) );
1204 foundSession = true;
1205 break;
1206 }
1207 }
1208
1209 // We received a search result for a session no longer in our list of friends sessions
1210 if(!foundSession) break;
1211
1212 // See if this result was contacted successfully via QoS probes.
1213 pxnqi = &m_pCurrentQoSResult[iPad]->axnqosinfo[dwResult];
1214 if( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_CONTACTED )
1215 {
1216
1217 if(pxnqi->cbData > 0)
1218 {
1219 sessionInfo->data = *(GameSessionData *)pxnqi->pbData;
1220
1221 wstring gamerName = convStringToWstring(sessionInfo->data.hostName);
1222 swprintf(sessionInfo->displayLabel,app.GetString(IDS_GAME_HOST_NAME),L"MWWWWWWWWWWWWWWM");// gamerName.c_str() );
1223 }
1224 else
1225 {
1226 swprintf(sessionInfo->displayLabel,app.GetString(IDS_GAME_HOST_NAME_UNKNOWN));
1227 }
1228 sessionInfo->displayLabelLength = wcslen( sessionInfo->displayLabel );
1229
1230 // If this host wasn't disabled use this one.
1231 if( !( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_DISABLED ) &&
1232 sessionInfo->data.netVersion == MINECRAFT_NET_VERSION &&
1233 sessionInfo->data.isJoinable)
1234 {
1235 foundSessionInfo->data = sessionInfo->data;
1236 if(foundSessionInfo->displayLabel != NULL) delete [] foundSessionInfo->displayLabel;
1237 foundSessionInfo->displayLabel = new wchar_t[100];
1238 memcpy(foundSessionInfo->displayLabel, sessionInfo->displayLabel, 100 * sizeof(wchar_t) );
1239 foundSessionInfo->displayLabelLength = sessionInfo->displayLabelLength;
1240 foundSessionInfo->hasPartyMember = sessionInfo->hasPartyMember;
1241 foundSessionInfo->searchResult = sessionInfo->searchResult;
1242 foundSessionInfo->sessionId = sessionInfo->sessionId;
1243
1244 hr = S_OK;
1245 }
1246 }
1247 }
1248 }
1249
1250 return ( hr == S_OK );
1251#else
1252 return false;
1253#endif
1254}
1255
1256void CPlatformNetworkManagerSony::SetSessionsUpdatedCallback( void (*SessionsUpdatedCallback)(LPVOID pParam), LPVOID pSearchParam )
1257{
1258 m_SessionsUpdatedCallback = SessionsUpdatedCallback; m_pSearchParam = pSearchParam;
1259}
1260
1261void CPlatformNetworkManagerSony::GetFullFriendSessionInfo( FriendSessionInfo *foundSession, void (* FriendSessionUpdatedFn)(bool success, void *pParam), void *pParam )
1262{
1263 m_pSQRNet->GetExtDataForRoom( foundSession->sessionId.m_RoomId, &foundSession->data, FriendSessionUpdatedFn, pParam);
1264}
1265
1266void CPlatformNetworkManagerSony::ForceFriendsSessionRefresh()
1267{
1268 app.DebugPrintf("Resetting friends session search data\n");
1269 m_lastSearchStartTime = 0;
1270 m_searchResultsCount = 0;
1271 delete m_pSearchResults;
1272 m_pSearchResults = NULL;
1273}
1274
1275INetworkPlayer *CPlatformNetworkManagerSony::addNetworkPlayer(SQRNetworkPlayer *pSQRPlayer)
1276{
1277 NetworkPlayerSony *pNetworkPlayer = new NetworkPlayerSony(pSQRPlayer);
1278 pSQRPlayer->SetCustomDataValue((ULONG_PTR)pNetworkPlayer);
1279 currentNetworkPlayers.push_back( pNetworkPlayer );
1280 return pNetworkPlayer;
1281}
1282
1283void CPlatformNetworkManagerSony::removeNetworkPlayer(SQRNetworkPlayer *pSQRPlayer)
1284{
1285 INetworkPlayer *pNetworkPlayer = getNetworkPlayer(pSQRPlayer);
1286 for( AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++ )
1287 {
1288 if( *it == pNetworkPlayer )
1289 {
1290 currentNetworkPlayers.erase(it);
1291 return;
1292 }
1293 }
1294}
1295
1296INetworkPlayer *CPlatformNetworkManagerSony::getNetworkPlayer(SQRNetworkPlayer *pSQRPlayer)
1297{
1298 return pSQRPlayer ? (INetworkPlayer *)(pSQRPlayer->GetCustomDataValue()) : NULL;
1299}
1300
1301
1302INetworkPlayer *CPlatformNetworkManagerSony::GetLocalPlayerByUserIndex(int userIndex )
1303{
1304 return getNetworkPlayer(m_pSQRNet->GetLocalPlayerByUserIndex(userIndex));
1305}
1306
1307INetworkPlayer *CPlatformNetworkManagerSony::GetPlayerByIndex(int playerIndex)
1308{
1309 return getNetworkPlayer(m_pSQRNet->GetPlayerByIndex(playerIndex));
1310}
1311
1312INetworkPlayer * CPlatformNetworkManagerSony::GetPlayerByXuid(PlayerUID xuid)
1313{
1314 return getNetworkPlayer(m_pSQRNet->GetPlayerByXuid(xuid));
1315}
1316
1317INetworkPlayer * CPlatformNetworkManagerSony::GetPlayerBySmallId(unsigned char smallId)
1318{
1319 return getNetworkPlayer(m_pSQRNet->GetPlayerBySmallId(smallId));
1320}
1321
1322INetworkPlayer *CPlatformNetworkManagerSony::GetHostPlayer()
1323{
1324 return getNetworkPlayer(m_pSQRNet->GetHostPlayer());
1325}
1326
1327bool CPlatformNetworkManagerSony::IsHost()
1328{
1329 return m_pSQRNet->IsHost() && !m_bHostChanged;
1330}
1331
1332bool CPlatformNetworkManagerSony::JoinGameFromInviteInfo( int userIndex, int userMask, const INVITE_INFO *pInviteInfo)
1333{
1334 return m_pSQRNet->JoinRoom( pInviteInfo->m_RoomId, pInviteInfo->m_ServerId, userMask, pInviteInfo );
1335}
1336
1337void CPlatformNetworkManagerSony::SetSessionTexturePackParentId( int id )
1338{
1339 m_hostGameSessionData.texturePackParentId = id;
1340}
1341
1342void CPlatformNetworkManagerSony::SetSessionSubTexturePackId( int id )
1343{
1344 m_hostGameSessionData.subTexturePackId = id;
1345}
1346
1347void CPlatformNetworkManagerSony::Notify(int ID, ULONG_PTR Param)
1348{
1349#if 0
1350 m_pSQRNet->Notify( ID, Param );
1351#endif
1352}
1353
1354bool CPlatformNetworkManagerSony::IsInSession()
1355{
1356 return m_pSQRNet->IsInSession();
1357}
1358
1359bool CPlatformNetworkManagerSony::IsInGameplay()
1360{
1361 return m_pSQRNet->GetState() == SQRNetworkManager::SNM_STATE_PLAYING;
1362}
1363
1364bool CPlatformNetworkManagerSony::IsReadyToPlayOrIdle()
1365{
1366 return m_pSQRNet->IsReadyToPlayOrIdle();
1367}
1368
1369void CPlatformNetworkManagerSony::SetSQRPresenceInfoFromExtData(SQRNetworkManager::PresenceSyncInfo *presence, void *pExtData, SceNpMatching2RoomId roomId, SceNpMatching2ServerId serverId)
1370{
1371 GameSessionData *gsd = (GameSessionData *)pExtData;
1372
1373 memcpy(&presence->hostPlayerUID, &gsd->hostPlayerUID, sizeof(GameSessionUID) );
1374 presence->m_RoomId = roomId;
1375 presence->m_ServerId = serverId;
1376 presence->texturePackParentId = gsd->texturePackParentId;
1377 presence->subTexturePackId = gsd->subTexturePackId;
1378 presence->netVersion = gsd->netVersion;
1379 presence->inviteOnly = !gsd->isJoinable;
1380}
1381
1382void CPlatformNetworkManagerSony::MallocAndSetExtDataFromSQRPresenceInfo(void **pExtData, SQRNetworkManager::PresenceSyncInfo *presence)
1383{
1384 GameSessionData *gsd = (GameSessionData *)malloc(sizeof(GameSessionData));
1385 memset(gsd, 0, sizeof(GameSessionData));
1386 if( presence->netVersion != 0 )
1387 {
1388 memcpy(&gsd->hostPlayerUID, &presence->hostPlayerUID, sizeof(GameSessionUID) );
1389 gsd->texturePackParentId = presence->texturePackParentId;
1390 gsd->subTexturePackId = presence->subTexturePackId;
1391 gsd->netVersion = presence->netVersion;
1392 gsd->isJoinable = !presence->inviteOnly;
1393 gsd->isReadyToJoin = true;
1394 }
1395 *pExtData = gsd;
1396}
1397
1398#ifdef __PSVITA__
1399bool CPlatformNetworkManagerSony::setAdhocMode( bool bAdhoc )
1400{
1401 if(m_bUsingAdhocMode != bAdhoc)
1402 {
1403 m_bUsingAdhocMode = bAdhoc;
1404 if(m_bUsingAdhocMode)
1405 {
1406 // uninit the PSN, and init adhoc
1407 if(m_pSQRNet_Vita->IsInitialised())
1408 {
1409 m_pSQRNet_Vita->UnInitialise();
1410 }
1411
1412 if(m_pSQRNet_Vita_Adhoc->IsInitialised()==false)
1413 {
1414 m_pSQRNet_Vita_Adhoc->Initialise();
1415 }
1416
1417 m_pSQRNet = m_pSQRNet_Vita_Adhoc;
1418 }
1419 else
1420 {
1421 if(m_pSQRNet_Vita_Adhoc->IsInitialised())
1422 {
1423 int ret = sceNetCtlAdhocDisconnect();
1424 // uninit the adhoc, and init psn
1425 m_pSQRNet_Vita_Adhoc->UnInitialise();
1426 }
1427
1428 if(m_pSQRNet_Vita->IsInitialised()==false)
1429 {
1430 m_pSQRNet_Vita->Initialise();
1431 }
1432
1433 m_pSQRNet = m_pSQRNet_Vita;
1434 }
1435 }
1436
1437 return true;
1438}
1439
1440void CPlatformNetworkManagerSony::startAdhocMatching( )
1441{
1442 assert(m_pSQRNet == m_pSQRNet_Vita_Adhoc);
1443 ((SQRNetworkManager_AdHoc_Vita*)m_pSQRNet_Vita_Adhoc)->startMatching();
1444}
1445
1446bool CPlatformNetworkManagerSony::checkValidInviteData(const INVITE_INFO* pInviteInfo)
1447{
1448 SQRNetworkManager_Vita* pSQR = (SQRNetworkManager_Vita*)m_pSQRNet_Vita;
1449 if(pSQR->IsOnlineGame() && !pSQR->IsHost()&& (pSQR->GetHostUID() == pInviteInfo->hostPlayerUID))
1450 {
1451 // we're trying to join a game we're already in, so we just ignore this
1452 return false;
1453 }
1454 else
1455 {
1456 return true;
1457 }
1458}
1459
1460
1461
1462#endif // __PSVITA__