!I 1937152 from //dev_game_hunt/consoles_candidate: !B Remove allocations of unnecess...
[CRYENGINE.git] / Code / CryPlugins / CryLobby / Module / DurangoLive / CryDurangoLiveMatchMaking.cpp
blob07b687e57ae239b5a9128025bf32dc1b811fba1c
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "CryDurangoLiveLobby.h"
6 #if USE_DURANGOLIVE && USE_CRY_MATCHMAKING
7 #using <windows.winmd>
8 #using <platform.winmd>
9 #using <Microsoft.Xbox.Services.winmd>
10 #using <Microsoft.Xbox.GameChat.winmd>
12 #include <CryCore/TypeInfo_impl.h>
14 #include "CryDurangoLiveMatchMaking.h"
15 #include "CryDurangoLiveLobbyPacket.h"
17 #include <CryCore/Platform/IPlatformOS.h>
19 #define TDM_SESSION_CREATE_SESSION_DATA 0
20 #define TDM_SESSION_CREATE_USERDATA 1
21 #define TDN_SESSION_CREATE_NUMUSERDATA 1
23 #define TDM_SESSION_UPDATE_USERDATA 0
24 #define TDN_SESSION_UPDATE_NUMUSERDATA 0
26 #define TDM_SESSION_SEARCH_PARAM 0
27 #define TDM_SESSION_SEARCH_PARAMDATA 1
28 #define TDN_SESSION_SEARCH_PARAMNUMDATA 1
30 #define TDN_UPDATE_SLOTS_PUBLIC 0
31 #define TDN_UPDATE_SLOTS_PRIVATE 1
33 #define TDM_SESSION_JOIN_CONNECTION_COUNTER 0
34 #define CONNECTION_JOIN_SEND_INTERVAL 1000
35 #define CONNECTION_JOIN_MAX_SEND_TIMES 30
37 #define GET_REMOTE_SDA_TIMEOUT 20000
39 #define SESSION_ID_ZERO 0
41 #pragma warning(push)
42 #pragma warning(disable:6011 6102 6246)
44 using namespace ABI::Windows::Foundation;
45 using namespace ABI::Windows::Storage::Streams;
46 using namespace Microsoft::WRL;
47 using namespace ABI::Windows::Xbox::Networking;
48 using namespace ABI::Windows::Xbox::System;
50 // XXX - ATG
51 #include "DurangoChat\ChatIntegrationLayer.h"
53 static const GUID SERVICECONFIG_GUID =
55 0xe1039253, 0x2550, 0x49c7, { 0xb7, 0x85, 0x49, 0x34, 0xf0, 0x78, 0xc6, 0x85 }
58 CCryDurangoLiveMatchMaking::CCryDurangoLiveMatchMaking(CCryLobby* pLobby, CCryLobbyService* pService, ECryLobbyService serviceType) : CCryMatchMaking(pLobby, pService, serviceType), m_user(nullptr)
60 m_AssociationIncoming.value = 0;
62 // Make the CCryMatchMaking base pointers point to our data so we can use the common code in CCryMatchMaking
63 for (uint32 i = 0; i < MAX_MATCHMAKING_SESSIONS; i++)
65 CCryMatchMaking::m_sessions[i] = &m_sessions[i];
66 CCryMatchMaking::m_sessions[i]->localConnection = &m_sessions[i].localConnection;
68 for (uint32 j = 0; j < MAX_LOBBY_CONNECTIONS; j++)
70 CCryMatchMaking::m_sessions[i]->remoteConnection[j] = &m_sessions[i].remoteConnection[j];
74 for (uint32 i = 0; i < MAX_MATCHMAKING_TASKS; i++)
76 CCryMatchMaking::m_task[i] = &m_task[i];
81 CryLobbySessionHandle CCryDurangoLiveMatchMaking::FindSessionFromID(GUID const& sessionID)
83 for (uint32 i = 0; i < MAX_MATCHMAKING_SESSIONS; i++)
85 if (m_sessions[i].localFlags & CRYSESSION_LOCAL_FLAG_USED)
87 if (IsEqualGUID(m_sessions[i].sessionID, sessionID))
89 return i;
94 return CryLobbyInvalidSessionHandle;
97 void CCryDurangoLiveMatchMaking::StartAsyncActionTask(CryMatchMakingTaskID mmTaskID, IAsyncAction* pAsyncAction)
99 STask* pTask = &m_task[mmTaskID];
101 pTask->asyncTaskState = STask::eATS_Pending;
103 StartConcurrencyTaskTask(mmTaskID, ABI::Concurrency::task_from_async(pAsyncAction));
106 void CCryDurangoLiveMatchMaking::StartConcurrencyTaskTask(CryMatchMakingTaskID mmTaskID, concurrency::task<HRESULT> pConcTask)
108 STask* pTask = &m_task[mmTaskID];
110 pTask->asyncTaskState = STask::eATS_Pending;
112 concurrency::cancellation_token_source src;
113 pConcTask.then([this, mmTaskID](HRESULT res)
115 STask* pTask = &m_task[mmTaskID];
116 if (SUCCEEDED(res))
118 pTask->asyncTaskState = STask::eATS_Success;
119 return;
122 pTask->asyncTaskState = STask::eATS_Failed;
123 UpdateTaskError(mmTaskID, CryDurangoLiveLobbyGetErrorFromDurangoLive(res));
124 }, src.get_token(), concurrency::task_continuation_context::use_current());
127 ECryLobbyError CCryDurangoLiveMatchMaking::StartTask(ETask etask, bool startRunning, CryMatchMakingTaskID* pMMTaskID, CryLobbyTaskID* pLTaskID, CryLobbySessionHandle h, void* pCB, void* pCBArg)
129 CryMatchMakingTaskID tmpMMTaskID;
130 CryMatchMakingTaskID* pUseMMTaskID = pMMTaskID ? pMMTaskID : &tmpMMTaskID;
131 ECryLobbyError error = CCryMatchMaking::StartTask(etask, startRunning, pUseMMTaskID, pLTaskID, h, pCB, pCBArg);
133 if (error == eCLE_Success)
135 ResetTask(*pUseMMTaskID);
138 return error;
141 void CCryDurangoLiveMatchMaking::ResetTask(CryMatchMakingTaskID mmTaskID)
145 void CCryDurangoLiveMatchMaking::StartSubTask(ETask etask, CryMatchMakingTaskID mmTaskID)
147 CCryMatchMaking::StartSubTask(etask, mmTaskID);
150 void CCryDurangoLiveMatchMaking::StartTaskRunning(CryMatchMakingTaskID mmTaskID)
152 LOBBY_AUTO_LOCK;
154 STask* pTask = &m_task[mmTaskID];
156 if (pTask->used)
158 #if ENABLE_CRYLOBBY_DEBUG_TESTS
159 ECryLobbyError error;
161 if (!m_lobby->DebugOKToStartTaskRunning(pTask->lTaskID))
163 return;
166 if (m_lobby->DebugGenerateError(pTask->lTaskID, error))
168 UpdateTaskError(mmTaskID, error);
169 StopTaskRunning(mmTaskID);
171 if ((pTask->startedTask == eT_SessionCreate) || (pTask->startedTask == eT_SessionJoin))
173 FreeSessionHandle(pTask->session);
176 return;
178 #endif
180 pTask->running = true;
182 switch (pTask->startedTask)
184 case eT_SessionRegisterUserData:
185 case eT_SessionMigrate:
186 StopTaskRunning(mmTaskID);
187 break;
189 case eT_SessionGetUsers:
190 StartSessionGetUsers(mmTaskID);
191 break;
193 case eT_SessionCreate:
194 StartSessionCreate(mmTaskID);
195 break;
197 case eT_SessionUpdate:
198 StartSessionUpdate(mmTaskID);
199 break;
201 case eT_SessionUpdateSlots:
202 StartSessionUpdateSlots(mmTaskID);
203 break;
205 case eT_SessionStart:
206 StartSessionStart(mmTaskID);
207 break;
209 case eT_SessionEnd:
210 StartSessionEnd(mmTaskID);
211 break;
213 case eT_SessionDelete:
214 StartSessionDelete(mmTaskID);
215 break;
217 case eT_SessionSearch:
218 StartSessionSearch(mmTaskID);
219 break;
221 case eT_SessionJoin:
222 StartSessionJoin(mmTaskID);
223 break;
225 #if NETWORK_HOST_MIGRATION
226 case eT_SessionMigrateHostStart:
227 HostMigrationStartNT(mmTaskID);
228 break;
230 case eT_SessionMigrateHostServer:
231 HostMigrationServerNT(mmTaskID);
232 break;
233 #endif
235 case eT_SessionSetLocalUserData:
236 StartSessionSetLocalUserData(mmTaskID);
237 break;
239 case eT_SessionQuery:
240 StartSessionQuery(mmTaskID);
241 break;
246 void CCryDurangoLiveMatchMaking::EndTask(CryMatchMakingTaskID mmTaskID)
248 LOBBY_AUTO_LOCK;
250 STask* pTask = &m_task[mmTaskID];
252 if (pTask->used)
254 #if NETWORK_HOST_MIGRATION
255 if (pTask->startedTask & HOST_MIGRATION_TASK_ID_FLAG)
257 m_sessions[pTask->session].hostMigrationInfo.m_taskID = CryLobbyInvalidTaskID;
259 #endif
261 if (pTask->cb)
263 switch (pTask->startedTask)
265 case eT_SessionRegisterUserData:
266 case eT_SessionUpdate:
267 case eT_SessionUpdateSlots:
268 case eT_SessionStart:
269 case eT_SessionEnd:
270 case eT_SessionSetLocalUserData:
271 case eT_SessionDelete:
272 #if NETWORK_HOST_MIGRATION
273 case eT_SessionMigrateHostStart:
274 #endif
275 ((CryMatchmakingCallback)pTask->cb)(pTask->lTaskID, pTask->error, pTask->cbArg);
276 break;
278 case eT_SessionGetUsers:
279 EndSessionGetUsers(mmTaskID);
280 break;
282 case eT_SessionMigrate: // From the games point of view a migrate is the same as a create
283 ((CryMatchmakingSessionCreateCallback)pTask->cb)(pTask->lTaskID, pTask->error, CreateGameSessionHandle(pTask->session, m_sessions[pTask->session].localConnection.uid), pTask->cbArg);
284 break;
286 case eT_SessionCreate:
287 EndSessionCreate(mmTaskID);
288 break;
290 case eT_SessionSearch:
291 EndSessionSearch(mmTaskID);
292 break;
294 case eT_SessionJoin:
295 EndSessionJoin(mmTaskID);
296 break;
298 case eT_SessionQuery:
299 EndSessionQuery(mmTaskID);
300 break;
304 if (pTask->error != eCLE_Success)
306 NetLog("[Lobby] EndTask %d (%d) error %d", pTask->startedTask, pTask->subTask, pTask->error);
309 // Clear LIVE specific task state so that base class tasks can use this slot
310 ResetTask(mmTaskID);
312 FreeTask(mmTaskID);
316 void CCryDurangoLiveMatchMaking::StopTaskRunning(CryMatchMakingTaskID mmTaskID)
318 STask* pTask = &m_task[mmTaskID];
320 if (pTask->used)
322 pTask->running = false;
323 TO_GAME_FROM_LOBBY(&CCryDurangoLiveMatchMaking::EndTask, this, mmTaskID);
327 ECryLobbyError CCryDurangoLiveMatchMaking::CreateSessionHandle(CryLobbySessionHandle* pH, bool host, uint32 createFlags, int numUsers)
329 ECryLobbyError error = CCryMatchMaking::CreateSessionHandle(pH, host, createFlags, numUsers);
331 if (error == eCLE_Success)
333 SSession* pSession = &m_sessions[*pH];
335 pSession->localConnection.name[0] = 0;
336 memset(pSession->localConnection.userData, 0, CRYLOBBY_USER_DATA_SIZE_IN_BYTES);
337 memset(&pSession->sessionID, 0, sizeof(pSession->sessionID));
339 if (!m_user)
341 return eCLE_UserNotSignedIn;
344 pSession->localConnection.xuid = m_user->Xuid();
345 pSession->localConnection.uid.m_uid = static_cast<uint16>(m_user->Xuid());
348 return error;
351 void CCryDurangoLiveMatchMaking::CreateSecureDeviceAssociationHandler(ISecureDeviceAssociation* pSecureDeviceAssociation, CryLobbySessionHandle h, CryMatchMakingConnectionID id)
353 SSession* pSession = &m_sessions[h];
354 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
356 pConnection->pSecureDeviceAssociation = pSecureDeviceAssociation;
357 if (!pConnection->pSecureDeviceAssociation)
359 return;
362 pConnection->state = SSession::SRConnection::eRCS_CreateAssociationSuccess;
364 SOCKADDR_STORAGE remoteSocketAddress;
365 pConnection->pSecureDeviceAssociation->GetRemoteSocketAddressBytes(sizeof(remoteSocketAddress), reinterpret_cast<BYTE*>(&remoteSocketAddress));
367 TNetAddress addr = TNetAddress(SSockAddrStorageAddr(remoteSocketAddress));
368 NetLog("[Lobby] Create Secure Device Association Handler from: " PRFORMAT_ADDR, PRARG_ADDR(addr));
370 CryLobbyConnectionID connectionID = m_lobby->FindConnection(addr);
372 if (connectionID == CryLobbyInvalidConnectionID)
374 connectionID = m_lobby->CreateConnection(addr);
377 if (connectionID != CryLobbyInvalidConnectionID)
379 m_lobby->ConnectionAddRef(connectionID);
381 pConnection->connectionID = connectionID;
385 void CCryDurangoLiveMatchMaking::StartCreateSecureDeviceAssociation(CryLobbySessionHandle h, CryMatchMakingConnectionID id)
387 SSession* pSession = &m_sessions[h];
388 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
390 ComPtr<IAsyncOperation<SecureDeviceAssociation*>> pCreateAssociationOperation;
391 if (!m_pSecureDeviceAssociationTemplate)
393 pConnection->state = SSession::SRConnection::eRCS_CreateAssociationFailed;
394 return;
397 NetLog("[Lobby] StartCreateSecureDeviceAssociation creating association");
398 m_pSecureDeviceAssociationTemplate->CreateAssociationAsync(pSession->remoteConnection[id].pSecureDeviceAddress.Get(), CreateSecureDeviceAssociationBehavior_Default, &pCreateAssociationOperation);
400 pConnection->state = SSession::SRConnection::eRCS_CreatingAssociation;
402 enum
404 Result = 0,
405 Association
408 ABI::Concurrency::task_from_async(pCreateAssociationOperation.Get()).then(
409 [this, h, id](std::tuple<HRESULT, ComPtr<ISecureDeviceAssociation>> res)
411 SSession* pSession = &m_sessions[h];
412 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
413 NetLog("[Lobby] StartCreateSecureDeviceAssociation create association result 0x%08x", std::get<Result>(res));
415 if (FAILED(std::get<Result>(res)))
417 pConnection->state = SSession::SRConnection::eRCS_CreateAssociationFailed;
418 return;
420 CreateSecureDeviceAssociationHandler(std::get<Association>(res).Get(), h, id);
424 CryMatchMakingConnectionID CCryDurangoLiveMatchMaking::AddRemoteConnection(CryLobbySessionHandle h, ISecureDeviceAddress* pSecureDeviceAddress, ISecureDeviceAssociation* pSecureDeviceAssociation, Live::Xuid xuid)
426 SSession* pSession = &m_sessions[h];
428 SCryMatchMakingConnectionUID remoteUID;
430 remoteUID.m_sid = GetSIDFromSessionHandle(h);
431 remoteUID.m_uid = static_cast<uint16>(xuid);
434 CryMatchMakingConnectionID id = CCryMatchMaking::AddRemoteConnection(h, CryLobbyInvalidConnectionID, remoteUID, 1);
436 if (id != CryMatchMakingInvalidConnectionID)
438 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
440 pConnection->flags |= CMMRC_FLAG_PLATFORM_DATA_VALID;
441 pConnection->xuid = xuid;
443 if (pSecureDeviceAssociation)
445 SOCKADDR_STORAGE remoteSocketAddress;
447 pConnection->state = SSession::SRConnection::eRCS_CreateAssociationSuccess;
448 pSecureDeviceAssociation->get_RemoteSecureDeviceAddress(&pConnection->pSecureDeviceAddress);
449 pConnection->pSecureDeviceAssociation = pSecureDeviceAssociation;
450 pConnection->pSecureDeviceAssociation->GetRemoteSocketAddressBytes(sizeof(remoteSocketAddress), reinterpret_cast<BYTE*>(&remoteSocketAddress));
452 TNetAddress addr = TNetAddress(SSockAddrStorageAddr(remoteSocketAddress));
453 NetLog("[Lobby] Adding Remote connection address: " PRFORMAT_ADDR, PRARG_ADDR(addr));
455 CryLobbyConnectionID connectionID = m_lobby->FindConnection(addr);
457 if (connectionID == CryLobbyInvalidConnectionID)
459 connectionID = m_lobby->CreateConnection(addr);
462 if (connectionID != CryLobbyInvalidConnectionID)
464 m_lobby->ConnectionAddRef(connectionID);
466 pConnection->connectionID = connectionID;
468 return id;
471 else
473 if (pSecureDeviceAddress)
475 pConnection->pSecureDeviceAddress = pSecureDeviceAddress;
477 return id;
482 if (id != CryMatchMakingInvalidConnectionID)
484 FreeRemoteConnection(h, id);
487 return CryMatchMakingInvalidConnectionID;
490 void CCryDurangoLiveMatchMaking::FreeRemoteConnection(CryLobbySessionHandle h, CryMatchMakingConnectionID id)
492 if (id != CryMatchMakingInvalidConnectionID)
494 SSession* pSession = &m_sessions[h];
495 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
497 if (pConnection->used)
499 SessionUserDataEvent(eCLSE_SessionUserLeave, h, id);
501 if (pConnection->pSecureDeviceAssociation)
503 ComPtr<IAsyncAction> action;
504 pConnection->pSecureDeviceAssociation->DestroyAsync(&action);
507 pConnection->pSecureDeviceAddress = nullptr;
508 pConnection->pSecureDeviceAssociation = nullptr;
510 pConnection->xuid = 0;
511 pConnection->name[0] = 0;
513 CCryMatchMaking::FreeRemoteConnection(h, id);
518 concurrency::task<HRESULT> CCryDurangoLiveMatchMaking::FreeRemoteConnectionAsync(CryLobbySessionHandle h, CryMatchMakingConnectionID id)
520 if (id == CryMatchMakingInvalidConnectionID)
521 return concurrency::create_task([](){ return S_OK; });
523 SSession* pSession = &m_sessions[h];
524 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
526 if (!pConnection->used)
527 return concurrency::create_task([](){ return S_OK; });
529 // XXX - ATG
530 GetChatIntegrationLayer()->RemoveRemoteConnection(h, id, pConnection->uid.m_uid);
532 SessionUserDataEvent(eCLSE_SessionUserLeave, h, id);
534 ComPtr<IAsyncAction> action;
535 if (pConnection->pSecureDeviceAssociation)
537 pConnection->pSecureDeviceAssociation->DestroyAsync(&action);
540 pConnection->pSecureDeviceAddress = nullptr;
541 pConnection->pSecureDeviceAssociation = nullptr;
543 pConnection->xuid = 0;
544 pConnection->name[0] = 0;
546 CCryMatchMaking::FreeRemoteConnection(h, id);
547 if (action.Get())
549 return ABI::Concurrency::task_from_async(action);
552 return concurrency::create_task([](){ return S_OK; });
555 uint64 CCryDurangoLiveMatchMaking::GetSIDFromSessionHandle(CryLobbySessionHandle h)
558 CRY_ASSERT_MESSAGE((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED), "CCryDurangoLiveMatchMaking::GetSIDFromSessionHandle: invalid session handle");
560 uint64 temp;
562 memcpy(&temp, &m_sessions[h].sessionID.Data4, sizeof(temp));
564 return temp;
568 void CCryDurangoLiveMatchMaking::Tick(CTimeValue tv)
570 CCryMatchMaking::Tick(tv);
572 for (uint32 i = 0; i < MAX_MATCHMAKING_TASKS; ++i)
574 STask* pTask = &m_task[i];
576 #if ENABLE_CRYLOBBY_DEBUG_TESTS
577 if (pTask->used)
579 if (m_lobby->DebugTickCallStartTaskRunning(pTask->lTaskID))
581 StartTaskRunning(i);
582 continue;
584 if (!m_lobby->DebugOKToTickTask(pTask->lTaskID, pTask->running))
586 continue;
589 #endif
591 if (pTask->used)
593 if (pTask->running)
595 switch (pTask->subTask)
597 case eT_SessionCreate:
598 TickSessionCreate(i);
599 break;
601 case eT_SessionUpdate:
602 TickSessionUpdate(i);
603 break;
605 case eT_SessionUpdateSlots:
606 TickSessionUpdateSlots(i);
607 break;
609 case eT_SessionStart:
610 TickSessionStart(i);
611 break;
613 case eT_SessionEnd:
614 TickSessionEnd(i);
615 break;
617 case eT_SessionDelete:
618 TickSessionDelete(i);
619 break;
621 case eT_SessionSearch:
622 TickSessionSearch(i);
623 break;
625 case eT_SessionJoin:
626 TickSessionJoin(i);
627 break;
629 case eT_SessionJoinCreateAssociation:
630 TickSessionJoinCreateAssociation(i);
631 break;
633 case eT_SessionRequestJoin:
634 TickSessionRequestJoin(i);
635 break;
637 #if NETWORK_HOST_MIGRATION
638 case eT_SessionMigrateHostStart:
639 TickHostMigrationStartNT(i);
640 break;
642 case eT_SessionMigrateHostServer:
643 TickHostMigrationServerNT(i);
644 break;
645 #endif
646 default:
647 TickBaseTask(i);
648 break;
654 for (uint32 i = 0; i < MAX_MATCHMAKING_SESSIONS; i++)
656 SSession* session = &m_sessions[i];
658 if (session->localFlags & CRYSESSION_LOCAL_FLAG_USED)
660 // Check what Live thinks the status of our connections is
661 for (uint32 j = 0; j < MAX_LOBBY_CONNECTIONS; j++)
663 SSession::SRConnection* pConnection = &session->remoteConnection[j];
665 if (pConnection->used)
667 if (m_lobby->ConnectionGetState(pConnection->connectionID) != eCLCS_NotConnected)
669 SecureDeviceAssociationState state = SecureDeviceAssociationState_Invalid;
670 pConnection->pSecureDeviceAssociation->get_State(&state);
671 if ((state == SecureDeviceAssociationState_DestroyingLocal) ||
672 (state == SecureDeviceAssociationState_DestroyingRemote) ||
673 (state == SecureDeviceAssociationState_Destroyed))
675 m_lobby->ConnectionSetState(pConnection->connectionID, eCLCS_NotConnected);
683 if (CLobbyCVars::Get().p2pShowConnectionStatus)
685 LogConnectionStatus();
689 void CCryDurangoLiveMatchMaking::LogConnectionStatus()
691 static float white[] = { 1.0f, 1.0f, 1.0f, 1.0f };
692 float xpos = 50;
693 CryFixedStringT<128> buffer;
695 for (uint32 sessionIndex = 0; sessionIndex < MAX_MATCHMAKING_SESSIONS; ++sessionIndex)
697 SSession* pSession = &m_sessions[sessionIndex];
698 float ypos = 50;
700 if (pSession->localFlags & CRYSESSION_LOCAL_FLAG_USED)
702 for (uint32 connectionIndex = 0; connectionIndex < MAX_LOBBY_CONNECTIONS; connectionIndex++)
704 SSession::SRConnection* pConnection = &pSession->remoteConnection[connectionIndex];
706 if (pConnection->used)
708 SecureDeviceAssociationState state = SecureDeviceAssociationState_Invalid;
709 pConnection->pSecureDeviceAssociation->get_State(&state);
710 switch (state)
712 case SecureDeviceAssociationState_Invalid:
713 buffer.Format(PRFORMAT_UID " : Invalid", PRARG_UID(pConnection->uid));
714 break;
716 case SecureDeviceAssociationState_CreatingOutbound:
717 buffer.Format(PRFORMAT_UID " : CreatingOutbound", PRARG_UID(pConnection->uid));
718 break;
720 case SecureDeviceAssociationState_CreatingInbound:
721 buffer.Format(PRFORMAT_UID " : CreatingInbound", PRARG_UID(pConnection->uid));
722 break;
724 case SecureDeviceAssociationState_Ready:
725 buffer.Format(PRFORMAT_UID " : Ready", PRARG_UID(pConnection->uid));
726 break;
728 case SecureDeviceAssociationState_DestroyingLocal:
729 buffer.Format(PRFORMAT_UID " : DestroyingLocal", PRARG_UID(pConnection->uid));
730 break;
732 case SecureDeviceAssociationState_DestroyingRemote:
733 buffer.Format(PRFORMAT_UID " : DestroyingRemote", PRARG_UID(pConnection->uid));
734 break;
736 case SecureDeviceAssociationState_Destroyed:
737 buffer.Format(PRFORMAT_UID " : Destroyed", PRARG_UID(pConnection->uid));
738 break;
741 if (gEnv->pRenderer)
743 gEnv->pRenderer->Draw2dLabel(xpos, ypos, 1.25f, white, false, buffer.c_str());
746 ypos += 20.0f;
751 xpos += 250.0f;
755 ECryLobbyError CCryDurangoLiveMatchMaking::Initialise()
757 ECryLobbyError error = CCryMatchMaking::Initialise();
759 if (error == eCLE_Success)
761 m_registeredUserData.num = 0;
763 HRESULT hr = Interface::Statics<ISecureDeviceAssociationTemplate>()->GetTemplateByName(Microsoft::WRL::Wrappers::HStringReference(L"PeerTraffic").Get(), &m_pSecureDeviceAssociationTemplate);
765 // XXX - ATG
766 error = GetChatIntegrationLayer()->Initialize(true, this);
769 return error;
772 ECryLobbyError CCryDurangoLiveMatchMaking::Terminate()
774 // XXX - ATG
775 ShutdownChatIntegrationLayer();
777 ECryLobbyError error = CCryMatchMaking::Terminate();
779 return error;
782 ECryLobbyError CCryDurangoLiveMatchMaking::SetINetworkingUser(Live::State::INetworkingUser* user)
784 m_user = user;
786 if (user == nullptr)
788 return eCLE_InvalidParam;
791 return eCLE_Success;
794 ECryLobbyError CCryDurangoLiveMatchMaking::SessionRegisterUserData(SCrySessionUserData* pData, uint32 numData, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
796 ECryLobbyError error = eCLE_Success;
798 LOBBY_AUTO_LOCK;
800 if (numData < MAX_MATCHMAKING_SESSION_USER_DATA)
802 CryMatchMakingTaskID mmTaskID;
804 error = StartTask(eT_SessionRegisterUserData, false, &mmTaskID, pTaskID, CryLobbyInvalidSessionHandle, pCB, pCBArg);
806 if (error == eCLE_Success)
808 memcpy(m_registeredUserData.data, pData, numData * sizeof(pData[0]));
809 m_registeredUserData.num = numData;
811 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
814 else
816 error = eCLE_OutOfSessionUserData;
819 NetLog("[Lobby] Start SessionRegisterUserData error %d", error);
821 return error;
824 ECryLobbyError CCryDurangoLiveMatchMaking::SessionMigrate(CrySessionHandle gh, uint32* pUsers, int numUsers, uint32 flags, SCrySessionData* pData, CryLobbyTaskID* pTaskID, CryMatchmakingSessionCreateCallback pCB, void* pCBArg)
826 ECryLobbyError error = eCLE_Success;
828 LOBBY_AUTO_LOCK;
830 // Because we simply want to re-use the session that is already available, we don't need to do much here
832 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
834 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
836 SSession* pSession = &m_sessions[h];
837 CryMatchMakingTaskID mmTaskID;
839 error = StartTask(eT_SessionMigrate, false, &mmTaskID, pTaskID, h, (void*)pCB, pCBArg);
841 if (error == eCLE_Success)
843 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
846 else
848 error = eCLE_InvalidSession;
851 NetLog("[Lobby] Start SessionMigrate error %d", error);
853 return error;
856 ECryLobbyError CCryDurangoLiveMatchMaking::SessionQuery(CrySessionHandle gh, CryLobbyTaskID* pTaskID, CryMatchmakingSessionQueryCallback pCB, void* pCBArg)
858 LOBBY_AUTO_LOCK;
860 ECryLobbyError error = eCLE_Success;
862 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
864 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
866 SSession* pSession = &m_sessions[h];
867 CryMatchMakingTaskID mmTaskID;
869 error = StartTask(eT_SessionQuery, false, &mmTaskID, pTaskID, h, (void*)pCB, pCBArg);
871 if (error == eCLE_Success)
873 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
876 else
878 error = eCLE_InvalidSession;
881 NetLog("[Lobby] Start SessionQuery error %d", error);
883 return error;
886 void CCryDurangoLiveMatchMaking::StartSessionQuery(CryMatchMakingTaskID mmTaskID)
888 StopTaskRunning(mmTaskID);
891 void CCryDurangoLiveMatchMaking::EndSessionQuery(CryMatchMakingTaskID mmTaskID)
893 STask* pTask = &m_task[mmTaskID];
895 ((CryMatchmakingSessionQueryCallback)pTask->cb)(pTask->lTaskID, pTask->error, NULL, pTask->cbArg);
898 ECryLobbyError CCryDurangoLiveMatchMaking::SessionGetUsers(CrySessionHandle gh, CryLobbyTaskID* pTaskID, CryMatchmakingSessionGetUsersCallback pCB, void* pCBArg)
900 ECryLobbyError error = eCLE_Success;
902 LOBBY_AUTO_LOCK;
904 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
906 if ((h < MAX_MATCHMAKING_SESSIONS) && m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED)
908 SSession* pSession = &m_sessions[h];
909 CryMatchMakingTaskID tid;
911 error = StartTask(eT_SessionGetUsers, false, &tid, pTaskID, h, pCB, pCBArg);
913 if (error == eCLE_Success)
915 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, tid);
918 else
920 error = eCLE_InvalidSession;
923 if (error != eCLE_Success)
925 NetLog("[Lobby] Start SessionGetUsers error %d", error);
928 return error;
931 void CCryDurangoLiveMatchMaking::StartSessionGetUsers(CryMatchMakingTaskID mmTaskID)
935 void CCryDurangoLiveMatchMaking::EndSessionGetUsers(CryMatchMakingTaskID mmTaskID)
937 STask* pTask = &m_task[mmTaskID];
939 if (pTask->error == eCLE_Success)
941 SCryUserInfoResult temp;
942 int a;
944 // Glue in local user
945 SCryDurangoLiveUserID* pID = new SCryDurangoLiveUserID(m_sessions[pTask->session].localConnection.xuid);
947 if (pID)
949 temp.m_userID = pID;
950 temp.m_conID = m_sessions[pTask->session].localConnection.uid;
951 temp.m_isDedicated = false; // Live does not support dedicated servers
952 cry_strcpy(temp.m_userName, m_sessions[pTask->session].localConnection.name);
953 memcpy(temp.m_userData, m_sessions[pTask->session].localConnection.userData, CRYLOBBY_USER_DATA_SIZE_IN_BYTES);
954 ((CryMatchmakingSessionGetUsersCallback)pTask->cb)(pTask->lTaskID, eCLE_SuccessContinue, &temp, pTask->cbArg);
956 else
958 UpdateTaskError(mmTaskID, eCLE_OutOfMemory);
961 for (a = 0; (a < MAX_LOBBY_CONNECTIONS) && (pTask->error == eCLE_Success); a++)
963 if (m_sessions[pTask->session].remoteConnection[a].used)
965 pID = new SCryDurangoLiveUserID(m_sessions[pTask->session].remoteConnection[a].xuid);
967 if (pID)
969 temp.m_userID = pID;
970 temp.m_conID = m_sessions[pTask->session].remoteConnection[a].uid;
971 cry_strcpy(temp.m_userName, m_sessions[pTask->session].remoteConnection[a].name);
972 memcpy(temp.m_userData, m_sessions[pTask->session].remoteConnection[a].userData, CRYLOBBY_USER_DATA_SIZE_IN_BYTES);
973 ((CryMatchmakingSessionGetUsersCallback)pTask->cb)(pTask->lTaskID, eCLE_SuccessContinue, &temp, pTask->cbArg);
975 else
977 UpdateTaskError(mmTaskID, eCLE_OutOfMemory);
983 ((CryMatchmakingSessionGetUsersCallback)pTask->cb)(pTask->lTaskID, pTask->error, NULL, pTask->cbArg);
986 ECryLobbyError CCryDurangoLiveMatchMaking::SessionSetLocalUserData(CrySessionHandle gh, CryLobbyTaskID* pTaskID, uint32 user, uint8* pData, uint32 dataSize, CryMatchmakingCallback pCB, void* pCBArg)
988 ECryLobbyError error = eCLE_Success;
990 LOBBY_AUTO_LOCK;
992 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
994 if ((h < MAX_MATCHMAKING_SESSIONS) && m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED)
996 if (dataSize <= CRYLOBBY_USER_DATA_SIZE_IN_BYTES)
998 SSession* pSession = &m_sessions[h];
999 SSession::SLConnection* pLConnection = &pSession->localConnection;
1000 CryMatchMakingTaskID mmTaskID;
1002 memcpy(pLConnection->userData, pData, dataSize);
1004 error = StartTask(eT_SessionSetLocalUserData, false, &mmTaskID, pTaskID, h, (void*)pCB, pCBArg);
1006 if (error == eCLE_Success)
1008 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1011 else
1013 error = eCLE_OutOfUserData;
1016 else
1018 error = eCLE_InvalidSession;
1021 return error;
1024 void CCryDurangoLiveMatchMaking::StartSessionSetLocalUserData(CryMatchMakingTaskID mmTaskID)
1026 StopTaskRunning(mmTaskID);
1029 ECryLobbyError CCryDurangoLiveMatchMaking::SessionCreate(uint32* pUsers, int numUsers, uint32 flags, SCrySessionData* pData, CryLobbyTaskID* pTaskID, CryMatchmakingSessionCreateCallback pCB, void* pCBArg)
1031 LOBBY_AUTO_LOCK;
1033 CryLobbySessionHandle h;
1034 ECryLobbyError error = CreateSessionHandle(&h, true, flags, numUsers);
1036 if (error == eCLE_Success)
1038 CryMatchMakingTaskID mmTaskID;
1040 error = StartTask(eT_SessionCreate, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1042 if (error == eCLE_Success)
1044 STask* pTask = &m_task[mmTaskID];
1046 error = CreateTaskParamMem(mmTaskID, TDM_SESSION_CREATE_SESSION_DATA, pData, sizeof(SCrySessionData));
1048 if (error == eCLE_Success)
1050 error = CreateTaskParamMem(mmTaskID, TDM_SESSION_CREATE_USERDATA, pData->m_data, pData->m_numData * sizeof(pData->m_data[0]));
1052 if (error == eCLE_Success)
1054 pTask->numParams[TDN_SESSION_CREATE_NUMUSERDATA] = pData->m_numData;
1055 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1059 if (error != eCLE_Success)
1061 FreeTask(mmTaskID);
1062 FreeSessionHandle(h);
1065 else
1067 FreeSessionHandle(h);
1071 NetLog("[Lobby] Start SessionCreate error %d", error);
1073 return error;
1076 // ~^~^~TODO: We should set up the Incoming SDA listener here.
1077 void CCryDurangoLiveMatchMaking::StartSessionCreate(CryMatchMakingTaskID mmTaskID)
1081 void CCryDurangoLiveMatchMaking::TickSessionCreate(CryMatchMakingTaskID mmTaskID)
1083 using namespace ABI::Microsoft::Xbox::Services::Matchmaking;
1084 STask* pTask = &m_task[mmTaskID];
1086 // If we don't have an async running... {
1087 // If we have not looked in 5 seconds:
1088 if (m_user)
1090 Live::Xuid xuids;
1091 HRESULT hr = m_user->GetRemoteXuids(1, &xuids, nullptr);
1093 SSession* pSession = &m_sessions[pTask->session];
1095 pSession->sessionID = m_user->GetSessionName();
1097 pSession->localConnection.uid.m_sid = GetSIDFromSessionHandle(pTask->session);
1098 pSession->localConnection.uid.m_uid = static_cast<uint16>(m_user->Xuid());
1100 if (m_AssociationIncoming.value == 0)
1102 m_pSecureDeviceAssociationTemplate->add_AssociationIncoming(Callback<ITypedEventHandler<SecureDeviceAssociationTemplate*, SecureDeviceAssociationIncomingEventArgs*>>(
1103 [](ISecureDeviceAssociationTemplate* sender, ISecureDeviceAssociationIncomingEventArgs* args) -> HRESULT
1105 UNREFERENCED_PARAMETER(sender);
1107 ComPtr<ISecureDeviceAssociation> SDAssoc;
1108 args->get_Association(&SDAssoc);
1110 SOCKADDR_STORAGE remoteSocketAddress;
1111 SDAssoc->GetRemoteSocketAddressBytes(sizeof(remoteSocketAddress), reinterpret_cast<BYTE*>(&remoteSocketAddress));
1112 TNetAddress addr = TNetAddress(SSockAddrStorageAddr(remoteSocketAddress));
1114 NetLog("[Lobby] Incoming Secure Device Association from: " PRFORMAT_ADDR, PRARG_ADDR(addr));
1116 return S_OK;
1117 }).Get(), &m_AssociationIncoming);
1120 StopTaskRunning(mmTaskID);
1124 void CCryDurangoLiveMatchMaking::EndSessionCreate(CryMatchMakingTaskID mmTaskID)
1126 STask* pTask = &m_task[mmTaskID];
1128 ((CryMatchmakingSessionCreateCallback)pTask->cb)(pTask->lTaskID, pTask->error, CreateGameSessionHandle(pTask->session, m_sessions[pTask->session].localConnection.uid), pTask->cbArg);
1130 if (pTask->error == eCLE_Success)
1132 InitialUserDataEvent(pTask->session);
1136 ECryLobbyError CCryDurangoLiveMatchMaking::SessionUpdate(CrySessionHandle gh, SCrySessionUserData* pData, uint32 numData, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
1138 ECryLobbyError error = eCLE_Success;
1140 LOBBY_AUTO_LOCK;
1142 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
1144 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
1146 SSession* pSession = &m_sessions[h];
1148 if (pSession->localFlags & CRYSESSION_LOCAL_FLAG_HOST)
1150 CryMatchMakingTaskID mmTaskID;
1152 error = StartTask(eT_SessionUpdate, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1154 if (error == eCLE_Success)
1156 STask* pTask = &m_task[mmTaskID];
1158 error = CreateTaskParamMem(mmTaskID, TDM_SESSION_UPDATE_USERDATA, pData, numData * sizeof(pData[0]));
1160 if (error == eCLE_Success)
1162 pTask->numParams[TDN_SESSION_UPDATE_NUMUSERDATA] = numData;
1163 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1165 else
1167 FreeTask(mmTaskID);
1171 else
1173 error = eCLE_InvalidRequest;
1176 else
1178 error = eCLE_InvalidSession;
1181 NetLog("[Lobby] Start SessionUpdate error %d", error);
1183 return error;
1186 void CCryDurangoLiveMatchMaking::StartSessionUpdate(CryMatchMakingTaskID mmTaskID)
1190 void CCryDurangoLiveMatchMaking::TickSessionUpdate(CryMatchMakingTaskID mmTaskID)
1192 StopTaskRunning(mmTaskID);
1195 ECryLobbyError CCryDurangoLiveMatchMaking::SessionUpdateSlots(CrySessionHandle gh, uint32 numPublic, uint32 numPrivate, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
1197 ECryLobbyError error = eCLE_Success;
1199 LOBBY_AUTO_LOCK;
1201 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
1203 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
1205 SSession* pSession = &m_sessions[h];
1206 CryMatchMakingTaskID mmTaskID;
1208 error = StartTask(eT_SessionUpdateSlots, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1210 if (error == eCLE_Success)
1212 STask* pTask = &m_task[mmTaskID];
1214 pTask->numParams[TDN_UPDATE_SLOTS_PUBLIC] = numPublic;
1215 pTask->numParams[TDN_UPDATE_SLOTS_PRIVATE] = numPrivate;
1217 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1220 else
1222 error = eCLE_InvalidSession;
1225 NetLog("[Lobby] Start SessionUpdateSlots return %d", error);
1227 return error;
1230 void CCryDurangoLiveMatchMaking::StartSessionUpdateSlots(CryMatchMakingTaskID mmTaskID)
1234 void CCryDurangoLiveMatchMaking::TickSessionUpdateSlots(CryMatchMakingTaskID mmTaskID)
1236 StopTaskRunning(mmTaskID);
1239 ECryLobbyError CCryDurangoLiveMatchMaking::SessionStart(CrySessionHandle gh, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
1241 ECryLobbyError error = eCLE_Success;
1243 LOBBY_AUTO_LOCK;
1245 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
1247 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
1249 SSession* pSession = &m_sessions[h];
1250 CryMatchMakingTaskID mmTaskID;
1252 error = StartTask(eT_SessionStart, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1254 if (error == eCLE_Success)
1256 pSession->localFlags |= CRYSESSION_LOCAL_FLAG_STARTED;
1257 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1260 else
1262 error = eCLE_InvalidSession;
1265 NetLog("[Lobby] Start SessionStart error %d", error);
1267 return error;
1270 void CCryDurangoLiveMatchMaking::StartSessionStart(CryMatchMakingTaskID mmTaskID)
1274 void CCryDurangoLiveMatchMaking::TickSessionStart(CryMatchMakingTaskID mmTaskID)
1276 StopTaskRunning(mmTaskID);
1279 ECryLobbyError CCryDurangoLiveMatchMaking::SessionEnd(CrySessionHandle gh, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
1281 ECryLobbyError error = eCLE_Success;
1283 LOBBY_AUTO_LOCK;
1285 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
1287 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
1289 SSession* pSession = &m_sessions[h];
1290 CryMatchMakingTaskID mmTaskID;
1292 error = StartTask(eT_SessionEnd, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1294 if (error == eCLE_Success)
1296 pSession->localFlags &= ~CRYSESSION_LOCAL_FLAG_STARTED;
1297 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1300 else
1302 error = eCLE_SuccessInvalidSession;
1305 NetLog("[Lobby] Start SessionEnd error %d", error);
1307 return error;
1310 void CCryDurangoLiveMatchMaking::StartSessionEnd(CryMatchMakingTaskID mmTaskID)
1314 void CCryDurangoLiveMatchMaking::TickSessionEnd(CryMatchMakingTaskID mmTaskID)
1316 StopTaskRunning(mmTaskID);
1319 ECryLobbyError CCryDurangoLiveMatchMaking::SessionDelete(CrySessionHandle gh, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
1321 ECryLobbyError error = eCLE_Success;
1323 LOBBY_AUTO_LOCK;
1325 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
1327 if ((h < MAX_MATCHMAKING_SESSIONS) && (m_sessions[h].localFlags & CRYSESSION_LOCAL_FLAG_USED))
1329 SSession* pSession = &m_sessions[h];
1330 CryMatchMakingTaskID mmTaskID;
1332 error = StartTask(eT_SessionDelete, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1334 if (error == eCLE_Success)
1336 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1339 else
1341 error = eCLE_SuccessInvalidSession;
1344 NetLog("[Lobby] Start SessionDelete error %d", error);
1346 return error;
1349 void CCryDurangoLiveMatchMaking::StartSessionDelete(CryMatchMakingTaskID mmTaskID)
1351 STask* pTask = &m_task[mmTaskID];
1352 SSession* pSession = &m_sessions[pTask->session];
1354 // Disconnect our local connection
1355 SessionDisconnectRemoteConnectionViaNub(pTask->session, CryMatchMakingInvalidConnectionID, eDS_Local, CryMatchMakingInvalidConnectionID, eDC_UserRequested, "Session deleted");
1356 SessionUserDataEvent(eCLSE_SessionUserLeave, pTask->session, CryMatchMakingInvalidConnectionID);
1358 auto tasks = std::make_shared<std::vector<concurrency::task<HRESULT>>>();
1360 // Free any remaining remote connections
1361 for (uint32 i = 0; i < MAX_LOBBY_CONNECTIONS; i++)
1363 SSession::SRConnection* pConnection = &pSession->remoteConnection[i];
1365 if (pConnection->used)
1367 tasks->emplace_back(FreeRemoteConnectionAsync(pTask->session, i));
1371 FreeSessionHandle(pTask->session);
1373 // XXX - ATG
1374 GetChatIntegrationLayer()->Reset();
1376 if (m_user)
1378 ComPtr<IAsyncAction> sessionDelete;
1379 HRESULT res = m_user->DeleteSessionAsync(&sessionDelete);
1380 if (SUCCEEDED(res))
1382 tasks->emplace_back(ABI::Concurrency::task_from_async(sessionDelete.Get()).then(
1383 [sessionDelete](HRESULT res)
1385 return res;
1386 }));
1390 m_pSecureDeviceAssociationTemplate->remove_AssociationIncoming(m_AssociationIncoming);
1391 m_AssociationIncoming.value = 0;
1393 StartConcurrencyTaskTask(mmTaskID, concurrency::when_all(tasks->begin(), tasks->end()).then(
1394 [tasks](std::vector<HRESULT> results)
1396 for (auto const& result : results)
1398 if (FAILED(result))
1399 return result;
1402 return S_OK;
1403 }));
1406 void CCryDurangoLiveMatchMaking::TickSessionDelete(CryMatchMakingTaskID mmTaskID)
1408 STask* pTask = &m_task[mmTaskID];
1409 SSession* pSession = &m_sessions[pTask->session];
1411 if (pTask->asyncTaskState != STask::eATS_Pending)
1413 StopTaskRunning(mmTaskID);
1417 ECryLobbyError CCryDurangoLiveMatchMaking::SessionSearch(uint32 user, SCrySessionSearchParam* pParam, CryLobbyTaskID* pTaskID, CryMatchmakingSessionSearchCallback pCB, void* pCBArg)
1419 LOBBY_AUTO_LOCK;
1421 CryMatchMakingTaskID mmTaskID;
1423 ECryLobbyError error = StartTask(eT_SessionSearch, false, &mmTaskID, pTaskID, CryLobbyInvalidSessionHandle, pCB, pCBArg);
1425 if (error == eCLE_Success)
1427 STask* pTask = &m_task[mmTaskID];
1429 error = CreateTaskParamMem(mmTaskID, TDM_SESSION_SEARCH_PARAM, pParam, sizeof(SCrySessionSearchParam));
1431 if (error == eCLE_Success)
1433 error = CreateTaskParamMem(mmTaskID, TDM_SESSION_SEARCH_PARAMDATA, pParam->m_data, pParam->m_numData * sizeof(pParam->m_data[0]));
1435 if (error == eCLE_Success)
1437 pTask->numParams[TDN_SESSION_SEARCH_PARAMNUMDATA] = pParam->m_numData;
1438 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1442 if (error != eCLE_Success)
1444 FreeTask(mmTaskID);
1448 NetLog("[Lobby] Start SessionSearch error %d", error);
1450 return error;
1453 void CCryDurangoLiveMatchMaking::StartSessionSearch(CryMatchMakingTaskID mmTaskID)
1455 StopTaskRunning(mmTaskID);
1458 void CCryDurangoLiveMatchMaking::TickSessionSearch(CryMatchMakingTaskID mmTaskID)
1460 StopTaskRunning(mmTaskID);
1463 void CCryDurangoLiveMatchMaking::EndSessionSearch(CryMatchMakingTaskID mmTaskID)
1465 STask* pTask = &m_task[mmTaskID];
1467 SCryDurangoLiveSessionID* id = nullptr;
1469 if (m_user)
1471 id = new SCryDurangoLiveSessionID(m_user->GetSessionName());
1475 if (id)
1477 SCrySessionSearchResult result;
1478 SCrySessionUserData userData[MAX_MATCHMAKING_SESSION_USER_DATA];
1480 result.m_id = id;
1482 result.m_numFilledSlots = 0;
1483 result.m_data.m_numPublicSlots = 0;
1484 result.m_data.m_numPrivateSlots = 0;
1485 cry_strcpy(result.m_data.m_name, "Test");
1486 result.m_data.m_ranked = false;
1488 result.m_data.m_data = userData;
1489 result.m_data.m_numData = m_registeredUserData.num;
1491 result.m_ping = 0;
1492 result.m_numFriends = 0;
1493 result.m_flags = 0;
1495 for (uint32 i = 0; i < m_registeredUserData.num; i++)
1497 result.m_data.m_data[i] = m_registeredUserData.data[i];
1500 if (pTask->cb)
1502 ((CryMatchmakingSessionSearchCallback)pTask->cb)(pTask->lTaskID, eCLE_SuccessContinue, &result, pTask->cbArg);
1506 // Need to check again as task is cancelled if result from previous call is automatically accepted,
1507 // in which case cb will be nulled out by the previous callback.
1508 if (pTask->cb)
1510 ((CryMatchmakingSessionSearchCallback)pTask->cb)(pTask->lTaskID, pTask->error, NULL, pTask->cbArg);
1514 ECryLobbyError CCryDurangoLiveMatchMaking::SessionJoin(uint32* pUsers, int numUsers, uint32 flags, CrySessionID id, CryLobbyTaskID* pTaskID, CryMatchmakingSessionJoinCallback pCB, void* pCBArg)
1516 LOBBY_AUTO_LOCK;
1518 CryLobbySessionHandle h;
1519 ECryLobbyError error = CreateSessionHandle(&h, false, flags, numUsers);
1521 if (error == eCLE_Success)
1523 CryMatchMakingTaskID mmTaskID;
1525 error = StartTask(eT_SessionJoin, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1527 if (error == eCLE_Success)
1529 SCryDurangoLiveSessionID* pDurangoLiveID = (SCryDurangoLiveSessionID*)id.get();
1530 SSession* pSession = &m_sessions[h];
1532 pSession->sessionID = pDurangoLiveID->m_sessionID;
1533 OLECHAR* bstrGuid;
1534 StringFromCLSID(pSession->sessionID, &bstrGuid);
1535 CryLogAlways("SessionJoin: SID: %s", bstrGuid);
1536 ::CoTaskMemFree(bstrGuid);
1538 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1540 else
1542 FreeSessionHandle(h);
1546 NetLog("[Lobby] Start SessionJoin error %d", error);
1548 return error;
1551 void CCryDurangoLiveMatchMaking::StartSessionJoin(CryMatchMakingTaskID mmTaskID)
1555 void CCryDurangoLiveMatchMaking::TickSessionJoin(CryMatchMakingTaskID mmTaskID)
1557 using namespace ABI::Microsoft::Xbox::Services::Matchmaking;
1558 STask* pTask = &m_task[mmTaskID];
1560 // If we don't have an async running... {
1561 // If we have not looked in 5 seconds:
1562 if (m_user)
1564 Live::Xuid xuids;
1565 HRESULT hr = m_user->GetHostXuid(xuids);
1567 unsigned int addresses = 1;
1568 ComPtr<ISecureDeviceAddress> sdaddr;
1569 hr = m_user->GetHostSecureDeviceAddress(&sdaddr, &addresses);
1571 SSession* pSession = &m_sessions[pTask->session];
1572 pSession->localConnection.uid.m_sid = GetSIDFromSessionHandle(pTask->session);
1574 CryMatchMakingConnectionID const remoteId =
1575 [&]()
1577 pSession->hostConnectionID = AddRemoteConnection(pTask->session, sdaddr.Get(), nullptr, xuids);
1578 return pSession->hostConnectionID;
1579 } ();
1581 if (remoteId != CryMatchMakingInvalidConnectionID)
1583 StartSubTask(eT_SessionJoinCreateAssociation, mmTaskID);
1584 StartCreateSecureDeviceAssociation(pTask->session, remoteId);
1586 else
1588 UpdateTaskError(mmTaskID, eCLE_ConnectionFailed);
1589 StopTaskRunning(mmTaskID);
1592 else
1594 UpdateTaskError(mmTaskID, eCLE_ConnectionFailed);
1595 StopTaskRunning(mmTaskID);
1599 void CCryDurangoLiveMatchMaking::TickSessionJoinCreateAssociation(CryMatchMakingTaskID mmTaskID)
1601 STask* pTask = &m_task[mmTaskID];
1602 SSession* pSession = &m_sessions[pTask->session];
1603 SSession::SRConnection* pConnection = &pSession->remoteConnection[pSession->hostConnectionID];
1605 if (pConnection->state == SSession::SRConnection::eRCS_CreateAssociationSuccess)
1607 StartSubTask(eT_SessionRequestJoin, mmTaskID);
1608 pTask->timerStarted = false;
1609 pTask->numParams[TDM_SESSION_JOIN_CONNECTION_COUNTER] = 0;
1612 if (pConnection->state == SSession::SRConnection::eRCS_CreateAssociationFailed)
1614 UpdateTaskError(mmTaskID, eCLE_ConnectionFailed);
1615 StopTaskRunning(mmTaskID);
1619 void CCryDurangoLiveMatchMaking::TickSessionRequestJoin(CryMatchMakingTaskID mmTaskID)
1621 STask* pTask = &m_task[mmTaskID];
1623 if (!pTask->TimerStarted() || (pTask->GetTimer() > CONNECTION_JOIN_SEND_INTERVAL))
1625 if (pTask->numParams[TDM_SESSION_JOIN_CONNECTION_COUNTER] < CONNECTION_JOIN_MAX_SEND_TIMES)
1627 SSession* pSession = &m_sessions[pTask->session];
1628 const uint32 MaxBufferSize = CryLobbyPacketHeaderSize + CryLobbyPacketUINT8Size + CryLobbyPacketUINT64Size;
1629 uint8 buffer[MaxBufferSize];
1630 CCryDurangoLiveLobbyPacket packet;
1632 pTask->StartTimer();
1633 pTask->numParams[TDM_SESSION_JOIN_CONNECTION_COUNTER]++;
1635 Live::Xuid xuid = m_user->Xuid();
1637 packet.SetWriteBuffer(buffer, MaxBufferSize);
1638 packet.StartWrite(eDurangoLivePT_SessionRequestJoin, false);
1639 packet.WriteUINT8(mmTaskID);
1640 packet.WriteUINT64(xuid);
1642 TNetAddress addr;
1643 m_lobby->AddressFromConnection(addr, pSession->remoteConnection[pSession->hostConnectionID].connectionID);
1644 NetLog("[Lobby] TickSessionRequestJoin sending to " PRFORMAT_ADDR, PRARG_ADDR(addr));
1646 if (Send(mmTaskID, &packet, pTask->session, pSession->hostConnectionID) != eSE_Ok)
1648 UpdateTaskError(mmTaskID, eCLE_ConnectionFailed);
1651 else
1653 UpdateTaskError(mmTaskID, eCLE_ConnectionFailed);
1654 StopTaskRunning(mmTaskID);
1659 void CCryDurangoLiveMatchMaking::EndSessionJoin(CryMatchMakingTaskID mmTaskID)
1661 STask* pTask = &m_task[mmTaskID];
1663 if (pTask->error == eCLE_Success)
1665 SSession* pSession = &m_sessions[pTask->session];
1667 ((CryMatchmakingSessionJoinCallback)pTask->cb)(pTask->lTaskID, pTask->error, CreateGameSessionHandle(pTask->session, pSession->localConnection.uid), 0, 0, pTask->cbArg);
1668 InitialUserDataEvent(pTask->session);
1670 return;
1673 ((CryMatchmakingSessionJoinCallback)pTask->cb)(pTask->lTaskID, pTask->error, CrySessionInvalidHandle, 0, 0, pTask->cbArg);
1676 void CCryDurangoLiveMatchMaking::ProcessSessionRequestJoin(const TNetAddress& addr, CCryDurangoLiveLobbyPacket* pPacket)
1678 NetLog("[Lobby] ProcessSessionRequestJoin from " PRFORMAT_ADDR, PRARG_ADDR(addr));
1680 CryMatchMakingTaskID returnTaskID;
1682 returnTaskID = pPacket->ReadUINT8();
1683 Live::Xuid xuid = pPacket->ReadUINT64();
1685 if (!m_user)
1686 return;
1688 SSockAddrStorageAddr const* pSockAddrStorageAddr = boost::get<SSockAddrStorageAddr>(&addr);
1689 if (!pSockAddrStorageAddr)
1690 return;
1692 IDatagramSocketPtr pSocket = m_lobby->GetInternalSocket(m_serviceType);
1693 if (!pSocket)
1694 return;
1696 ComPtr<ISecureDeviceAssociation> pSecureDeviceAssociation;
1698 sockaddr_storage localAddr;
1699 int localAddrLen = sizeof(localAddr);
1701 if (getsockname(pSocket->GetSysSocket(), (CRYSOCKADDR*)&localAddr, &localAddrLen) == 0)
1703 HRESULT hr = Interface::Statics<ISecureDeviceAssociationStatics>()->GetAssociationBySocketAddressBytes(
1704 sizeof(pSockAddrStorageAddr->addr),
1705 reinterpret_cast<uint8*>(&const_cast<SSockAddrStorageAddr*>(pSockAddrStorageAddr)->addr),
1706 localAddrLen,
1707 reinterpret_cast<uint8*>(&localAddr),
1708 &pSecureDeviceAssociation);
1709 CryLogAlways("CCryDurangoLiveMatchMaking::ProcessSessionRequestJoin - GetAssociationBySocketAddressBytes returned 0x%08x", hr);
1713 if (!pSecureDeviceAssociation)
1714 return;
1716 CryLobbySessionHandle h = FindSessionFromID(m_user->GetSessionName());
1717 if (h == CryLobbyInvalidSessionHandle)
1718 return;
1720 //Live::Xuid xuid;
1721 //m_user->GetRemoteXuids(1, &xuid, nullptr);
1723 SSession* pSession = &m_sessions[h];
1724 CryMatchMakingConnectionID id = AddRemoteConnection(h, nullptr, pSecureDeviceAssociation.Get(), xuid);
1726 if (id == CryMatchMakingInvalidConnectionID)
1727 return;
1729 SSession::SLConnection* pLocalConnection = &pSession->localConnection;
1730 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
1731 const uint32 MaxBufferSize = CryLobbyPacketHeaderSize + CryLobbyPacketUINT8Size + CryLobbyPacketErrorSize + CryLobbyPacketConnectionUIDSize + CryLobbyPacketConnectionUIDSize;
1732 uint8 buffer[MaxBufferSize];
1733 CCryDurangoLiveLobbyPacket packet;
1735 packet.SetWriteBuffer(buffer, MaxBufferSize);
1736 packet.StartWrite(eDurangoLivePT_SessionRequestJoinResult, true);
1737 packet.WriteUINT8(returnTaskID);
1738 packet.WriteError(eCLE_Success);
1740 // Add clients connection info.
1741 packet.WriteConnectionUID(pConnection->uid);
1743 // Add servers connection info.
1744 packet.WriteConnectionUID(pLocalConnection->uid);
1746 Send(CryMatchMakingInvalidTaskID, &packet, h, id);
1748 ConnectionEstablishedUserDataEvent(h, id);
1750 return;
1753 void CCryDurangoLiveMatchMaking::ProcessSessionRequestJoinResult(const TNetAddress& addr, CCryDurangoLiveLobbyPacket* pPacket)
1755 CryMatchMakingTaskID mmTaskID = pPacket->ReadUINT8();
1757 mmTaskID = FindTaskFromTaskTaskID(eT_SessionRequestJoin, mmTaskID);
1759 if (mmTaskID != CryMatchMakingInvalidTaskID)
1761 STask* pTask = &m_task[mmTaskID];
1762 ECryLobbyError error = pPacket->ReadError();
1764 UpdateTaskError(mmTaskID, error);
1765 StopTaskRunning(mmTaskID);
1769 uint32 CCryDurangoLiveMatchMaking::GetSessionIDSizeInPacket() const
1771 return 0;
1774 ECryLobbyError CCryDurangoLiveMatchMaking::WriteSessionIDToPacket(CrySessionID sessionId, CCryLobbyPacket* pPacket) const
1776 return eCLE_Success;
1779 CrySessionID CCryDurangoLiveMatchMaking::ReadSessionIDFromPacket(CCryLobbyPacket* pPacket) const
1781 return CrySessionInvalidID;
1784 CrySessionID CCryDurangoLiveMatchMaking::SessionGetCrySessionIDFromCrySessionHandle(CrySessionHandle gh)
1786 return CrySessionInvalidID;
1789 void CCryDurangoLiveMatchMaking::OnPacket(const TNetAddress& addr, CCryLobbyPacket* pPacket)
1791 CCryDurangoLiveLobbyPacket* pDLPacket = (CCryDurangoLiveLobbyPacket*)pPacket;
1793 switch (pDLPacket->StartRead())
1795 case eDurangoLivePT_SessionRequestJoin:
1796 ProcessSessionRequestJoin(addr, pDLPacket);
1797 break;
1799 case eDurangoLivePT_SessionRequestJoinResult:
1800 ProcessSessionRequestJoinResult(addr, pDLPacket);
1801 break;
1803 // XXX - ATG
1804 case eDurangoLivePT_Chat:
1805 GetChatIntegrationLayer()->ReceivePacket(pDLPacket);
1806 break;
1808 default:
1809 CCryMatchMaking::OnPacket(addr, pDLPacket);
1810 break;
1814 #if NETWORK_HOST_MIGRATION
1815 void CCryDurangoLiveMatchMaking::HostMigrationInitialise(CryLobbySessionHandle h, EDisconnectionCause cause)
1817 SSession* pSession = &m_sessions[h];
1819 pSession->hostMigrationInfo.Reset();
1822 void CCryDurangoLiveMatchMaking::HostMigrationFinalise(CryLobbySessionHandle h)
1824 SSession* pSession = &m_sessions[h];
1826 HostMigrationReset(h);
1828 if ((pSession->localFlags & CRYSESSION_LOCAL_FLAG_HOST) == 0)
1830 MarkHostHintInformationDirty(h);
1834 ECryLobbyError CCryDurangoLiveMatchMaking::HostMigrationServer(SHostMigrationInfo* pInfo)
1836 ECryLobbyError error = eCLE_Success;
1838 LOBBY_AUTO_LOCK;
1840 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(pInfo->m_session);
1842 if (h != CryLobbyInvalidSessionHandle)
1844 SSession* pSession = &m_sessions[h];
1846 if (pSession->localFlags & CRYSESSION_LOCAL_FLAG_USED)
1848 CryMatchMakingTaskID mmTaskID;
1850 pSession->localFlags |= CRYSESSION_LOCAL_FLAG_HOST;
1851 pSession->hostConnectionID = CryMatchMakingInvalidConnectionID;
1852 error = StartTask(eT_SessionMigrateHostServer, false, &mmTaskID, NULL, h, NULL, NULL);
1854 if (error == eCLE_Success)
1856 STask* pTask = &m_task[mmTaskID];
1857 #if HOST_MIGRATION_SOAK_TEST_BREAK_DETECTION
1858 DetectHostMigrationTaskBreak(h, "HostMigrationServer()");
1859 #endif
1860 pSession->hostMigrationInfo.m_taskID = pTask->lTaskID;
1862 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1865 else
1867 error = eCLE_InvalidSession;
1870 else
1872 error = eCLE_InvalidSession;
1875 if (error != eCLE_Success)
1877 m_hostMigration.Terminate((SHostMigrationInfo_Private*)pInfo);
1878 NetLog("[Host Migration]: CCryLiveMatchMaking::HostMigrationServer(): " PRFORMAT_SH ", error %d", PRARG_SH(h), error);
1881 return error;
1884 void CCryDurangoLiveMatchMaking::HostMigrationServerNT(CryMatchMakingTaskID mmTaskID)
1888 void CCryDurangoLiveMatchMaking::TickHostMigrationServerNT(CryMatchMakingTaskID mmTaskID)
1890 STask* pTask = &m_task[mmTaskID];
1891 SSession* pSession = &m_sessions[pTask->session];
1893 pSession->hostMigrationInfo.m_matchMakingFinished = true;
1894 StopTaskRunning(mmTaskID);
1897 bool CCryDurangoLiveMatchMaking::GetNewHostAddress(char* pAddress, SHostMigrationInfo* pInfo)
1899 return false;
1902 void CCryDurangoLiveMatchMaking::HostMigrationStartNT(CryMatchMakingTaskID mmTaskID)
1906 void CCryDurangoLiveMatchMaking::TickHostMigrationStartNT(CryMatchMakingTaskID mmTaskID)
1908 StopTaskRunning(mmTaskID);
1910 #endif
1912 ECryLobbyError CCryDurangoLiveMatchMaking::SessionEnsureBestHost(CrySessionHandle gh, CryLobbyTaskID* pTaskID, CryMatchmakingCallback pCB, void* pCBArg)
1914 ECryLobbyError rc = eCLE_Success;
1916 #if NETWORK_HOST_MIGRATION
1917 LOBBY_AUTO_LOCK;
1919 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
1921 if (h != CryLobbyInvalidSessionHandle)
1923 CryMatchMakingTaskID mmTaskID;
1924 SSession* pSession = &m_sessions[h];
1925 rc = StartTask(eT_SessionMigrateHostStart, false, &mmTaskID, pTaskID, h, pCB, pCBArg);
1927 if (rc == eCLE_Success)
1929 FROM_GAME_TO_LOBBY(&CCryDurangoLiveMatchMaking::StartTaskRunning, this, mmTaskID);
1932 #endif
1934 return rc;
1937 void CCryDurangoLiveMatchMaking::SessionUserDataEvent(ECryLobbySystemEvent event, CryLobbySessionHandle h, CryMatchMakingConnectionID id)
1939 SSession* pSession = &m_sessions[h];
1941 if (pSession->localFlags & CRYSESSION_LOCAL_FLAG_USER_DATA_EVENTS_STARTED)
1943 ComPtr<IUser> pUser;
1944 ISystem* pSystem = GetISystem();
1946 if (pSystem)
1948 int userIndex = pSystem->GetPlatformOS()->GetFirstSignedInUser();
1949 if (userIndex != IPlatformOS::Unknown_User)
1951 int userId = pSystem->GetPlatformOS()->UserGetId(userIndex);
1952 Interface::Statics<IUser>()->GetUserById(userId, &pUser);
1956 if (id == CryMatchMakingInvalidConnectionID)
1958 SSession::SLConnection* pConnection = &pSession->localConnection;
1959 SCryDurangoLiveUserID* pID = new SCryDurangoLiveUserID(pConnection->xuid);
1961 if (pID)
1963 SCryUserInfoResult userInfo;
1965 userInfo.m_conID = pConnection->uid;
1966 userInfo.m_isDedicated = false; // Live does not support dedicated servers
1967 userInfo.m_userID = pID;
1968 cry_strcpy(userInfo.m_userName, pConnection->name);
1969 memcpy(userInfo.m_userData, pConnection->userData, CRYLOBBY_USER_DATA_SIZE_IN_BYTES);
1971 CCryMatchMaking::SessionUserDataEvent(event, h, &userInfo);
1974 if (event == eCLSE_SessionUserJoin)
1976 if (pUser.Get())
1978 // XXX - ATG
1979 auto user = reinterpret_cast<Windows::Xbox::System::User^>(pUser.Get());
1980 GetChatIntegrationLayer()->AddLocalUserToChatChannel(0, user);
1983 else if (event == eCLSE_SessionUserLeave)
1985 if (pUser.Get())
1987 // XXX - ATG
1988 auto user = reinterpret_cast<Windows::Xbox::System::User^>(pUser.Get());
1989 GetChatIntegrationLayer()->RemoveUserFromChatChannel(0, user);
1993 else
1995 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
1996 SCryDurangoLiveUserID* pID = new SCryDurangoLiveUserID(pConnection->xuid);
1998 if (pID)
2000 SCryUserInfoResult userInfo;
2002 userInfo.m_conID = pConnection->uid;
2003 userInfo.m_isDedicated = false; // Live does not support dedicated servers
2004 userInfo.m_userID = pID;
2005 cry_strcpy(userInfo.m_userName, pConnection->name);
2006 memcpy(userInfo.m_userData, pConnection->userData, CRYLOBBY_USER_DATA_SIZE_IN_BYTES);
2008 CCryMatchMaking::SessionUserDataEvent(event, h, &userInfo);
2011 if (event == eCLSE_SessionUserJoin)
2013 // XXX - ATG
2014 GetChatIntegrationLayer()->AddRemoteConnection(h, id, pConnection->uid.m_uid);
2016 else if (event == eCLSE_SessionUserLeave)
2018 // XXX - ATG
2019 GetChatIntegrationLayer()->RemoveRemoteConnection(h, id, pConnection->uid.m_uid);
2025 void CCryDurangoLiveMatchMaking::ConnectionEstablishedUserDataEvent(CryLobbySessionHandle h, CryMatchMakingConnectionID id)
2027 SSession* pSession = &m_sessions[h];
2028 SSession::SRConnection* pConnection = &pSession->remoteConnection[id];
2030 SessionUserDataEvent(eCLSE_SessionUserJoin, h, id);
2033 void CCryDurangoLiveMatchMaking::InitialUserDataEvent(CryLobbySessionHandle h)
2035 SSession* pSession = &m_sessions[h];
2037 pSession->localFlags |= CRYSESSION_LOCAL_FLAG_USER_DATA_EVENTS_STARTED;
2039 SessionUserDataEvent(eCLSE_SessionUserJoin, h, CryMatchMakingInvalidConnectionID);
2041 for (uint32 i = 0; i < MAX_LOBBY_CONNECTIONS; ++i)
2043 SSession::SRConnection* pConnection = &pSession->remoteConnection[i];
2045 if (pConnection->used)
2047 SessionUserDataEvent(eCLSE_SessionUserJoin, h, i);
2052 const char* CCryDurangoLiveMatchMaking::SSession::GetLocalUserName(uint32 localUserIndex) const
2054 return NULL;
2057 void CCryDurangoLiveMatchMaking::SSession::Reset()
2059 CCryMatchMaking::SSession::Reset();
2061 sessionID = NULL_GUID;
2062 hostConnectionID = CryMatchMakingInvalidConnectionID;
2065 const char* CCryDurangoLiveMatchMaking::GetConnectionName(CCryMatchMaking::SSession::SRConnection* pConnection, uint32 localUserIndex) const
2067 SSession::SRConnection* pPlatformConnection = reinterpret_cast<SSession::SRConnection*>(pConnection);
2069 if (pPlatformConnection->uid.m_uid == DEDICATED_SERVER_CONNECTION_UID)
2071 return "DedicatedServer";
2074 if (pPlatformConnection->used)
2076 return pPlatformConnection->name;
2079 return NULL;
2082 uint64 CCryDurangoLiveMatchMaking::GetConnectionUserID(CCryMatchMaking::SSession::SRConnection* pConnection, uint32 localUserIndex) const
2084 return INVALID_USER_ID;
2087 TNetAddress CCryDurangoLiveMatchMaking::GetHostAddressFromSessionHandle(CrySessionHandle gh)
2089 LOBBY_AUTO_LOCK;
2091 CryLobbySessionHandle h = GetSessionHandleFromGameSessionHandle(gh);
2092 SSession* pSession = &m_sessions[h];
2094 if (pSession->serverConnectionID != CryMatchMakingInvalidConnectionID)
2096 const TNetAddress* pDedicatedServerAddr = m_lobby->GetNetAddress(pSession->remoteConnection[pSession->serverConnectionID].connectionID);
2098 if (pDedicatedServerAddr)
2100 return *pDedicatedServerAddr;
2104 if (pSession->localFlags & CRYSESSION_LOCAL_FLAG_HOST)
2106 return TNetAddress(TLocalNetAddress(m_lobby->GetInternalSocketPort(eCLS_Online)));
2109 if (pSession->hostConnectionID != CryMatchMakingInvalidConnectionID)
2111 const TNetAddress* pHostAddr = m_lobby->GetNetAddress(pSession->remoteConnection[pSession->hostConnectionID].connectionID);
2113 if (pHostAddr)
2115 return *pHostAddr;
2119 return TNetAddress(SNullAddr());
2122 #pragma warning(pop)
2124 #endif // USE_DURANGOLIVE && USE_CRY_MATCHMAKING