Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,374 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Multiplayer/BehaviorContext/GridSearchContext.h"
#include <GridMate/NetworkGridMate.h>
#include "Multiplayer/MultiplayerEventsComponent.h"
#include "Multiplayer/BehaviorContext/GridSystemContext.h"
#include "Multiplayer/GridMateServiceWrapper/GridMateServiceWrapper.h"
#include <Multiplayer/MultiplayerUtils.h>
namespace Multiplayer
{
/**
* Wrapper around a GridMate::GridSearch pointer
*/
struct GridSearchTicket
{
AZ_TYPE_INFO(GridSearchTicket, "{ADFA9839-4D38-4B3E-8909-9D55261E69D5}");
AZ_CLASS_ALLOCATOR(GridSearchTicket, AZ::SystemAllocator, 0);
GridSearchTicket(GridMate::GridSearch* ptr) : m_ptr(ptr)
{
}
~GridSearchTicket()
{
Reset();
}
int GetNumResults() const
{
if (m_ptr)
{
return m_ptr->GetNumResults();
}
return 0;
}
void Reset()
{
m_ptr = nullptr;
}
GridMate::GridSearch* GetGridSearch() const
{
return m_ptr;
}
private:
GridMate::GridSearch* m_ptr;
};
/**
* Helper class to manage SessionEventBus events on behalf of GridSearchBusHandler
*/
struct GridSessionCallbacksHandler
: public GridMate::SessionEventBus::Handler
{
GridSessionCallbacksHandler()
{
}
virtual ~GridSessionCallbacksHandler()
{
Disconnect();
}
void Connect(const SessionDesc& m_sessionDesc, GridMate::IGridMate* gridMate)
{
m_desc = m_sessionDesc;
GridMate::SessionEventBus::Handler::BusConnect(gridMate);
}
void Disconnect()
{
GridMate::SessionEventBus::Handler::BusDisconnect();
for (auto it : m_ticketMap)
{
delete it.second;
}
m_ticketMap.clear();
}
GridSearchTicket* CreateTicket(GridMate::GridSearch* gridSearch)
{
GridSearchTicket* gridSearchTicket = aznew GridSearchTicket(gridSearch);
m_ticketMap.insert(AZStd::make_pair(gridSearch, gridSearchTicket));
return gridSearchTicket;
}
bool ReleaseTicket(GridSearchTicket* ticket)
{
return ReleaseGridSearch(ticket->GetGridSearch());
}
bool ReleaseGridSearch(GridMate::GridSearch* gridSearch)
{
if (gridSearch == nullptr)
{
return false;
}
auto it = m_ticketMap.find(gridSearch);
if (it != m_ticketMap.end())
{
delete it->second;
m_ticketMap.erase(it);
return true;
}
return false;
}
GridSearchTicket* FindOrCreateGridSearchTicket(GridMate::GridSearch* gridSearch)
{
auto it = m_ticketMap.find(gridSearch);
if (it != m_ticketMap.end())
{
return it->second;
}
GridSearchTicket* newTicket = aznew GridSearchTicket(gridSearch);
m_ticketMap.insert(AZStd::make_pair(gridSearch, newTicket));
return newTicket;
}
//
// GridMate::SessionEventBus::Handler
//
void OnGridSearchComplete(GridMate::GridSearch* gridSearch) override
{
for (size_t i = 0; i < gridSearch->GetNumResults(); ++i)
{
EBUS_EVENT(GridSearchBus, OnSearchInfo, gridSearch->GetResult(i));
}
EBUS_EVENT(GridSearchBus, OnSearchComplete, FindOrCreateGridSearchTicket(gridSearch));
}
void OnGridSearchRelease(GridMate::GridSearch* gridSearch) override
{
ReleaseGridSearch(gridSearch);
}
void OnGridSearchStart(GridMate::GridSearch* gridSearch) override
{
(void)gridSearch;
}
void OnSessionDelete(GridMate::GridSession* session) override
{
(void)session;
Disconnect();
}
void OnSessionJoined(GridMate::GridSession* session) override
{
EBUS_EVENT(GridSearchBus, OnJoinComplete, session);
}
private:
SessionDesc m_desc;
AZStd::unordered_map<GridMate::GridSearch*, GridSearchTicket*> m_ticketMap;
};
/**
* Extends the Grid parameters with an optional security string
*/
struct SearchGridParameters
{
GridMate::string m_securityString;
const SessionDesc& m_sessionDesc;
SearchGridParameters(const SessionDesc& sessionDesc)
: m_securityString()
, m_sessionDesc(sessionDesc)
{
}
GridMate::GridSessionParam FetchGridSessionParam(const char* key)
{
GridMate::GridSessionParam param;
if (GridMateSystemContext::FetchParam(key, m_sessionDesc, param))
{
return param;
}
else if (!strcmp(key, "gm_securityData")) // has to come from a CFG
{
if (gEnv && gEnv->pConsole && gEnv->pConsole->GetCVar("gm_securityData"))
{
m_securityString = gEnv->pConsole->GetCVar("gm_securityData")->GetString();
param.SetValue(m_securityString);
}
}
return param;
}
};
/**
* Handles grid searches for a behavior context
*/
class GridSearchBusHandler
: public GridSearchBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(GridSearchBusHandler, "{83FF3AEB-2513-43A0-9BEE-ED8980449AEB}", AZ::SystemAllocator
, StartSearch
, StopSearch
, OnSearchComplete
, OnSearchError
, OnSearchInfo
, OnSearchClosed
, OnJoinComplete
);
protected:
//
// GridSearchInterface::Handler
//
const GridSearchTicket* StartSearch(const SessionDesc& sessionDesc) override
{
m_sessionDesc = sessionDesc;
GridMate::IGridMate* gridMate = FindGridMate();
if (!gridMate)
{
OnSearchError("Global GridMate not ready");
return nullptr;
}
m_gridSessionCallbacksHandler.Connect(m_sessionDesc, gridMate);
m_gridMateServiceWrapper.reset(GridMateSystemContext::RegisterServiceWrapper(m_sessionDesc.m_serviceType));
if (!m_gridMateServiceWrapper)
{
// error
return nullptr;
}
SearchGridParameters searchGridParameters(m_sessionDesc);
GridMateServiceParams gridMateServiceParams({}, AZStd::bind(&SearchGridParameters::FetchGridSessionParam, &searchGridParameters, AZStd::placeholders::_1));
GridMate::GridSearch* search = m_gridMateServiceWrapper->ListServers(gridMate, gridMateServiceParams);
if (search == nullptr)
{
EBUS_EVENT(GridSearchBus, OnSearchError, "ListServers failed to start a GridSearch.");
}
return m_gridSessionCallbacksHandler.CreateTicket(search);
}
bool JoinSession(const GridMate::SearchInfo* searchInfo)
{
GridMate::GridSession* session = nullptr;
GridMate::CarrierDesc carrierDesc;
SearchGridParameters searchGridParameters(m_sessionDesc);
GridMateServiceParams gridMateServiceParams({}, AZStd::bind(&SearchGridParameters::FetchGridSessionParam, &searchGridParameters, AZStd::placeholders::_1));
GridMateSystemContext::InitCarrierDesc(gridMateServiceParams, carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForJoin(carrierDesc);
session = m_gridMateServiceWrapper->JoinSession(FindGridMate(), carrierDesc, searchInfo);
if (session == nullptr)
{
OnSearchClosed(false);
Multiplayer::NetSec::OnSessionFailedToCreate(carrierDesc);
EBUS_EVENT(GridSearchBus, OnSearchError, "ListServers failed to start a GridSearch.");
}
else
{
OnSearchClosed(true);
}
return session != nullptr;
}
bool StopSearch(GridSearchTicket* ticket) override
{
if (ticket)
{
m_gridSessionCallbacksHandler.ReleaseTicket(ticket);
return true;
}
return false;
}
void OnSearchComplete(const GridSearchTicket* gridSearchTicket) override
{
Call(FN_OnSearchComplete, gridSearchTicket);
}
void OnSearchError(const GridMate::string& errorMsg)
{
Call(FN_OnSearchError, errorMsg);
}
void OnSearchInfo(const GridMate::SearchInfo* searchInfo) override
{
Call(FN_OnSearchInfo, searchInfo);
}
void OnSearchClosed(bool isJoiningSession) override
{
Call(FN_OnSearchClosed, isJoiningSession);
}
void OnJoinComplete(const GridMate::GridSession* gridSession) override
{
Call(FN_OnJoinComplete, gridSession);
}
//
// helper method(s)
//
GridMate::IGridMate* FindGridMate()
{
if (gEnv && gEnv->pNetwork)
{
return gEnv->pNetwork->GetGridMate();
}
return nullptr;
}
GridSessionCallbacksHandler m_gridSessionCallbacksHandler;
SessionDesc m_sessionDesc;
AZStd::unique_ptr<GridMateServiceWrapper> m_gridMateServiceWrapper;
};
/**
* Exposes Grid searching events and callbacks to a behavior context such as Lua
*/
namespace GridSearchBehavior
{
void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<GridMate::SearchInfo>()
->Version(1)
->Field("SessionId", &GridMate::SearchInfo::m_sessionId)
->Field("FreePublicSlots", &GridMate::SearchInfo::m_numFreePublicSlots)
->Field("FreePrivateSlots", &GridMate::SearchInfo::m_numFreePrivateSlots)
->Field("UsedPublicSlots", &GridMate::SearchInfo::m_numUsedPublicSlots)
->Field("UsedPrivateSlots", &GridMate::SearchInfo::m_numUsedPrivateSlots)
->Field("NumPlayers", &GridMate::SearchInfo::m_numPlayers)
;
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext);
if (behaviorContext)
{
behaviorContext->Class<GridSearchTicket>()
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::Value)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Method("GetNumResults", &GridSearchTicket::GetNumResults)
;
behaviorContext->Class<GridMate::SearchInfo>()
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::RuntimeOwn)
->Property("numPlayers", BehaviorValueProperty(&GridMate::SearchInfo::m_numPlayers))
->Property("numFreePrivateSlots", BehaviorValueProperty(&GridMate::SearchInfo::m_numFreePrivateSlots))
->Property("numUsedPrivateSlots", BehaviorValueProperty(&GridMate::SearchInfo::m_numUsedPrivateSlots))
->Property("numFreePublicSlots", BehaviorValueProperty(&GridMate::SearchInfo::m_numFreePublicSlots))
->Property("numUsedPublicSlots", BehaviorValueProperty(&GridMate::SearchInfo::m_numUsedPublicSlots))
;
behaviorContext->EBus<GridSearchBus>("GridSearchBusHandler")
->Handler<GridSearchBusHandler>()
->Event("StartSearch", &GridSearchBus::Events::StartSearch)
->Event("StopSearch", &GridSearchBus::Events::StopSearch)
->Event("JoinSession", &GridSearchBus::Events::JoinSession)
;
}
}
}
};
@@ -0,0 +1,427 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Multiplayer/BehaviorContext/GridSystemContext.h"
#include "Multiplayer/BehaviorContext/GridSearchContext.h"
#include <GridMate/NetworkGridMate.h>
#include "Multiplayer/GridMateServiceWrapper/GridMateLANServiceWrapper.h"
#include <Multiplayer_Traits_Platform.h>
#include <Multiplayer_GridMateServiceWrapper_Platform.h>
// Forward declarations for platform operations
namespace Platform
{
bool FetchParam(const char* key, const Multiplayer::SessionDesc& sessionDesc, GridMate::GridSessionParam& p);
}
#include "Multiplayer/MultiplayerUtils.h"
namespace Multiplayer
{
/**
* used to capture SessionEventBus and MultiplayerLobbyBus bus events for this behavior to forward onto the SessionManagerHandler
*/
struct SessionManagerHandlerImpl
: public GridMate::SessionEventBus::Handler
{
SessionManagerHandlerImpl()
: m_gridMate(nullptr)
{
if (gEnv->pNetwork)
{
m_gridMate = gEnv->pNetwork->GetGridMate();
}
}
~SessionManagerHandlerImpl()
{
Disconnect();
}
void Connect(SessionDesc sessionDesc)
{
m_sessionDesc = sessionDesc;
if (m_gridMate)
{
GridMate::SessionEventBus::Handler::BusConnect(m_gridMate);
}
}
void Disconnect()
{
GridMate::SessionEventBus::Handler::BusDisconnect();
}
//
// GridMate::SessionEventBus::Handler
//
void OnSessionCreated(GridMate::GridSession* session) override
{
(void)session;
}
void OnSessionStart(GridMate::GridSession* session) override
{
EBUS_EVENT(SessionManagerBus, OnHostSessionStarted, session);
}
void OnSessionEnd(GridMate::GridSession* session) override
{
(void)session;
}
void OnSessionDelete(GridMate::GridSession* session) override
{
(void)session;
}
void OnSessionError(GridMate::GridSession* session, const GridMate::string& errorMsg) override
{
(void)session;
(void)errorMsg;
}
//
// shared resource(s)
//
GridMate::IGridMate* GetGridMate() const
{
AZ_Assert(m_gridMate, "IGridMate missing.");
return m_gridMate;
}
private:
GridMate::IGridMate* m_gridMate;
SessionDesc m_sessionDesc;
};
/**
* The high level bus manager for GridMate Lua behaviors
*/
class SessionManagerHandler
: public SessionManagerBus::Handler
, public AZ::BehaviorEBusHandler
{
public:
AZ_EBUS_BEHAVIOR_BINDER(SessionManagerHandler, "{97F049D6-1C49-4661-A88C-1AE63E0554B3}", AZ::SystemAllocator
, StartHost
, Close
, OnHostSessionStarted
);
//
// SessionManagerBus::Handler
//
bool StartHost(const SessionDesc& sessionDesc) override
{
m_sessionDesc = sessionDesc;
Close();
m_gridMateSessionHandler.Connect(m_sessionDesc);
m_gridMateServiceWrapper.reset(GridMateSystemContext::RegisterServiceWrapper(m_sessionDesc.m_serviceType));
if (m_gridMateServiceWrapper)
{
if (m_gridMateServiceWrapper->StartSessionService(m_gridMateSessionHandler.GetGridMate()))
{
return CreateServerForWrappedService(sessionDesc);
}
}
return false;
}
bool Close() override
{
// disable further EBus communications with GridMate::SessionEventBus::Handler or MultiplayerLobbyBus::Handler
m_gridMateSessionHandler.Disconnect();
// handle GridMate resources
if (m_gridMateServiceWrapper)
{
m_gridMateServiceWrapper->StopSessionService(m_gridMateSessionHandler.GetGridMate());
m_gridMateServiceWrapper.reset(nullptr);
return true;
}
return false;
}
void OnHostSessionStarted(GridMate::GridSession* session) override
{
Call(FN_OnHostSessionStarted, session);
}
protected:
void InitCarrierDesc(GridMate::CarrierDesc& carrierDesc, const GridMateServiceParams& gridMateServiceParams)
{
if (!carrierDesc.m_simulator)
{
EBUS_EVENT_RESULT(carrierDesc.m_simulator, Multiplayer::MultiplayerRequestBus, GetSimulator);
}
m_securityString = gridMateServiceParams.FetchString("gm_securityData");
carrierDesc.m_port = gridMateServiceParams.FetchValueOrDefault<int>("cl_clientport", 0);
carrierDesc.m_connectionTimeoutMS = 10000;
carrierDesc.m_threadUpdateTimeMS = 30;
carrierDesc.m_threadInstantResponse = true;
carrierDesc.m_driverIsCrossPlatform = true;
carrierDesc.m_securityData = m_securityString.c_str();
carrierDesc.m_familyType = gridMateServiceParams.FetchValueOrDefault<int>("gm_ipversion", 1);
carrierDesc.m_version = gridMateServiceParams.m_version;
carrierDesc.m_enableDisconnectDetection = !!gridMateServiceParams.FetchValueOrDefault<int>("gm_disconnectDetection", 1);
carrierDesc.m_disconnectDetectionRttThreshold = gridMateServiceParams.FetchValueOrDefault<float>("gm_disconnectDetectionRttThreshold", 500.0f);
carrierDesc.m_disconnectDetectionPacketLossThreshold = gridMateServiceParams.FetchValueOrDefault<float>("gm_disconnectDetectionPacketLossThreshold", 0.3f);
#if AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY
#if AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE
AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(AZ_TRAIT_MULTIPLAYER_SESSION_NAME, AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE);
#endif
AZ_Error(AZ_TRAIT_MULTIPLAYER_SESSION_NAME, carrierDesc.m_familyType == AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE, AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE);
carrierDesc.m_familyType = AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE;
#endif
}
bool CreateServerForWrappedService([[maybe_unused]] const SessionDesc& sessionDesc)
{
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession, Multiplayer::MultiplayerRequestBus, GetSession);
if (!gridSession)
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
GridMate::SessionParams sessionParams;
sessionParams.m_topology = GridMate::ST_CLIENT_SERVER;
sessionParams.m_numPublicSlots = m_sessionDesc.m_maxPlayerSlots + (gEnv->IsDedicated() ? 1 : 0); // One slot for server member.
sessionParams.m_numPrivateSlots = 0;
sessionParams.m_peerToPeerTimeout = 60000;
sessionParams.m_flags = 0;
sessionParams.m_numParams = 0;
sessionParams.m_params[sessionParams.m_numParams].m_id = "sv_name";
sessionParams.m_params[sessionParams.m_numParams].SetValue(m_sessionDesc.m_serverName.c_str());
sessionParams.m_numParams++;
sessionParams.m_params[sessionParams.m_numParams].m_id = "sv_map";
sessionParams.m_params[sessionParams.m_numParams].SetValue(m_sessionDesc.m_mapName.c_str());
sessionParams.m_numParams++;
std::string securityString;
auto fetchParams = [&](const char* param)
{
GridMate::GridSessionParam p;
if (!strcmp(param, "cl_clientport"))
{
p.SetValue(m_sessionDesc.m_gamePort);
}
else if (!strcmp(param, "gm_ipversion"))
{
p.SetValue(AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE);
}
return p;
};
GridMateServiceParams gridMateServiceParams(sessionParams, fetchParams);
GridMate::CarrierDesc carrierDesc;
InitCarrierDesc(carrierDesc, gridMateServiceParams);
Multiplayer::NetSec::ConfigureCarrierDescForHost(carrierDesc);
carrierDesc.m_port = m_sessionDesc.m_gamePort;
carrierDesc.m_enableDisconnectDetection = m_sessionDesc.m_enableDisconnectDetection;
carrierDesc.m_connectionTimeoutMS = m_sessionDesc.m_connectionTimeoutMS;
carrierDesc.m_threadUpdateTimeMS = m_sessionDesc.m_threadUpdateTimeMS;
GridMate::GridSession* session = m_gridMateServiceWrapper->CreateServer(gridMate, carrierDesc, gridMateServiceParams);
if (session == nullptr)
{
Multiplayer::NetSec::OnSessionFailedToCreate(carrierDesc);
EBUS_EVENT(GridMate::SessionEventBus, OnSessionError, gridSession, "Error while hosting Session.");
}
else
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus, RegisterSession, session);
}
}
else
{
EBUS_EVENT(GridMate::SessionEventBus, OnSessionError, gridSession, "Invalid Gem Session");
return false;
}
return true;
}
SessionDesc m_sessionDesc;
SessionManagerHandlerImpl m_gridMateSessionHandler;
AZStd::unique_ptr<GridMateServiceWrapper> m_gridMateServiceWrapper;
AZStd::string m_securityString;
};
//////////////////////////////////////////////////////////////////////////
// GridMateSystemContext
namespace GridMateSystemContext
{
void Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serializeContext)
{
serializeContext->Class<SessionDesc>()
->Version(1)
->Field("Port", &SessionDesc::m_gamePort)
->Field("MaxPlayerSlots", &SessionDesc::m_maxPlayerSlots)
->Field("EnableDisconnectDetection", &SessionDesc::m_enableDisconnectDetection)
->Field("ConnectionTimeoutMS", &SessionDesc::m_connectionTimeoutMS)
->Field("ThreadUpdateTimeMS", &SessionDesc::m_threadUpdateTimeMS)
->Field("MapName", &SessionDesc::m_mapName)
->Field("ServerName", &SessionDesc::m_serverName)
->Field("ServiceType", &SessionDesc::m_serviceType)
;
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext);
if (behaviorContext)
{
behaviorContext->Class<GridMate::ServiceType>("GridServiceType")
->Enum<(int)GridMate::ST_LAN>("LAN")
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
->Enum<GridMate::ST_##CODENAME>(PublicAuxName2)
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
#endif
->Enum<(int)GridMate::ST_STEAM>("Steam")
;
// expose the parameters for a GridSession
behaviorContext->Class<SessionDesc>("SessionDesc")
->Property("gamePort", BehaviorValueProperty(&SessionDesc::m_gamePort))
->Property("mapName", BehaviorValueProperty(&SessionDesc::m_mapName))
->Property("maxPlayerSlots", BehaviorValueProperty(&SessionDesc::m_maxPlayerSlots))
->Property("serverName", BehaviorValueProperty(&SessionDesc::m_serverName))
->Property("enableDisconnectDetection", BehaviorValueProperty(&SessionDesc::m_enableDisconnectDetection))
->Property("connectionTimeoutMS", BehaviorValueProperty(&SessionDesc::m_connectionTimeoutMS))
->Property("threadUpdateTimeMS", BehaviorValueProperty(&SessionDesc::m_threadUpdateTimeMS))
->Property("serviceType", [](SessionDesc* that) -> int { return that->m_serviceType; }, [](SessionDesc* that, int value) { that->m_serviceType = static_cast<GridMate::ServiceType>(value); });
;
behaviorContext->EBus<SessionManagerBus>("SessionManagerBus")
->Handler<SessionManagerHandler>()
->Event("StartHost", &SessionManagerBus::Events::StartHost)
->Event("Close", &SessionManagerBus::Events::Close)
;
GridSearchBehavior::Reflect(behaviorContext);
}
}
// STATIC
bool FetchParam(const char * key, SessionDesc sessionDesc, GridMate::GridSessionParam& p)
{
if (!strcmp(key, "cl_clientport"))
{
if (sessionDesc.m_gamePort == 0)
{
if (gEnv && gEnv->pConsole && gEnv->pConsole->GetCVar("cl_clientport"))
{
p.SetValue(gEnv->pConsole->GetCVar("cl_clientport")->GetIVal());
}
}
else
{
p.SetValue(sessionDesc.m_gamePort);
}
}
else if (!strcmp(key, "gm_ipversion"))
{
p.SetValue(AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE);
}
else if (!strcmp(key, "gm_disconnectDetection"))
{
p.SetValue(sessionDesc.m_enableDisconnectDetection);
}
else if (!strcmp(key, "gm_disconnectDetectionRttThreshold"))
{
if (gEnv && gEnv->pConsole && gEnv->pConsole->GetCVar("gm_disconnectDetectionRttThreshold"))
{
p.SetValue(gEnv->pConsole->GetCVar("gm_disconnectDetectionRttThreshold")->GetFVal());
}
}
else if (!strcmp(key, "gm_disconnectDetectionPacketLossThreshold"))
{
if (gEnv && gEnv->pConsole && gEnv->pConsole->GetCVar("gm_disconnectDetectionPacketLossThreshold"))
{
p.SetValue(gEnv->pConsole->GetCVar("gm_disconnectDetectionPacketLossThreshold")->GetFVal());
}
}
else if (Platform::FetchParam(key, sessionDesc, p))
{
return true;
}
return !p.m_value.empty();
}
void InitCarrierDesc(const GridMateServiceParams& gridMateServiceParams, GridMate::CarrierDesc& carrierDesc)
{
if (!carrierDesc.m_simulator)
{
EBUS_EVENT_RESULT(carrierDesc.m_simulator, Multiplayer::MultiplayerRequestBus, GetSimulator);
}
carrierDesc.m_port = gridMateServiceParams.FetchValueOrDefault<int>("cl_clientport", 0);
carrierDesc.m_connectionTimeoutMS = 10000;
carrierDesc.m_threadUpdateTimeMS = 30;
carrierDesc.m_threadInstantResponse = true;
carrierDesc.m_driverIsCrossPlatform = true;
carrierDesc.m_securityData = gridMateServiceParams.FetchString("gm_securityData").c_str();
carrierDesc.m_familyType = gridMateServiceParams.FetchValueOrDefault<int>("gm_ipversion", 1);
carrierDesc.m_version = gridMateServiceParams.m_version;
carrierDesc.m_enableDisconnectDetection = !!gridMateServiceParams.FetchValueOrDefault<int>("gm_disconnectDetection", 1);
if (carrierDesc.m_enableDisconnectDetection)
{
carrierDesc.m_disconnectDetectionRttThreshold = gridMateServiceParams.FetchValueOrDefault<float>("gm_disconnectDetectionRttThreshold", 500.0f);
carrierDesc.m_disconnectDetectionPacketLossThreshold = gridMateServiceParams.FetchValueOrDefault<float>("gm_disconnectDetectionPacketLossThreshold", 0.3f);
}
#if AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY
#if AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE
AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(AZ_TRAIT_MULTIPLAYER_SESSION_NAME, AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE);
#endif
AZ_Error(AZ_TRAIT_MULTIPLAYER_SESSION_NAME, carrierDesc.m_familyType == AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE, AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE);
carrierDesc.m_familyType = AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE;
#endif
}
/**
* Helper function to translate GridMate::ServiceType to the proper MultiplayerLobbyServiceWrapper
*/
GridMateServiceWrapper* RegisterServiceWrapper(GridMate::ServiceType gridServiceType)
{
switch (gridServiceType)
{
case GridMate::ST_LAN:
return aznew GridMateLANServiceWrapper();
#if AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_WRAPPER
case GridMate::AZ_TRAIT_MULTIPLAYER_GRIDMATE_SERVICE_TYPE_ENUM:
return aznew AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_TYPE_CLASS();
#endif
default:
AZ_Assert(false, "Unsupported GridMate::ServiceType of %d", gridServiceType);
}
return nullptr;
}
} // namespace GridMateSystemContext
};
@@ -0,0 +1,121 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <Source/Canvas/MultiplayerCanvasHelper.h>
#include <Source/Canvas/MultiplayerBusyAndErrorCanvas.h>
namespace Multiplayer
{
static const char* ErrorWindow = "ErrorWindow";
static const char* ErrorMessage = "ErrorMessage";
static const char* BusyScreen = "BusyScreen";
static const char* MultiplayeBusyAndErrorCanvasName = "ui/Canvases/busy_error.uicanvas";
MultiplayerBusyAndErrorCanvas::MultiplayerBusyAndErrorCanvas(const MultiplayerBusyAndErrorCanvasContext& context)
: m_context(context)
, m_isShowingBusy(false)
, m_isShowingError(false)
{
m_canvasEntityId = LoadCanvas(MultiplayeBusyAndErrorCanvasName);
AZ_Error("MultiplayerLobbyComponent", m_canvasEntityId.IsValid(), "Missing UI file for Busy and Error Canvas.");
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
SetElementEnabled(m_canvasEntityId, ErrorWindow, false);
SetElementEnabled(m_canvasEntityId, BusyScreen, false);
}
MultiplayerBusyAndErrorCanvas::~MultiplayerBusyAndErrorCanvas()
{
UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasEntityId);
}
void MultiplayerBusyAndErrorCanvas::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId);
if (actionName == "OnDismissErrorMessage")
{
m_context.OnDismissErrroWindowButtonClicked(false);
}
}
void MultiplayerBusyAndErrorCanvas::ShowError(const char* message)
{
if (m_isShowingBusy)
{
DismissBusyScreen();
}
if (!m_isShowingError)
{
m_isShowingError = true;
SetElementEnabled(m_canvasEntityId, ErrorWindow, true);
SetElementText(m_canvasEntityId, ErrorMessage, message);
}
else
{
m_errorMessageQueue.emplace_back(message);
}
}
void MultiplayerBusyAndErrorCanvas::ShowQueuedErrorMessage()
{
if (!m_errorMessageQueue.empty())
{
AZStd::string errorMessage = m_errorMessageQueue.front();
m_errorMessageQueue.erase(m_errorMessageQueue.begin());
ShowError(errorMessage.c_str());
}
}
void MultiplayerBusyAndErrorCanvas::DismissError(bool force)
{
if (m_isShowingError || force)
{
m_isShowingError = false;
SetElementEnabled(m_canvasEntityId, ErrorWindow, false);
if (force)
{
m_errorMessageQueue.clear();
}
else
{
ShowQueuedErrorMessage();
}
}
}
void MultiplayerBusyAndErrorCanvas::ShowBusyScreen()
{
if (!m_isShowingBusy)
{
m_isShowingBusy = true;
SetElementEnabled(m_canvasEntityId, BusyScreen, true);
}
}
void MultiplayerBusyAndErrorCanvas::DismissBusyScreen(bool force)
{
if (m_isShowingBusy || force)
{
m_isShowingBusy = false;
SetElementEnabled(m_canvasEntityId, BusyScreen, false);
}
}
}
@@ -0,0 +1,53 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
namespace Multiplayer
{
struct MultiplayerBusyAndErrorCanvasContext
{
std::function<void(bool)> OnDismissErrroWindowButtonClicked;
};
/*
* Canvas to support Multiplayer busy and error screens. Handles canvas UI events. Load last to overlay over others
*/
class MultiplayerBusyAndErrorCanvas
: public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerBusyAndErrorCanvas, AZ::SystemAllocator, 0);
MultiplayerBusyAndErrorCanvas() {}
MultiplayerBusyAndErrorCanvas(const MultiplayerBusyAndErrorCanvasContext&);
virtual ~MultiplayerBusyAndErrorCanvas();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
virtual void ShowError(const char* error);
virtual void DismissError(bool force = false);
virtual void ShowBusyScreen();
virtual void DismissBusyScreen(bool force = false);
private:
void ShowQueuedErrorMessage();
AZ::EntityId m_canvasEntityId;
MultiplayerBusyAndErrorCanvasContext m_context;
AZStd::vector< AZStd::string > m_errorMessageQueue;
bool m_isShowingError;
bool m_isShowingBusy;
};
}
@@ -0,0 +1,187 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <LyShine/Bus/UiElementBus.h>
#include <LyShine/Bus/UiInteractableBus.h>
#include <LyShine/Bus/UiTextBus.h>
#include <LyShine/Bus/UiTextInputBus.h>
#include <LyShine/Bus/UiCheckboxBus.h>
#include <LyShine/Bus/UiCanvasManagerBus.h>
#include <LyShine/Bus/UiCanvasBus.h>
#include <IConsole.h>
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Multiplayer
{
AZ::EntityId LoadCanvas(const char* canvasName)
{
AZ::EntityId canvasEntityId;
EBUS_EVENT_RESULT(canvasEntityId, UiCanvasManagerBus, LoadCanvas, canvasName);
return canvasEntityId;
}
void ReleaseCanvas(const AZ::EntityId& canvasId)
{
if (canvasId.IsValid())
{
EBUS_EVENT(UiCanvasManagerBus, UnloadCanvas, canvasId);
}
}
void SetElementEnabled(const AZ::EntityId& canvasID, const char* elementName, bool enabled)
{
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
if (element != nullptr)
{
EBUS_EVENT_ID(element->GetId(), UiElementBus, SetIsEnabled, enabled);
}
}
bool IsElementEnabled(const AZ::EntityId& canvasID, const char* elementName)
{
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
bool enabled = false;
if (element != nullptr)
{
EBUS_EVENT_ID_RESULT(enabled, element->GetId(), UiElementBus, IsEnabled);
}
return enabled;
}
void SetElementInputEnabled(const AZ::EntityId& canvasID, const char* elementName, bool enabled)
{
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
if (element != nullptr)
{
EBUS_EVENT_ID(element->GetId(), UiInteractableBus, SetIsHandlingEvents, enabled);
}
}
void SetElementText(const AZ::EntityId& canvasID, const char* elementName, const char* text)
{
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
if (element != nullptr)
{
if (UiTextInputBus::FindFirstHandler(element->GetId()))
{
EBUS_EVENT_ID(element->GetId(), UiTextInputBus, SetText, text);
}
else if (UiTextBus::FindFirstHandler(element->GetId()))
{
EBUS_EVENT_ID(element->GetId(), UiTextBus, SetText, text);
}
}
}
LyShine::StringType GetElementText(const AZ::EntityId& canvasID, const char* elementName)
{
LyShine::StringType retVal;
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
if (element != nullptr)
{
if (UiTextInputBus::FindFirstHandler(element->GetId()))
{
EBUS_EVENT_ID_RESULT(retVal, element->GetId(), UiTextInputBus, GetText);
}
else if (UiTextBus::FindFirstHandler(element->GetId()))
{
EBUS_EVENT_ID_RESULT(retVal, element->GetId(), UiTextBus, GetText);
}
}
return retVal;
}
void SetCheckBoxState(const AZ::EntityId& canvasID, const char* elementName, bool value)
{
bool retVal = false;;
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
if (element != nullptr)
{
EBUS_EVENT_ID(element->GetId(), UiCheckboxBus, SetState, value);
}
}
bool GetCheckBoxState(const AZ::EntityId& canvasID, const char* elementName)
{
bool retVal = false;;
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, canvasID, UiCanvasBus, FindElementByName, elementName);
if (element != nullptr)
{
EBUS_EVENT_ID_RESULT(retVal, element->GetId(), UiCheckboxBus, GetState);
}
return retVal;
}
const char* GetConsoleVarValue(const char* param)
{
ICVar* cvar = gEnv->pConsole->GetCVar(param);
if (cvar)
{
return cvar->GetString();
}
return "";
}
bool GetGetConsoleVarBoolValue(const char* param)
{
bool value = false;
ICVar* cvar = gEnv->pConsole->GetCVar(param);
if (cvar)
{
if (cvar->GetI64Val())
{
value = true;
}
}
return value;
}
void SetConsoleVarValue(const char* param, const char* value)
{
ICVar* cvar = gEnv->pConsole->GetCVar(param);
if (cvar)
{
cvar->Set(value);
}
}
bool SetGetConsoleVarBoolValue(const char* param, bool value)
{
ICVar* cvar = gEnv->pConsole->GetCVar(param);
if (cvar)
{
value ? cvar->Set(1) : cvar->Set(0);
}
return value;
}
}
@@ -0,0 +1,43 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/UiBase.h>
namespace Multiplayer
{
AZ::EntityId LoadCanvas(const char* canvasName);
void ReleaseCanvas(const AZ::EntityId& canvasId);
void SetElementEnabled(const AZ::EntityId& canvasID, const char* elementName, bool enabled);
bool IsElementEnabled(const AZ::EntityId& canvasID, const char* elementName);
void SetElementInputEnabled(const AZ::EntityId& canvasID, const char* elementName, bool enabled);
void SetElementText(const AZ::EntityId& canvasID, const char* elementName, const char* text);
LyShine::StringType GetElementText(const AZ::EntityId& canvasID, const char* elementName);
void SetCheckBoxState(const AZ::EntityId& canvasID, const char* elementName, bool value);
bool GetCheckBoxState(const AZ::EntityId& canvasID, const char* elementName);
const char* GetConsoleVarValue(const char* param);
bool GetGetConsoleVarBoolValue(const char* param);
void SetConsoleVarValue(const char* param, const char* value);
bool SetGetConsoleVarBoolValue(const char* param, bool value);
}
@@ -0,0 +1,57 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <Source/Canvas/MultiplayerCanvasHelper.h>
#include <Source/Canvas/MultiplayerCreateServerView.h>
namespace Multiplayer
{
static const char* ServerNameTextBox = "ServerNameTextBox";
static const char* MapNameTextBox = "MapNameTextBox";
MultiplayerCreateServerView::MultiplayerCreateServerView(const MultiplayerCreateServerViewContext& context, const AZ::EntityId canvasEntityId)
: m_context(context)
, m_canvasEntityId(canvasEntityId)
{
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
SetElementText(m_canvasEntityId, ServerNameTextBox, m_context.DefaultServerName.c_str());
SetElementText(m_canvasEntityId, MapNameTextBox, m_context.DefaultMapName.c_str());
}
MultiplayerCreateServerView::~MultiplayerCreateServerView()
{
UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasEntityId);
}
void MultiplayerCreateServerView::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId)
if (actionName == "OnCreateServer")
{
m_context.OnCreateServerButtonClicked();
}
}
LyShine::StringType MultiplayerCreateServerView::GetMapName() const
{
return GetElementText(m_canvasEntityId, MapNameTextBox);
}
LyShine::StringType MultiplayerCreateServerView::GetServerName() const
{
return GetElementText(m_canvasEntityId, ServerNameTextBox);
}
}
@@ -0,0 +1,46 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
namespace Multiplayer
{
struct MultiplayerCreateServerViewContext
{
AZStd::string DefaultMapName;
AZStd::string DefaultServerName;
std::function<void()> OnCreateServerButtonClicked;
};
/*
* View to support Multiplayer Create Server. Handles UI events for creating server.
*/
class MultiplayerCreateServerView
: public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerCreateServerView, AZ::SystemAllocator, 0);
MultiplayerCreateServerView(const MultiplayerCreateServerViewContext&, const AZ::EntityId);
virtual ~MultiplayerCreateServerView();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
LyShine::StringType GetMapName() const;
LyShine::StringType GetServerName() const;
private:
AZ::EntityId m_canvasEntityId;
MultiplayerCreateServerViewContext m_context;
};
}
@@ -0,0 +1,130 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <Source/Canvas/MultiplayerDedicatedHostTypeSelectionCanvas.h>
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Multiplayer
{
static const char* MultiplayerDedicatedHostTypeSelectionCanvasName = "ui/Canvases/selection_lobby.uicanvas";
static const char* GameLiftConfigWindow = "GameLiftConfig";
static const char* GameliftAWSAccesKeyInput = "AWSAccessKey";
static const char* GameliftAWSSecretKeyInput = "AWSSecretKey";
static const char* GameliftAWSRegionInput = "AWSRegion";
static const char* GameliftEndPointInput = "EndPoint";
static const char* GameliftPlayerIDInput = "PlayerId";
static const char* GameliftButton = "GameLiftButton";
MultiplayerDedicatedHostTypeSelectionCanvas::MultiplayerDedicatedHostTypeSelectionCanvas(const MultiplayerDedicatedHostTypeSelectionCanvasContext& context)
: m_context(context)
, m_isShowingGameLiftConfig(false)
{
m_canvasEntityId = LoadCanvas(MultiplayerDedicatedHostTypeSelectionCanvasName);
AZ_Error("MultiplayerLobbyComponent", m_canvasEntityId.IsValid(), "Missing UI file for ServerType Selection Lobby.");
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
#if defined(BUILD_GAMELIFT_CLIENT)
SetElementInputEnabled(m_canvasEntityId, GameliftButton, true);
#else
SetElementInputEnabled(m_canvasEntityId, GameliftButton, false);
#endif
SetElementEnabled(m_canvasEntityId, GameLiftConfigWindow, false);
}
MultiplayerDedicatedHostTypeSelectionCanvas::~MultiplayerDedicatedHostTypeSelectionCanvas()
{
UiCanvasNotificationBus::Handler::BusDisconnect();
ReleaseCanvas(m_canvasEntityId);
}
void MultiplayerDedicatedHostTypeSelectionCanvas::Show()
{
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, true);
}
void MultiplayerDedicatedHostTypeSelectionCanvas::Hide()
{
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, false);
}
void MultiplayerDedicatedHostTypeSelectionCanvas::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId)
if (actionName == "LANButtonClicked")
{
m_context.OnLANButtonClicked();
}
else if (actionName == "GameliftButtonClicked")
{
ShowGameLiftConfig();
}
else if (actionName == "OnGameliftConnect")
{
SaveGameLiftConfig();
DismissGameLiftConfig();
m_context.OnGameLiftConnectButtonClicked();
}
else if (actionName == "OnGameliftCancel")
{
DismissGameLiftConfig();
}
}
void MultiplayerDedicatedHostTypeSelectionCanvas::ShowGameLiftConfig()
{
if (!m_isShowingGameLiftConfig)
{
m_isShowingGameLiftConfig = true;
SetElementEnabled(m_canvasEntityId, GameLiftConfigWindow, true);
SetElementText(m_canvasEntityId, GameliftAWSAccesKeyInput, GetConsoleVarValue("gamelift_aws_access_key"));
SetElementText(m_canvasEntityId, GameliftAWSSecretKeyInput, GetConsoleVarValue("gamelift_aws_secret_key"));
SetElementText(m_canvasEntityId, GameliftAWSRegionInput, GetConsoleVarValue("gamelift_aws_region"));
SetElementText(m_canvasEntityId, GameliftPlayerIDInput, GetConsoleVarValue("gamelift_player_id"));
SetElementText(m_canvasEntityId, GameliftEndPointInput, GetConsoleVarValue("gamelift_endpoint"));
}
}
void MultiplayerDedicatedHostTypeSelectionCanvas::DismissGameLiftConfig()
{
if (m_isShowingGameLiftConfig)
{
m_isShowingGameLiftConfig = false;
SetElementEnabled(m_canvasEntityId, GameLiftConfigWindow, false);
}
}
void MultiplayerDedicatedHostTypeSelectionCanvas::SaveGameLiftConfig()
{
LyShine::StringType param;
param = GetElementText(m_canvasEntityId, GameliftAWSAccesKeyInput);
SetConsoleVarValue("gamelift_aws_access_key", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftAWSSecretKeyInput);
SetConsoleVarValue("gamelift_aws_secret_key", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftAWSRegionInput);
SetConsoleVarValue("gamelift_aws_region", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftEndPointInput);
SetConsoleVarValue("gamelift_endpoint", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftPlayerIDInput);
SetConsoleVarValue("gamelift_player_id", param.c_str());
}
}
@@ -0,0 +1,56 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
namespace Multiplayer
{
struct MultiplayerDedicatedHostTypeSelectionCanvasContext
{
std::function<void()> OnLANButtonClicked;
std::function<void()> OnGameLiftConnectButtonClicked;
};
/*
* Canvas view to support Multiplayer server hosting type. Currently Supported LAN and GameLift. Handles canvas UI events.
*/
class MultiplayerDedicatedHostTypeSelectionCanvas
: public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerDedicatedHostTypeSelectionCanvas, AZ::SystemAllocator, 0);
MultiplayerDedicatedHostTypeSelectionCanvas() {}
MultiplayerDedicatedHostTypeSelectionCanvas(const MultiplayerDedicatedHostTypeSelectionCanvasContext&);
virtual ~MultiplayerDedicatedHostTypeSelectionCanvas();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
virtual void Show();
virtual void Hide();
private:
void ShowGameLiftConfig();
void DismissGameLiftConfig();
void SaveGameLiftConfig();
AZ::EntityId m_canvasEntityId;
MultiplayerDedicatedHostTypeSelectionCanvasContext m_context;
AZStd::vector< AZStd::string > m_errorMessageQueue;
bool m_isShowingBusy;
bool m_isShowingError;
bool m_isShowingGameLiftConfig;
};
}
@@ -0,0 +1,62 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <Source/Canvas/MultiplayerGameLiftFlextMatchView.h>
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Multiplayer
{
const char* MultiplayerGameLiftMatchmakingConfig = "MatchmakingConfigTextBox";
MultiplayerGameLiftFlextMatchView::MultiplayerGameLiftFlextMatchView(const MultiplayerGameLiftFlextMatchViewContext& context, const AZ::EntityId canvasEntityId)
: m_context(context)
, m_canvasEntityId(canvasEntityId)
{
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
LyShine::StringType configName = GetConsoleVarValue("gamelift_matchmaking_config_name");
if (!configName.empty())
{
SetElementText(m_canvasEntityId, MultiplayerGameLiftMatchmakingConfig, configName.c_str());
}
else
{
SetElementText(m_canvasEntityId, MultiplayerGameLiftMatchmakingConfig, m_context.DefaultMatchmakingConfig.c_str());
SaveMatchmakingConfigName();
}
}
MultiplayerGameLiftFlextMatchView::~MultiplayerGameLiftFlextMatchView()
{
UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasEntityId);
}
void MultiplayerGameLiftFlextMatchView::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId)
if (actionName == "OnStartMatchmaking")
{
SaveMatchmakingConfigName();
m_context.OnStartMatchmakingButtonClicked();
}
}
void MultiplayerGameLiftFlextMatchView::SaveMatchmakingConfigName()
{
LyShine::StringType param;
param = GetElementText(m_canvasEntityId, MultiplayerGameLiftMatchmakingConfig);;
SetConsoleVarValue("gamelift_matchmaking_config_name", param.c_str());
}
}
@@ -0,0 +1,42 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
namespace Multiplayer
{
struct MultiplayerGameLiftFlextMatchViewContext
{
AZStd::string DefaultMatchmakingConfig;
std::function<void()> OnStartMatchmakingButtonClicked;
};
/*
* View to support GameLift flex match. Handles canvas UI events.
*/
class MultiplayerGameLiftFlextMatchView : public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerGameLiftFlextMatchView, AZ::SystemAllocator, 0);
MultiplayerGameLiftFlextMatchView(const MultiplayerGameLiftFlextMatchViewContext&, const AZ::EntityId);
virtual ~MultiplayerGameLiftFlextMatchView();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
private:
void SaveMatchmakingConfigName();
AZ::EntityId m_canvasEntityId;
MultiplayerGameLiftFlextMatchViewContext m_context;
};
}
@@ -0,0 +1,190 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <Source/Canvas/MultiplayerGameLiftLobbyCanvas.h>
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Multiplayer
{
static const char* MultiplayerGameLiftLobbyCanvasName = "ui/Canvases/gamelift_lobby.uicanvas";
static const char* MultiplayerGameLiftLobbyCreateServerContainerName = "CreateServerContainer";
static const char* MultiplayerGameLiftLobbyJoinServerContainerName = "JoinServerContainer";
static const char* MultiplayerGameLiftLobbyFlexMatchContainerName = "FlexMatchContainer";
static const char* GameliftCreateContainerFleetIDInput = "FleetId";
static const char* GameliftCreateContainerQueueNameInput = "QueueName";
static const char* GameliftCreateContainerAliasIDInput = "AliasId";
static const char* GameliftJoinContainerFleetIDInput = "JoinContainerFleetId";
static const char* GameliftJoinContainerQueueNameInput = "JoinContainerQueueName";
static const char* GameliftJoinContainerAliasIDInput = "JoinContainerAliasId";
MultiplayerGameLiftLobbyCanvas::MultiplayerGameLiftLobbyCanvas(const MultiplayerGameLiftLobbyCanvasContext& context)
: m_context(context)
{
m_canvasEntityId = LoadCanvas(MultiplayerGameLiftLobbyCanvasName);
AZ_Error("MultiplayerLobbyComponent", m_canvasEntityId.IsValid(), "Missing UI file for GameLift Lobby.");
m_context.JoinServerViewContext.ServerListingVector.emplace_back(69, 72, 70);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(73, 76, 74);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(77, 80, 78);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(81, 84, 82);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(85, 88, 86);
m_joinServerScreen = aznew MultiplayerJoinServerView(m_context.JoinServerViewContext, m_canvasEntityId);
m_flexMatchScreen = aznew MultiplayerGameLiftFlextMatchView(m_context.GameLiftFlexMatchViewContext, m_canvasEntityId);
m_createServerScreen = aznew MultiplayerCreateServerView(m_context.CreateServerViewContext, m_canvasEntityId);
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, false);
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyCreateServerContainerName, true);
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyJoinServerContainerName, false);
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyFlexMatchContainerName, false);
RefreshGameLiftConfig();
}
MultiplayerGameLiftLobbyCanvas::~MultiplayerGameLiftLobbyCanvas()
{
delete m_joinServerScreen;
m_joinServerScreen = nullptr;
delete m_createServerScreen;
m_createServerScreen = nullptr;
delete m_flexMatchScreen;
m_flexMatchScreen = nullptr;
UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasEntityId);
ReleaseCanvas(m_canvasEntityId);
m_canvasEntityId.SetInvalid();
}
void MultiplayerGameLiftLobbyCanvas::Show()
{
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, true);
}
void MultiplayerGameLiftLobbyCanvas::Hide()
{
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, false);
}
void MultiplayerGameLiftLobbyCanvas::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId)
if (actionName == "CreateServerRadioButtonOn")
{
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyCreateServerContainerName, true);
}
else if (actionName == "CreateServerRadioButtonOff")
{
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyCreateServerContainerName, false);
}
else if (actionName == "JoinServerRadioButtonOn")
{
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyJoinServerContainerName, true);
}
else if (actionName == "JoinServerRadioButtonOff")
{
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyJoinServerContainerName, false);
}
else if (actionName == "FlextMatchRadioButtonOn")
{
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyFlexMatchContainerName, true);
}
else if (actionName == "FlextMatchRadioButtonOff")
{
SetElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyFlexMatchContainerName, false);
}
else if (actionName == "OnReturn")
{
m_context.OnReturnButtonClicked();
}
else if (actionName == "OnGameLiftConfigEdit")
{
SaveGameLiftConfig();
}
RefreshGameLiftConfig();
}
void MultiplayerGameLiftLobbyCanvas::RefreshGameLiftConfig()
{
if (IsElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyCreateServerContainerName))
{
SetElementText(m_canvasEntityId, GameliftCreateContainerFleetIDInput, GetConsoleVarValue("gamelift_fleet_id"));
SetElementText(m_canvasEntityId, GameliftCreateContainerQueueNameInput, GetConsoleVarValue("gamelift_queue_name"));
SetElementText(m_canvasEntityId, GameliftCreateContainerAliasIDInput, GetConsoleVarValue("gamelift_alias_id"));
}
else if (IsElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyJoinServerContainerName))
{
SetElementText(m_canvasEntityId, GameliftJoinContainerFleetIDInput, GetConsoleVarValue("gamelift_fleet_id"));
SetElementText(m_canvasEntityId, GameliftJoinContainerQueueNameInput, GetConsoleVarValue("gamelift_queue_name"));
SetElementText(m_canvasEntityId, GameliftJoinContainerAliasIDInput, GetConsoleVarValue("gamelift_alias_id"));
}
}
void MultiplayerGameLiftLobbyCanvas::SaveGameLiftConfig()
{
LyShine::StringType param;
if (IsElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyCreateServerContainerName))
{
param = GetElementText(m_canvasEntityId, GameliftCreateContainerFleetIDInput);
SetConsoleVarValue("gamelift_fleet_id", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftCreateContainerQueueNameInput);
SetConsoleVarValue("gamelift_queue_name", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftCreateContainerAliasIDInput);
SetConsoleVarValue("gamelift_alias_id", param.c_str());
}
else if (IsElementEnabled(m_canvasEntityId, MultiplayerGameLiftLobbyJoinServerContainerName))
{
param = GetElementText(m_canvasEntityId, GameliftJoinContainerFleetIDInput);
SetConsoleVarValue("gamelift_fleet_id", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftJoinContainerQueueNameInput);
SetConsoleVarValue("gamelift_queue_name", param.c_str());
param = GetElementText(m_canvasEntityId, GameliftJoinContainerAliasIDInput);
SetConsoleVarValue("gamelift_alias_id", param.c_str());
}
}
void MultiplayerGameLiftLobbyCanvas::DisplaySearchResults(const GridMate::GridSearch* search)
{
m_joinServerScreen->DisplaySearchResults(search);
}
LyShine::StringType MultiplayerGameLiftLobbyCanvas::GetMapName() const
{
return m_createServerScreen->GetMapName();
}
LyShine::StringType MultiplayerGameLiftLobbyCanvas::GetServerName() const
{
return m_createServerScreen->GetServerName();
}
void MultiplayerGameLiftLobbyCanvas::ClearSearchResults()
{
m_joinServerScreen->ClearSearchResults();
}
int MultiplayerGameLiftLobbyCanvas::GetSelectedServerResult()
{
return m_joinServerScreen->m_selectedServerResult;
}
}
@@ -0,0 +1,64 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
#include <Source/Canvas/MultiplayerJoinServerView.h>
#include <Source/Canvas/MultiplayerCreateServerView.h>
#include <Source/Canvas/MultiplayerGameLiftFlextMatchView.h>
namespace Multiplayer
{
struct MultiplayerGameLiftLobbyCanvasContext
{
MultiplayerJoinServerViewContext JoinServerViewContext;
MultiplayerGameLiftFlextMatchViewContext GameLiftFlexMatchViewContext;
MultiplayerCreateServerViewContext CreateServerViewContext;
std::function<void()> OnReturnButtonClicked;
};
/*
* Canvas view to support GameLift lobby. Handles canvas UI events.
*/
class MultiplayerGameLiftLobbyCanvas
: public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerGameLiftLobbyCanvas, AZ::SystemAllocator, 0);
MultiplayerGameLiftLobbyCanvas() {}
MultiplayerGameLiftLobbyCanvas(const MultiplayerGameLiftLobbyCanvasContext&);
virtual ~MultiplayerGameLiftLobbyCanvas();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
virtual void Show();
virtual void Hide();
virtual void DisplaySearchResults(const GridMate::GridSearch*);
virtual void ClearSearchResults();
virtual int GetSelectedServerResult();
virtual LyShine::StringType GetMapName() const;
virtual LyShine::StringType GetServerName() const;
protected:
MultiplayerJoinServerView* m_joinServerScreen;
MultiplayerGameLiftFlextMatchView* m_flexMatchScreen;
MultiplayerCreateServerView* m_createServerScreen;
private:
void SaveGameLiftConfig();
void RefreshGameLiftConfig();
AZ::EntityId m_canvasEntityId;
MultiplayerGameLiftLobbyCanvasContext m_context;
};
}
@@ -0,0 +1,197 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <GridMate/Session/Session.h>
#include <LyShine/Bus/UiElementBus.h>
#include <LyShine/Bus/UiTextBus.h>
#include <Source/Canvas/MultiplayerJoinServerView.h>
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Multiplayer
{
static const char* JoinButton = "JoinButton";
MultiplayerJoinServerView::MultiplayerJoinServerView(const MultiplayerJoinServerViewContext& context, const AZ::EntityId canvasEntityId)
: m_context(context), m_canvasEntityId(canvasEntityId)
{
AZ_Error("MultiplayerLobbyComponent", m_canvasEntityId.IsValid(), "Invalid CanvasId passed in");
for (ServerListingResultRowData serverListingData : m_context.ServerListingVector)
{
m_listingRows.emplace_back(m_canvasEntityId, serverListingData.RowElementId, serverListingData.TextElementId, serverListingData.HighlightElementId);
}
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
ClearSearchResults();
}
MultiplayerJoinServerView::~MultiplayerJoinServerView()
{
UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasEntityId);
}
void MultiplayerJoinServerView::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId)
if (actionName == "OnJoinServer")
{
m_context.OnJoinButtonClicked();
}
else if (actionName == "OnRefresh")
{
m_context.OnRefreshButtonClicked();
}
else if (actionName == "OnSelectServer")
{
LyShine::ElementId elementId = 0;
EBUS_EVENT_ID_RESULT(elementId, entityId, UiElementBus, GetElementId);
SelectId(elementId);
}
}
void MultiplayerJoinServerView::DisplaySearchResults(const GridMate::GridSearch* search)
{
for (unsigned int i = 0; i < search->GetNumResults(); ++i)
{
// Screen is currently not dynamically populated, so we are stuck with a fixed size
// amount of results for now.
if (i >= m_listingRows.size())
{
break;
}
const GridMate::SearchInfo* searchInfo = search->GetResult(i);
ServerListingResultRow& resultRow = m_listingRows[i];
resultRow.DisplayResult(searchInfo);
}
}
void MultiplayerJoinServerView::ClearSearchResults()
{
m_selectedServerResult = -1;
for (ServerListingResultRow& serverResultRow : m_listingRows)
{
serverResultRow.ResetDisplay();
}
SetElementInputEnabled(m_canvasEntityId, JoinButton, false);
}
void MultiplayerJoinServerView::SelectId(int rowId)
{
SetElementInputEnabled(m_canvasEntityId, JoinButton, false);
int lastSelection = m_selectedServerResult;
m_selectedServerResult = -1;
for (int i = 0; i < static_cast<int>(m_listingRows.size()); ++i)
{
ServerListingResultRow& resultRow = m_listingRows[i];
if (resultRow.GetRowID() == rowId)
{
SetElementInputEnabled(m_canvasEntityId, JoinButton, true);
m_selectedServerResult = i;
resultRow.Select();
}
else
{
resultRow.Deselect();
}
}
// Double click to join.
if (m_selectedServerResult >= 0 && lastSelection == m_selectedServerResult)
{
m_context.OnJoinButtonClicked();
}
}
///////////////////////////
// ServerListingResultRow
///////////////////////////
MultiplayerJoinServerView::ServerListingResultRow::ServerListingResultRow(const AZ::EntityId& canvas, int row, int text, int highlight)
: m_canvas(canvas)
, m_row(row)
, m_text(text)
, m_highlight(highlight)
{
}
int MultiplayerJoinServerView::ServerListingResultRow::GetRowID()
{
return m_row;
}
void MultiplayerJoinServerView::ServerListingResultRow::Select()
{
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, m_canvas, UiCanvasBus, FindElementById, m_highlight);
if (element != nullptr)
{
EBUS_EVENT_ID(element->GetId(), UiElementBus, SetIsEnabled, true);
}
}
void MultiplayerJoinServerView::ServerListingResultRow::Deselect()
{
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, m_canvas, UiCanvasBus, FindElementById, m_highlight);
if (element != nullptr)
{
EBUS_EVENT_ID(element->GetId(), UiElementBus, SetIsEnabled, false);
}
}
void MultiplayerJoinServerView::ServerListingResultRow::DisplayResult(const GridMate::SearchInfo* searchInfo)
{
char displayString[64];
const char* serverName = "";
for (unsigned int i = 0; i < searchInfo->m_numParams; ++i)
{
const GridMate::GridSessionParam& param = searchInfo->m_params[i];
if (param.m_id == "sv_name")
{
serverName = param.m_value.c_str();
break;
}
}
azsnprintf(displayString, AZ_ARRAY_SIZE(displayString), "%s (%u/%u)", serverName, searchInfo->m_numUsedPublicSlots, searchInfo->m_numFreePublicSlots + searchInfo->m_numUsedPublicSlots);
AZ::Entity* element = nullptr;
EBUS_EVENT_ID_RESULT(element, m_canvas, UiCanvasBus, FindElementById, m_text);
if (element != nullptr)
{
LyShine::StringType textString(displayString);
EBUS_EVENT_ID(element->GetId(), UiTextBus, SetText, textString);
}
}
void MultiplayerJoinServerView::ServerListingResultRow::ResetDisplay()
{
Deselect();
}
}
@@ -0,0 +1,93 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
#include <GridMate/GridMate.h>
namespace Multiplayer
{
/*
* Stores find server listing data
*/
struct ServerListingResultRowData
{
int RowElementId;
int TextElementId;
int HighlightElementId;
ServerListingResultRowData(int row, int text, int highlight)
{
this->RowElementId = row;
this->TextElementId = text;
this->HighlightElementId = highlight;
}
};
struct MultiplayerJoinServerViewContext
{
std::function<void()> OnJoinButtonClicked;
std::function<void()> OnRefreshButtonClicked;
AZStd::vector<ServerListingResultRowData> ServerListingVector;
};
/*
* View to support Multiplayer find and join Server. Handles canvas UI events.
*/
class MultiplayerJoinServerView
: public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerJoinServerView, AZ::SystemAllocator, 0);
MultiplayerJoinServerView(const MultiplayerJoinServerViewContext&, const AZ::EntityId);
virtual ~MultiplayerJoinServerView();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
void DisplaySearchResults(const GridMate::GridSearch*);
void ClearSearchResults();
void SelectId(int rowId);
int m_selectedServerResult;
private:
AZ::EntityId m_canvasEntityId;
MultiplayerJoinServerViewContext m_context;
/*
* Defines UI view and actions for listing servers
*/
class ServerListingResultRow
{
public:
ServerListingResultRow(const AZ::EntityId& canvas, int row, int text, int highlight);
int GetRowID();
void Select();
void Deselect();
void DisplayResult(const GridMate::SearchInfo* result);
void ResetDisplay();
private:
AZ::EntityId m_canvas;
int m_row;
int m_text;
int m_highlight;
};
AZStd::vector< ServerListingResultRow > m_listingRows;
};
}
@@ -0,0 +1,99 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <Source/Canvas/MultiplayerJoinServerView.h>
#include <Source/Canvas/MultiplayerCreateServerView.h>
#include <Source/Canvas/MultiplayerLANGameLobbyCanvas.h>
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Multiplayer
{
static const char* MultiplayerLANGameLobbyCanvasName = "ui/Canvases/listing_lobby.uicanvas";
MultiplayerLANGameLobbyCanvas::MultiplayerLANGameLobbyCanvas(const MultiplayerLANGameLobbyCanvasContext& context)
: m_context(context)
{
m_canvasEntityId = LoadCanvas(MultiplayerLANGameLobbyCanvasName);
AZ_Error("MultiplayerLobbyComponent", m_canvasEntityId.IsValid(), "Missing UI file for Server Listing Lobby.");
m_context.JoinServerViewContext.ServerListingVector.emplace_back(10, 11, 32);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(12, 13, 33);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(14, 15, 34);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(16, 17, 35);
m_context.JoinServerViewContext.ServerListingVector.emplace_back(18, 19, 36);
m_joinServerScreen = aznew MultiplayerJoinServerView(m_context.JoinServerViewContext, m_canvasEntityId);
m_createServerScreen = aznew MultiplayerCreateServerView(m_context.CreateServerViewContext, m_canvasEntityId);
UiCanvasNotificationBus::Handler::BusConnect(m_canvasEntityId);
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, false);
}
MultiplayerLANGameLobbyCanvas::~MultiplayerLANGameLobbyCanvas()
{
delete m_joinServerScreen;
m_joinServerScreen = nullptr;
delete m_createServerScreen;
m_createServerScreen = nullptr;
UiCanvasNotificationBus::Handler::BusDisconnect(m_canvasEntityId);
ReleaseCanvas(m_canvasEntityId);
m_canvasEntityId.SetInvalid();
}
void MultiplayerLANGameLobbyCanvas::OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName)
{
AZ_UNUSED(entityId)
if (actionName == "OnReturn")
{
m_context.OnReturnButtonClicked();
}
}
void MultiplayerLANGameLobbyCanvas::Show()
{
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, true);
}
void MultiplayerLANGameLobbyCanvas::Hide()
{
EBUS_EVENT_ID(m_canvasEntityId, UiCanvasBus, SetEnabled, false);
}
void MultiplayerLANGameLobbyCanvas::DisplaySearchResults(const GridMate::GridSearch* search)
{
m_joinServerScreen->DisplaySearchResults(search);
}
void MultiplayerLANGameLobbyCanvas::ClearSearchResults()
{
m_joinServerScreen->ClearSearchResults();
}
int MultiplayerLANGameLobbyCanvas::GetSelectedServerResult()
{
return m_joinServerScreen->m_selectedServerResult;
}
LyShine::StringType MultiplayerLANGameLobbyCanvas::GetMapName() const
{
return m_createServerScreen->GetMapName();
}
LyShine::StringType MultiplayerLANGameLobbyCanvas::GetServerName() const
{
return m_createServerScreen->GetServerName();
}
}
@@ -0,0 +1,64 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <LyShine/Bus/UiCanvasBus.h>
#include <GridMate/GridMate.h>
namespace Multiplayer
{
struct MultiplayerCreateServerViewContext;
class MultiplayerCreateServerView;
struct MultiplayerJoinServerViewContext;
class MultiplayerJoinServerView;
struct MultiplayerLANGameLobbyCanvasContext
{
MultiplayerJoinServerViewContext JoinServerViewContext;
MultiplayerCreateServerViewContext CreateServerViewContext;
std::function<void()> OnReturnButtonClicked;
};
/*
* Canvas view to support Multiplayer LAN lobby. Handles canvas UI events.
*/
class MultiplayerLANGameLobbyCanvas
: public UiCanvasNotificationBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(MultiplayerLANGameLobbyCanvas, AZ::SystemAllocator, 0);
MultiplayerLANGameLobbyCanvas() {}
MultiplayerLANGameLobbyCanvas(const MultiplayerLANGameLobbyCanvasContext&);
virtual ~MultiplayerLANGameLobbyCanvas();
// UiCanvasActionNotification
void OnAction(AZ::EntityId entityId, const LyShine::ActionName& actionName) override;
virtual void Show();
virtual void Hide();
virtual void DisplaySearchResults(const GridMate::GridSearch*);
virtual void ClearSearchResults();
virtual int GetSelectedServerResult();
virtual LyShine::StringType GetMapName() const;
virtual LyShine::StringType GetServerName() const;
protected:
MultiplayerJoinServerView* m_joinServerScreen;
MultiplayerCreateServerView* m_createServerScreen;
private:
AZ::EntityId m_canvasEntityId;
MultiplayerLANGameLobbyCanvasContext m_context;
};
}
@@ -0,0 +1,140 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Source/GameLift/GameLiftMatchmakingComponent.h"
#include <GridMate/NetworkGridMate.h>
#include <GameLift/GameLiftBus.h>
#include <GameLift/Session/GameLiftServerServiceBus.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_SERVER)
GameLiftMatchmakingComponent::GameLiftMatchmakingComponent(GridMate::GridSession* gridSession)
{
m_session = gridSession;
m_startTime = AZStd::chrono::system_clock::now();
m_customMatchBackfillEnable = GetConsoleVarBoolValue("gamelift_flexmatch_enable");
m_customMatchBackfillOnPlayerRemovedEnable = GetConsoleVarBoolValue("gamelift_flexmatch_onplayerremoved_enable");
m_customMatchBackfillStartDelaySeconds = GetConsoleVarFloatValue("gamlift_flexmatch_start_delay");
m_minimumPlayerSessionCount = GetConsoleVarIntValue("gamelift_flexmatch_minimumplayersessioncount");
AZ::SystemTickBus::Handler::BusConnect();
GridMate::GameLiftServerServiceEventsBus::Handler::BusConnect(m_session->GetGridMate());
GridMate::SessionEventBus::Handler::BusConnect(m_session->GetGridMate());
}
GameLiftMatchmakingComponent::~GameLiftMatchmakingComponent()
{
AZ::SystemTickBus::Handler::BusDisconnect();
GridMate::GameLiftServerServiceEventsBus::Handler::BusDisconnect(m_session->GetGridMate());
GridMate::SessionEventBus::Handler::BusDisconnect(m_session->GetGridMate());
m_matchmakingTicketIds.clear();
m_session = nullptr;
}
void GameLiftMatchmakingComponent::OnSystemTick()
{
if (m_customMatchBackfillEnable && m_customMatchBackfillStart)
{
GridMate::TimeStamp now = AZStd::chrono::system_clock::now();
float timeElapsed = AZStd::chrono::duration<float>(now - m_startTime).count();
if (timeElapsed > m_customMatchBackfillStartDelaySeconds)
{
CallStartMatchmakingBackfill();
m_customMatchBackfillStart = false;
}
}
}
void GameLiftMatchmakingComponent::OnMemberJoined([[maybe_unused]] GridMate::GridSession* session, [[maybe_unused]] GridMate::GridMember* member)
{
AZ_TracePrintf("Multiplayer", "calling OnMemberJoined FreeSlots:%d UsedSLots:%d", m_session->GetNumFreePublicSlots(), m_session->GetNumUsedPublicSlots());
// Start delayed matchbackfill after initial minimum players have joined.
if (m_session->GetNumUsedPublicSlots() == m_minimumPlayerSessionCount)
{
m_customMatchBackfillStart = true;
return;
}
if (m_customMatchBackfillEnable && m_session->GetNumFreePublicSlots() > 0 // Need at least 1 free slot
&& (m_session->GetNumUsedPublicSlots() > m_minimumPlayerSessionCount // Minimum number of players already exists for the one time delayed back fill
|| (m_session->GetNumUsedPublicSlots() == m_minimumPlayerSessionCount && !m_customMatchBackfillStart))) // After initial delayed backfill rest of the times
{
CallStartMatchmakingBackfill();
}
}
void GameLiftMatchmakingComponent::OnGameLiftGameSessionUpdated([[maybe_unused]] GridMate::GameLiftServerService* service, const Aws::GameLift::Server::Model::UpdateGameSession& updateGameSession)
{
if (updateGameSession.GetUpdateReason() == Aws::GameLift::Server::Model::UpdateReason::BACKFILL_TIMED_OUT)
{
auto it = AZStd::find(m_matchmakingTicketIds.begin(), m_matchmakingTicketIds.end(), AZStd::string(updateGameSession.GetBackfillTicketId().c_str()));
if (it != m_matchmakingTicketIds.end())
{
EBUS_EVENT_ID(gEnv->pNetwork->GetGridMate(), GridMate::GameLiftServerServiceBus, StartMatchmakingBackfill, m_session, *it, false);
}
}
}
void GameLiftMatchmakingComponent::OnMemberLeaving([[maybe_unused]] GridMate::GridSession* session, [[maybe_unused]] GridMate::GridMember* member)
{
AZ_TracePrintf("Multiplayer", "calling OnMemberLeaving FreeSlots:%d UsedSLots:%d", m_session->GetNumFreePublicSlots(), m_session->GetNumUsedPublicSlots());
if (m_session->GetNumUsedPublicSlots() < m_minimumPlayerSessionCount)
{
for (auto ticketId : m_matchmakingTicketIds)
{
EBUS_EVENT_ID(gEnv->pNetwork->GetGridMate(), GridMate::GameLiftServerServiceBus, StopMatchmakingBackfill, m_session, ticketId);
}
m_matchmakingTicketIds.clear();
EBUS_EVENT(GridMate::GameLiftServerServiceBus, ShutdownSession, m_session);
return;
}
if (m_customMatchBackfillOnPlayerRemovedEnable)
{
CallStartMatchmakingBackfill(false);
}
}
void GameLiftMatchmakingComponent::CallStartMatchmakingBackfill(bool checkAutoBackfill)
{
bool matchmakingBackfillTicketCreated = false;
AZStd::string matchmakingBackfillTicketId = "";
EBUS_EVENT_ID_RESULT(matchmakingBackfillTicketCreated, gEnv->pNetwork->GetGridMate(), GridMate::GameLiftServerServiceBus
, StartMatchmakingBackfill, m_session, matchmakingBackfillTicketId, checkAutoBackfill);
if (matchmakingBackfillTicketCreated)
{
m_matchmakingTicketIds.push_back(matchmakingBackfillTicketId);
}
}
float GameLiftMatchmakingComponent::GetConsoleVarFloatValue(const char* param)
{
ICVar* cvar = gEnv->pConsole->GetCVar(param);
return cvar ? cvar->GetFVal() : 0.0F;
}
int GameLiftMatchmakingComponent::GetConsoleVarIntValue(const char* param)
{
ICVar* cvar = gEnv->pConsole->GetCVar(param);
return cvar ? cvar->GetIVal() : 0;
}
bool GameLiftMatchmakingComponent::GetConsoleVarBoolValue(const char* param)
{
ICVar* cvar = gEnv->pConsole->GetCVar(param);
return cvar ? cvar->GetI64Val() : false;
}
#endif
}
@@ -0,0 +1,62 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <AzCore/Component/TickBus.h>
#include <GameLift/Session/GameLiftServerServiceEventsBus.h>
#include <GridMate/Session/Session.h>
#include <GridMate/Types.h>
#include <AzCore/Memory/SystemAllocator.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_SERVER)
/**
* GameLiftMatchmakingComponent responsible for handling custom matchmaking events for Multiplayer
*/
class GameLiftMatchmakingComponent
: public AZ::SystemTickBus::Handler
, public GridMate::GameLiftServerServiceEventsBus::Handler
, public GridMate::SessionEventBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(GameLiftMatchmakingComponent, AZ::SystemAllocator, 0)
GameLiftMatchmakingComponent(GridMate::GridSession* gridSession);
~GameLiftMatchmakingComponent();
private:
void OnSystemTick() override;
void OnGameLiftGameSessionUpdated(GridMate::GameLiftServerService* service, const Aws::GameLift::Server::Model::UpdateGameSession& updateGameSession) override;
void OnMemberJoined(GridMate::GridSession* session, GridMate::GridMember* member) override;
void OnMemberLeaving(GridMate::GridSession* session, GridMate::GridMember* member) override;
void CallStartMatchmakingBackfill(bool checkAutoBackfill = true);
float GetConsoleVarFloatValue(const char* param);
bool GetConsoleVarBoolValue(const char* param);
int GetConsoleVarIntValue(const char* param);
// Initialized from Cvars
float m_customMatchBackfillStartDelaySeconds;
bool m_customMatchBackfillEnable;
bool m_customMatchBackfillOnPlayerRemovedEnable;
int m_minimumPlayerSessionCount;
GridMate::TimeStamp m_startTime;
bool m_customMatchBackfillStart = false;
GridMate::GridSession* m_session;
AZStd::vector<AZStd::string> m_matchmakingTicketIds;
};
#endif
}
@@ -0,0 +1,91 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "GameLiftListener.h"
#include "MultiplayerGem.h"
#include "Multiplayer/MultiplayerUtils.h"
#include <GridMate/NetworkGridMate.h>
#include <GameLift/Session/GameLiftServerSession.h>
#include <GameLift/Session/GameLiftServerServiceBus.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_SERVER)
GameLiftListener::GameLiftListener()
{
CRY_ASSERT(gEnv->pNetwork);
CRY_ASSERT(gEnv->pNetwork->GetGridMate());
GridMate::GameLiftServerServiceEventsBus::Handler::BusConnect(gEnv->pNetwork->GetGridMate());
}
GameLiftListener::~GameLiftListener()
{
GridMate::GameLiftServerServiceEventsBus::Handler::BusDisconnect();
}
void GameLiftListener::OnGameLiftGameSessionStarted([[maybe_unused]] GridMate::GameLiftServerService* service, const Aws::GameLift::Server::Model::GameSession& gameSession)
{
CRY_ASSERT(gEnv->pNetwork);
CRY_ASSERT(gEnv->pNetwork->GetGridMate());
GridMate::Network* gm = static_cast<GridMate::Network*>(gEnv->pNetwork);
if (gm->GetCurrentSession())
{
CryLogAlways("New session(%s) started from gamelift while another session(%s) is still in progress.",
gameSession.GetGameSessionId().c_str(),
gm->GetCurrentSession()->GetId().c_str());
return;
}
// server begins hosting
GridMate::CarrierDesc carrierDesc;
// Get the general configurations, then override the port.
Multiplayer::Utils::InitCarrierDesc(carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForHost(carrierDesc);
carrierDesc.m_port = gEnv->pConsole->GetCVar("sv_port")->GetIVal();
GridMate::GameLiftSessionParams sp;
sp.m_topology = GridMate::ST_CLIENT_SERVER;
sp.m_flags = 0;
sp.m_numParams = 0;
sp.m_numPrivateSlots = 1; // One slot for server member.
sp.m_gameSession = &gameSession;
GridMate::GridSession* session = nullptr;
EBUS_EVENT_ID_RESULT(session,gEnv->pNetwork->GetGridMate(),GridMate::GameLiftServerServiceBus, HostSession, sp, carrierDesc);
if (session)
{
EBUS_EVENT(MultiplayerRequestBus, RegisterSession, session);
}
}
void GameLiftListener::OnGameLiftGameSessionUpdated(GridMate::GameLiftServerService* service, const Aws::GameLift::Server::Model::UpdateGameSession& updateGameSession)
{
AZ_UNUSED(service);
AZ_UNUSED(updateGameSession);
}
void GameLiftListener::OnGameLiftServerWillTerminate(GridMate::GameLiftServerService* service)
{
(void)service;
CryLogAlways("Got terminate request from GameLift. Application will be closed!");
gEnv->pSystem->Quit();
}
#endif
}
@@ -0,0 +1,40 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <GameLift/Session/GameLiftServerServiceEventsBus.h>
#include <AzCore/Memory/SystemAllocator.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_SERVER)
/**
* GameLiftListener
* pImpl implementation to listen for GameLift specific events. Will start hosting session once GameLift is ready.
* Will trigger application shutdown when it is triggered by GameLift
*/
class GameLiftListener
: public GridMate::GameLiftServerServiceEventsBus::Handler
{
public:
AZ_CLASS_ALLOCATOR(GameLiftListener, AZ::SystemAllocator, 0)
GameLiftListener();
~GameLiftListener();
private:
void OnGameLiftGameSessionStarted(GridMate::GameLiftServerService* service, const Aws::GameLift::Server::Model::GameSession& gameSession) override;
void OnGameLiftGameSessionUpdated(GridMate::GameLiftServerService* service, const Aws::GameLift::Server::Model::UpdateGameSession& updateGameSession) override;
void OnGameLiftServerWillTerminate(GridMate::GameLiftServerService* service) override;
};
#endif
}
@@ -0,0 +1,91 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <GridMate/Session/LANSession.h>
#include "Multiplayer/GridMateServiceWrapper/GridMateLANServiceWrapper.h"
#include "Multiplayer/MultiplayerUtils.h"
#include <Multiplayer_Traits_Platform.h>
namespace Multiplayer
{
bool GridMateLANServiceWrapper::SanityCheck(GridMate::IGridMate* gridMate)
{
// Nothing in LAN Session Service we need to sanity check
(void)gridMate;
return true;
}
bool GridMateLANServiceWrapper::StartSessionService(GridMate::IGridMate* gridMate)
{
Multiplayer::LAN::StartSessionService(gridMate);
return GridMate::HasGridMateService<GridMate::LANSessionService>(gridMate);
}
void GridMateLANServiceWrapper::StopSessionService(GridMate::IGridMate* gridMate)
{
Multiplayer::LAN::StopSessionService(gridMate);
}
GridMate::GridSession* GridMateLANServiceWrapper::CreateServerForService(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc, const GridMateServiceParams& params)
{
GridMate::GridSession* gridSession = nullptr;
// Setup and create the LANSessionParams
GridMate::LANSessionParams sessionParams;
params.AssignSessionParams(sessionParams);
sessionParams.m_port = GetServerPort(params);
EBUS_EVENT_ID_RESULT(gridSession,gridMate,GridMate::LANSessionServiceBus,HostSession,sessionParams,carrierDesc);
return gridSession;
}
GridMate::GridSearch* GridMateLANServiceWrapper::ListServersForService(GridMate::IGridMate* gridMate, const GridMateServiceParams& params)
{
GridMate::GridSearch* retVal = nullptr;
GridMate::LANSearchParams searchParams;
searchParams.m_serverPort = GetServerPort(params);
searchParams.m_listenPort = 0;
searchParams.m_version = params.m_version;
searchParams.m_familyType = static_cast<GridMate::Driver::BSDSocketFamilyType>(params.FetchValueOrDefault<int>("gm_ipversion", GridMate::Driver::BSDSocketFamilyType::BSD_AF_INET));
#if AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY
AZ_Error(AZ_TRAIT_MULTIPLAYER_SESSION_NAME, searchParams.m_familyType == AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE, AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE);
searchParams.m_familyType = AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE;
#endif
EBUS_EVENT_ID_RESULT(retVal, gridMate, GridMate::LANSessionServiceBus, StartGridSearch, searchParams);
return retVal;
}
GridMate::GridSession* GridMateLANServiceWrapper::JoinSessionForService(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc, const GridMate::SearchInfo* searchInfo)
{
GridMate::GridSession* gridSession = nullptr;
const GridMate::LANSearchInfo& lanSearchInfo = static_cast<const GridMate::LANSearchInfo&>(*searchInfo);
GridMate::JoinParams joinParams;
EBUS_EVENT_ID_RESULT(gridSession, gridMate, GridMate::LANSessionServiceBus, JoinSessionBySearchInfo, lanSearchInfo, joinParams, carrierDesc);
return gridSession;
}
int GridMateLANServiceWrapper::GetServerPort(const GridMateServiceParams& params) const
{
// GamePort is reserved for game traffic, we want to go 1 above it to manage our server duties. i.e. Responding to search requests.
return params.FetchValueOrDefault<int>("cl_clientport", 0) + 1;
}
}
@@ -0,0 +1,96 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Multiplayer/GridMateServiceWrapper/GridMateServiceWrapper.h"
#include <AzCore/std/string/conversions.h>
namespace Multiplayer
{
namespace Convert
{
template <>
int GridSessionParam(const GridMate::GridSessionParam& param, int orDefault)
{
if (param.m_type != GridMate::GridSessionParam::VT_INT32)
{
return orDefault;
}
return AZStd::stoi(param.m_value);
}
template <>
float GridSessionParam(const GridMate::GridSessionParam& param, float orDefault)
{
if (param.m_type != GridMate::GridSessionParam::VT_FLOAT)
{
return orDefault;
}
return AZStd::stof(param.m_value);
}
template <>
long long GridSessionParam(const GridMate::GridSessionParam& param, long long orDefault)
{
if (param.m_type != GridMate::GridSessionParam::VT_INT64)
{
return orDefault;
}
return AZStd::stoll(param.m_value);
}
template <>
double GridSessionParam(const GridMate::GridSessionParam& param, double orDefault)
{
if (param.m_type != GridMate::GridSessionParam::VT_DOUBLE)
{
return orDefault;
}
return AZStd::stod(param.m_value);
}
}
GridMate::GridSession* GridMateServiceWrapper::CreateServer(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc, const GridMateServiceParams& params)
{
GridMate::GridSession* gridSession = nullptr;
if (StartSessionService(gridMate) && SanityCheck(gridMate))
{
gridSession = CreateServerForService(gridMate,carrierDesc, params);
}
return gridSession;
}
GridMate::GridSearch* GridMateServiceWrapper::ListServers(GridMate::IGridMate* gridMate, const GridMateServiceParams& params)
{
GridMate::GridSearch* gridSearch = nullptr;
if (StartSessionService(gridMate) && SanityCheck(gridMate))
{
gridSearch = ListServersForService(gridMate, params);
}
return gridSearch;
}
GridMate::GridSession* GridMateServiceWrapper::JoinSession(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc, const GridMate::SearchInfo* searchInfo)
{
GridMate::GridSession* gridSession = nullptr;
if (StartSessionService(gridMate) && SanityCheck(gridMate))
{
gridSession = JoinSessionForService(gridMate, carrierDesc, searchInfo);
}
return gridSession;
}
}
@@ -0,0 +1,886 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <INetwork.h>
#include <SFunctor.h>
#include "MultiplayerCVars.h"
#include "MultiplayerGem.h"
#include "MultiplayerGameLiftClient.h"
#include "Multiplayer/MultiplayerUtils.h"
#include <GameLift/GameLiftBus.h>
#include <GameLift/Session/GameLiftSessionDefs.h>
#include <GameLift/Session/GameLiftServerService.h>
#include <CertificateManager/ICertificateManagerGem.h>
#include <CertificateManager/DataSource/FileDataSourceBus.h>
#include <GridMate/Carrier/DefaultSimulator.h>
#include <GridMate/Session/LANSession.h>
#include <Multiplayer_Traits_Platform.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_SERVER)
static void StartGameLiftServer([[maybe_unused]] IConsoleCmdArgs *args)
{
CRY_ASSERT(gEnv->pConsole);
// set the sys_dump_type to 2 so error dump files don't exceed GameLift size limits
ICVar* sys_dump_type_cvar = gEnv->pConsole->GetCVar("sys_dump_type");
if (sys_dump_type_cvar)
{
sys_dump_type_cvar->Set(2);
}
GridMate::GameLiftServerServiceDesc serviceDesc;
if (gEnv && gEnv->pFileIO)
{
const char pathToLogFolder[] = "@log@/";
char resolvedPath[AZ_MAX_PATH_LEN];
if (gEnv->pFileIO->ResolvePath(pathToLogFolder, resolvedPath, AZ_ARRAY_SIZE(resolvedPath)))
{
serviceDesc.m_logPaths.push_back(resolvedPath);
}
}
if (gEnv->pConsole->GetCVar("sv_port"))
{
serviceDesc.m_port = gEnv->pConsole->GetCVar("sv_port")->GetIVal();
}
EBUS_EVENT(GameLift::GameLiftRequestBus, StartServerService, serviceDesc);
}
static void StopGameLiftServer([[maybe_unused]] IConsoleCmdArgs *args)
{
EBUS_EVENT(GameLift::GameLiftRequestBus, StopServerService);
}
#endif
//-----------------------------------------------------------------------------
void CmdNetSimulator(IConsoleCmdArgs* args)
{
GridMate::Simulator* simulator = nullptr;
EBUS_EVENT_RESULT(simulator,Multiplayer::MultiplayerRequestBus,GetSimulator);
GridMate::GridSession* session = nullptr;
EBUS_EVENT_RESULT(session,Multiplayer::MultiplayerRequestBus,GetSession);
if (!simulator && session)
{
CryLogAlways("Simulator should be enabled before GridMate session starts. Use 'mpdisconnect' to destroy the session.");
return;
}
if (args->GetArgCount() == 2 && CryStringUtils::ToYesNoType(args->GetArg(1)) == CryStringUtils::YesNoType::No)
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus,DisableSimulator);
return;
}
if (args->GetArgCount() == 2 && !azstricmp(args->GetArg(1), "help"))
{
CryLogAlways("gm_net_simulator off - Disable simulator");
CryLogAlways("gm_net_simulator param1:value1 param2:value2, ... - Enable simulator with given parameters");
CryLogAlways("Available parameters:");
CryLogAlways("oLatMin, oLatMax - Outgoing latency in milliseconds");
CryLogAlways("iLatMin, iLatMax - Incoming latency in milliseconds");
CryLogAlways("oBandMin, oBandMax - Outgoing bandwidth in Kbps");
CryLogAlways("iBandMin, iBandMax - Incoming bandwidth in Kbps");
CryLogAlways("oLossMin, oLossMax - Outgoing packet loss, will lose one packet every interval");
CryLogAlways("iLossMin, iLossMax - Incoming packet loss, will lose one packet every interval");
CryLogAlways("oDropMin, oDropMax, oDropPeriodMin, oDropPeriodMax - Outgoing packet drop, will periodically lose packets for given interval");
CryLogAlways("iDropMin, iDropMax, iDropPeriodMin, iDropPeriodMax - Incoming packet drop, will periodically lose packets for given interval");
CryLogAlways("oReorder - [0|1] Outgoing packet reordering. You need to enable latency to reorder packets.");
CryLogAlways("iReorder - [0|1] Incoming packet reordering. You need to enable latency to reorder packets.");
return;
}
if (args->GetArgCount() > 1)
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus,EnableSimulator);
EBUS_EVENT_RESULT(simulator, Multiplayer::MultiplayerRequestBus, GetSimulator);
}
GridMate::DefaultSimulator* sim = static_cast<GridMate::DefaultSimulator*>(simulator);
if (sim)
{
unsigned int oLatMin, oLatMax;
unsigned int iLatMin, iLatMax;
unsigned int oBandMin, oBandMax;
unsigned int iBandMin, iBandMax;
unsigned int oLossMin, oLossMax;
unsigned int iLossMin, iLossMax;
unsigned int oDropMin, oDropMax, oDropPeriodMin, oDropPeriodMax;
unsigned int iDropMin, iDropMax, iDropPeriodMin, iDropPeriodMax;
bool oReorder, iReorder;
sim->GetOutgoingLatency(oLatMin, oLatMax);
sim->GetIncomingLatency(iLatMin, iLatMax);
sim->GetOutgoingBandwidth(oBandMin, oBandMax);
sim->GetIncomingBandwidth(iBandMin, iBandMax);
sim->GetOutgoingPacketLoss(oLossMin, oLossMax);
sim->GetIncomingPacketLoss(iLossMin, iLossMax);
sim->GetOutgoingPacketDrop(oDropMin, oDropMax, oDropPeriodMin, oDropPeriodMax);
sim->GetIncomingPacketDrop(iDropMin, iDropMax, iDropPeriodMin, iDropPeriodMax);
oReorder = sim->IsOutgoingReorder();
iReorder = sim->IsIncomingReorder();
for (int i = 1; i < args->GetArgCount(); ++i)
{
const char* arg = args->GetArg(i);
unsigned int param;
char key[64];
#if AZ_TRAIT_USE_SECURE_CRT_FUNCTIONS
int numParams = sscanf_s(arg, "%64[^:]:%u", key, (unsigned int)AZ_ARRAY_SIZE(key), &param) - 1;
#else
int numParams = sscanf(arg, "%64[^:]:%u", key, &param) - 1;
#endif
if (numParams <= 0)
{
CryLogAlways("ERROR: Invalid argument format: %s. Should be 'key:value'. Bailing out.", arg);
return;
}
if (!azstricmp(key, "oLatMin"))
{
oLatMin = param;
}
else if (!azstricmp(key, "oLatMax"))
{
oLatMax = param;
}
else if (!azstricmp(key, "iLatMin"))
{
iLatMin = param;
}
else if (!azstricmp(key, "iLatMax"))
{
iLatMax = param;
}
else if (!azstricmp(key, "oBandMin"))
{
oBandMin = param;
}
else if (!azstricmp(key, "oBandMax"))
{
oBandMax = param;
}
else if (!azstricmp(key, "iBandMin"))
{
iBandMin = param;
}
else if (!azstricmp(key, "iBandMax"))
{
iBandMax = param;
}
else if (!azstricmp(key, "oLossMin"))
{
oLossMin = param;
}
else if (!azstricmp(key, "oLossMax"))
{
oLossMax = param;
}
else if (!azstricmp(key, "iLossMin"))
{
iLossMin = param;
}
else if (!azstricmp(key, "iLossMax"))
{
iLossMax = param;
}
else if (!azstricmp(key, "oDropMin"))
{
oDropMin = param;
}
else if (!azstricmp(key, "oDropMax"))
{
oDropMax = param;
}
else if (!azstricmp(key, "oDropPeriodMin"))
{
oDropPeriodMin = param;
}
else if (!azstricmp(key, "oDropPeriodMax"))
{
oDropPeriodMax = param;
}
else if (!azstricmp(key, "iDropMin"))
{
iDropMin = param;
}
else if (!azstricmp(key, "iDropMax"))
{
iDropMax = param;
}
else if (!azstricmp(key, "iDropPeriodMin"))
{
iDropPeriodMin = param;
}
else if (!azstricmp(key, "iDropPeriodMax"))
{
iDropPeriodMax = param;
}
else if (!azstricmp(key, "oReorder"))
{
oReorder = param != 0;
}
else if (!azstricmp(key, "iReorder"))
{
iReorder = param != 0;
}
else
{
CryLogAlways("ERROR: Invalid argument: %s. Bailing out.", key);
return;
}
}
sim->SetOutgoingLatency(oLatMin, oLatMax);
sim->SetIncomingLatency(iLatMin, iLatMax);
sim->SetOutgoingBandwidth(oBandMin, oBandMax);
sim->SetIncomingBandwidth(iBandMin, iBandMax);
sim->SetOutgoingPacketLoss(oLossMin, oLossMax);
sim->SetIncomingPacketLoss(iLossMin, iLossMax);
sim->SetOutgoingPacketDrop(oDropMin, oDropMax, oDropPeriodMin, oDropPeriodMax);
sim->SetIncomingPacketDrop(iDropMin, iDropMax, iDropPeriodMin, iDropPeriodMax);
sim->SetOutgoingReorder(oReorder);
sim->SetIncomingReorder(iReorder);
CryLogAlways("Simulator settings:");
CryLogAlways("OutgoingLatency: (%u, %u)", oLatMin, oLatMax);
CryLogAlways("IncomingLatency: (%u, %u)", iLatMin, iLatMax);
CryLogAlways("OutgoingBandwidth: (%u, %u)", oBandMin, oBandMax);
CryLogAlways("IncomingBandwidth: (%u, %u)", iBandMin, iBandMax);
CryLogAlways("OutgoingPacketLoss: (%u, %u)", oLossMin, oLossMax);
CryLogAlways("IncomingPacketLoss: (%u, %u)", iLossMin, iLossMax);
CryLogAlways("OutgoingPacketDrop: (%u, %u, %u, %u)", oDropMin, oDropMax, oDropPeriodMin, oDropPeriodMax);
CryLogAlways("IncomingPacketDrop: (%u, %u, %u, %u)", iDropMin, iDropMax, iDropPeriodMin, iDropPeriodMax);
CryLogAlways("OutgoingReorder: %s", oReorder ? "on" : "off");
CryLogAlways("IncomingReorder: %s", iReorder ? "on" : "off");
}
else
{
CryLogAlways("Simulator is disabled.");
}
}
#if defined(NET_SUPPORT_SECURE_SOCKET_DRIVER)
void MultiplayerCVars::OnPrivateKeyChanged(ICVar* filename)
{
if (filename && filename->GetString() && filename->GetString()[0])
{
CreateFileDataSource();
EBUS_EVENT(CertificateManager::FileDataSourceConfigurationBus,ConfigurePrivateKey,filename->GetString());
}
else
{
AZ_Warning("CertificateManager", false, "Failed to load Private Key '%s'.", filename->GetString());
}
}
void MultiplayerCVars::OnCertificateChanged(ICVar* filename)
{
if (filename && filename->GetString() && filename->GetString()[0])
{
CreateFileDataSource();
EBUS_EVENT(CertificateManager::FileDataSourceConfigurationBus,ConfigureCertificate,filename->GetString());
}
else
{
AZ_Warning("CertificateManager", false, "Failed to load Certificate '%s'.", filename->GetString());
}
}
void MultiplayerCVars::OnCAChanged(ICVar* filename)
{
if (filename && filename->GetString() && filename->GetString()[0])
{
CreateFileDataSource();
EBUS_EVENT(CertificateManager::FileDataSourceConfigurationBus,ConfigureCertificateAuthority,filename->GetString());
}
else
{
AZ_Warning("CertificateManager", false, "Failed to load CA '%s'.", filename->GetString());
}
}
void MultiplayerCVars::CreateFileDataSource()
{
if (CertificateManager::FileDataSourceConfigurationBus::FindFirstHandler() == nullptr)
{
EBUS_EVENT(CertificateManager::FileDataSourceCreationBus,CreateFileDataSource);
if (CertificateManager::FileDataSourceConfigurationBus::FindFirstHandler() == nullptr)
{
AZ_Assert(false,"Unable to create File Data Source");
}
}
AZ_Assert(CertificateManager::FileDataSourceConfigurationBus::FindFirstHandler() != nullptr,"Incorrect DataSource configured for File Based CVars");
}
#endif
static void OnDisconnectDetectionChanged(ICVar* cvar)
{
GridMate::GridSession* session = nullptr;
EBUS_EVENT_RESULT(session,Multiplayer::MultiplayerRequestBus,GetSession);
if (!session)
{
return;
}
if (!session->IsHost())
{
CryLogAlways("Will not apply to the active session, only host can control disconnect detection mode for a game in progress.");
return;
}
session->DebugEnableDisconnectDetection(cvar->GetIVal() != 0);
}
static void OnReplicasSendTimeChanged(ICVar* cvar)
{
GridMate::GridSession* session = nullptr;
EBUS_EVENT_RESULT(session,Multiplayer::MultiplayerRequestBus,GetSession);
if (!session)
{
return;
}
session->GetReplicaMgr()->SetSendTimeInterval(cvar->GetIVal());
}
static void OnReplicasSendLimitChanged(ICVar* cvar)
{
GridMate::GridSession* session = nullptr;
EBUS_EVENT_RESULT(session,Multiplayer::MultiplayerRequestBus,GetSession);
if (!session)
{
return;
}
session->GetReplicaMgr()->SetSendLimit(cvar->GetIVal());
}
static void OnReplicasBurstRangeChanged(ICVar* cvar)
{
GridMate::GridSession* session = nullptr;
EBUS_EVENT_RESULT(session,Multiplayer::MultiplayerRequestBus,GetSession);
if (!session)
{
return;
}
session->GetReplicaMgr()->SetSendLimitBurstRange(cvar->GetFVal());
}
//-----------------------------------------------------------------------------
MultiplayerCVars* MultiplayerCVars::s_instance = nullptr;
//-----------------------------------------------------------------------------
MultiplayerCVars::MultiplayerCVars()
: m_autoJoin(false)
, m_search(nullptr)
{
s_instance = this;
}
//-----------------------------------------------------------------------------
MultiplayerCVars::~MultiplayerCVars()
{
if (s_instance == this)
{
s_instance = nullptr;
}
}
void MultiplayerCVars::VerifyMaxPlayers(ICVar* pVar)
{
int nPlayers = pVar->GetIVal();
if (nPlayers < 2 || nPlayers > MAXIMUM_NUMBER_OF_CONNECTIONS)
{
nPlayers = CLAMP(nPlayers, 2, MAXIMUM_NUMBER_OF_CONNECTIONS);
pVar->Set(nPlayers);
}
}
//------------------------------------------------------------------------
void MultiplayerCVars::RegisterCVars()
{
if (gEnv && !gEnv->IsEditor())
{
// Adding removed cvars from CryAction
if (gEnv->IsDedicated())
{
REGISTER_STRING("sv_map", "nolevel", 0, "The map the server should load");
REGISTER_STRING("sv_levelrotation", "levelrotation", 0, "Sequence of levels to load after each game ends");
REGISTER_STRING("sv_requireinputdevice", "dontcare", VF_DUMPTODISK | VF_REQUIRE_LEVEL_RELOAD, "Which input devices to require at connection (dontcare, none, gamepad, keyboard)");
REGISTER_STRING("sv_gamerulesdefault", "DummyRules", 0, "The game rules that the server default to when disconnecting");
REGISTER_STRING("sv_gamerules", "Multiplayer", 0, "The game rules that the server should use");
REGISTER_INT("sv_port", SERVER_DEFAULT_PORT, VF_DUMPTODISK, "Server address");
REGISTER_STRING("sv_password", "", VF_DUMPTODISK, "Server password");
REGISTER_INT("sv_lanonly", 0, VF_DUMPTODISK, "Set for LAN games");
REGISTER_STRING("sv_bind", "0.0.0.0", VF_REQUIRE_LEVEL_RELOAD, "Bind the server to a specific IP address");
REGISTER_STRING("sv_servername", "", VF_DUMPTODISK, "Server name will be displayed in server list. If empty, machine name will be used.");
REGISTER_INT_CB("sv_maxplayers", 32, VF_DUMPTODISK, "Maximum number of players allowed to join server.", VerifyMaxPlayers);
REGISTER_INT("sv_maxspectators", 32, VF_DUMPTODISK, "Maximum number of players allowed to be spectators during the game.");
REGISTER_INT("ban_timeout", 30, VF_DUMPTODISK, "Ban timeout in minutes");
REGISTER_FLOAT("sv_timeofdaylength", 1.0f, VF_DUMPTODISK, "Sets time of day changing speed.");
REGISTER_FLOAT("sv_timeofdaystart", 12.0f, VF_DUMPTODISK, "Sets time of day start time.");
REGISTER_INT("sv_timeofdayenable", 0, VF_DUMPTODISK, "Enables time of day simulation.");
}
REGISTER_COMMAND("mphost", MPHostLANCmd, 0, "begin hosting a LAN session");
REGISTER_COMMAND("mpjoin", MPJoinLANCmd, 0, "try to join a LAN session");
REGISTER_COMMAND("mpsearch", MPJoinLANCmd, 0, "try to find a LAN session");
REGISTER_COMMAND("mpdisconnect", MPDisconnectCmd, 0, "disconnect from our session");
REGISTER_INT("gm_version", 1, VF_CONST_CVAR, "Set the gridmate version number.");
#ifdef NET_SUPPORT_SECURE_SOCKET_DRIVER
REGISTER_CVAR2("gm_netsec_enable", &NetSec::s_NetsecEnabled, NetSec::s_NetsecEnabled, VF_NULL,
"Enable network level encryption. Must be called before hosting or joining a session (e.g. by using mphost or mpjoin).");
REGISTER_STRING_CB("gm_netsec_private_key", nullptr, VF_DEV_ONLY,
"Set the private key file (PEM format) to use when establishing a secure network connection.", OnPrivateKeyChanged);
REGISTER_STRING_CB("gm_netsec_certificate", nullptr, VF_DEV_ONLY,
"Set the certificate file (PEM format) to use when establishing a secure network connection.", OnCertificateChanged);
REGISTER_STRING_CB("gm_netsec_ca", nullptr, VF_DEV_ONLY,
"Set the CA certificate file (PEM format) to use when establishing a secure network connection.", OnCAChanged);
REGISTER_CVAR2("gm_netsec_verify_client", &NetSec::s_NetsecVerifyClient, NetSec::s_NetsecVerifyClient, VF_NULL,
"Enable client authentication. If not set only the server will be authenticated. Only needs to be called on the server!");
#endif
REGISTER_COMMAND("gm_net_simulator", CmdNetSimulator, VF_DEV_ONLY, "Setup network simulator. See 'gm_net_simulator help' for available options.");
REGISTER_INT_CB("gm_disconnectDetection", 1, VF_NULL, "GridMate disconnect detection.", OnDisconnectDetectionChanged);
REGISTER_FLOAT("gm_disconnectDetectionRttThreshold", 500.0f, VF_NULL, "Rtt threshold in milliseconds, connection will be dropped once actual rtt is bigger than this value");
REGISTER_FLOAT("gm_disconnectDetectionPacketLossThreshold", 0.3f, VF_NULL, "Packet loss percentage threshold (0.0..1.0, 1.0 is 100%), connection will be dropped once actual packet loss exceeds this value");
REGISTER_INT("gm_recvPacketsLimit", 0, VF_NULL, "Maximum packets per second allowed to be received from an existing connection");
REGISTER_INT("gm_maxSearchResults", GridMate::SearchParams::s_defaultMaxSessions, VF_NULL, "Maximum number of search results to be returned from a session search.");
REGISTER_STRING("gm_ipversion", "IPv4", 0, "IP protocol version. (Can be 'IPv4' or 'IPv6')");
REGISTER_STRING("gm_securityData", "", 0, AZ_TRAIT_MULTIPLAYER_REGISTER_CVAR_SECURITY_DATA_DESC);
REGISTER_INT_CB("gm_replicasSendTime", 0, VF_NULL, "Time interval between replicas sends (in milliseconds), 0 will bound sends to GridMate tick rate", OnReplicasSendTimeChanged);
REGISTER_INT_CB("gm_replicasSendLimit", 0, VF_DEV_ONLY, "Replica data send limit in bytes per second. 0 - limiter turned off. (Dev build only)", OnReplicasSendLimitChanged);
REGISTER_FLOAT_CB("gm_burstTimeLimit", 10.f, VF_DEV_ONLY, "Burst in bandwidth will be allowed for the given amount of time(in seconds). Burst will only be allowed if bandwidth is not capped at the time of burst. (Dev build only)", OnReplicasBurstRangeChanged);
#if AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS
REGISTER_STRING(AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE, "GroupBuildingLobby", 0, AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE_DESC);
REGISTER_STRING(AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID, "DefaultHopper", 0, AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID_DESC);
#endif
#if defined(BUILD_GAMELIFT_CLIENT)
REGISTER_STRING("gamelift_fleet_id", "", VF_DUMPTODISK, "Id of GameLift Fleet to use with this client.");
REGISTER_STRING("gamelift_queue_name", "", VF_DUMPTODISK, "Name of GameLift Queue to use with this client.");
REGISTER_STRING("gamelift_aws_access_key", "", VF_DUMPTODISK, "AWS Access Key.");
REGISTER_STRING("gamelift_aws_secret_key", "", VF_DUMPTODISK, "AWS Secret Key.");
REGISTER_STRING("gamelift_aws_region", "us-west-2", VF_DUMPTODISK, "AWS Region to use for GameLift.");
REGISTER_STRING("gamelift_endpoint", "gamelift.us-west-2.amazonaws.com", VF_DUMPTODISK, "GameLift service endpoint.");
REGISTER_STRING("gamelift_alias_id", "", VF_DUMPTODISK, "Id of GameLift alias to use with the client.");
REGISTER_STRING("gamelift_matchmaking_config_name", "", VF_DUMPTODISK, "Matchmaking config name");
REGISTER_INT("gamelift_uselocalserver", 0, VF_DEV_ONLY, "Set to non zero to use the local GameLift Server.");
REGISTER_COMMAND_DEV_ONLY("gamelift_host", MPHostGameLiftCmd, 0, "try to create and then join a GameLift session. gamelift_host <serverName> <mapName> <maxPlayers>");
REGISTER_COMMAND_DEV_ONLY("gamelift_join", MPJoinGameLiftCmd, 0, "try to join a GameLift session");
REGISTER_COMMAND_DEV_ONLY("gamelift_flexmatch", MPMatchmakingGameLiftCmd, 0, "try to matchmake a GameLift session creates or backfills matchmake game session. gamelift_flexmatch <configName>");
// player IDs must be unique and anonymous
bool includeBrackets = false;
bool includeDashes = true;
AZStd::string defaultPlayerId = AZ::Uuid::CreateRandom().ToString<AZStd::string>(includeBrackets, includeDashes);
REGISTER_STRING("gamelift_player_id", defaultPlayerId.c_str(), VF_DUMPTODISK, "Player Id.");
REGISTER_COMMAND("gamelift_stop_client", StopGameLiftClient, VF_NULL, "Stops GameLift session service and terminates the session if it had one.");
#endif
#if defined(BUILD_GAMELIFT_SERVER)
REGISTER_COMMAND("gamelift_start_server", StartGameLiftServer, VF_NULL, "Start up the GameLift server. This will initialize gameLift server API.\nThe session will start after GameLift initialization");
REGISTER_COMMAND("gamelift_stop_server", StopGameLiftServer, VF_NULL, "Stops GameLift session service and terminates the session if it had one.");
REGISTER_INT("gamelift_flexmatch_enable", 0, VF_NULL, "Enable Custom backfill");
REGISTER_INT("gamelift_flexmatch_onplayerremoved_enable", 0, VF_NULL, "Enables creating backfill tickets on player disconnect.");
REGISTER_INT("gamelift_flexmatch_minimumplayersessioncount", 2, VF_NULL, "Minimum player session count in a matchmaking config. Same as min players in matchmaking rule set");
REGISTER_FLOAT("gamlift_flexmatch_start_delay", 5.0F, VF_NULL, "initial delay for custom backfill in seconds.");
#endif
}
}
//------------------------------------------------------------------------
void MultiplayerCVars::UnregisterCVars()
{
if (gEnv && !gEnv->IsEditor())
{
#if defined(BUILD_GAMELIFT_CLIENT)
UNREGISTER_COMMAND("gamelift_start_client");
UNREGISTER_CVAR("gamelift_player_id");
UNREGISTER_CVAR("gamelift_alias_id");
UNREGISTER_CVAR("gamelift_uselocalserver");
UNREGISTER_CVAR("gamelift_endpoint");
UNREGISTER_CVAR("gamelift_aws_region");
UNREGISTER_CVAR("gamelift_aws_secret_key");
UNREGISTER_CVAR("gamelift_aws_access_key");
UNREGISTER_CVAR("gamelift_fleet_id");
UNREGISTER_CVAR("gamelift_queue_name");
UNREGISTER_CVAR("gamelift_matchmaking_config_name");
#endif
#if defined(BUILD_GAMELIFT_SERVER)
UNREGISTER_COMMAND("gamelift_stop_server");
UNREGISTER_COMMAND("gamelift_start_server");
UNREGISTER_COMMAND("gamelift_flexmatch_enable");
UNREGISTER_COMMAND("gamelift_flexmatch_onplayerremoved_enable");
UNREGISTER_COMMAND("gamelift_flexmatch_minimumplayersessioncount");
UNREGISTER_COMMAND("gamlift_flexmatch_start_delay");
#endif
#if AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS
UNREGISTER_CVAR(AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID);
UNREGISTER_CVAR(AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE);
#endif
UNREGISTER_CVAR("gm_burstTimeLimit");
UNREGISTER_CVAR("gm_replicasSendLimit");
UNREGISTER_CVAR("gm_replicasSendTime");
UNREGISTER_CVAR("gm_securityData");
UNREGISTER_CVAR("gm_ipversion");
UNREGISTER_CVAR("gm_maxSearchResults");
UNREGISTER_CVAR("gm_disconnectDetectionPacketLossThreshold");
UNREGISTER_CVAR("gm_disconnectDetectionRttThreshold");
UNREGISTER_CVAR("gm_disconnectDetection");
UNREGISTER_COMMAND("gm_net_simulator");
#ifdef NET_SUPPORT_SECURE_SOCKET_DRIVER
UNREGISTER_CVAR("gm_netsec_ca");
UNREGISTER_CVAR("gm_netsec_certificate");
UNREGISTER_CVAR("gm_netsec_private_key");
UNREGISTER_CVAR("gm_netsec_enable");
#endif
UNREGISTER_CVAR("gm_version");
UNREGISTER_COMMAND("mpdisconnect");
UNREGISTER_COMMAND("mpsearch");
UNREGISTER_COMMAND("mpjoin");
UNREGISTER_COMMAND("mphost");
{
gEnv->pConsole->RemoveCommand("mpdisconnect");
gEnv->pConsole->RemoveCommand("mpsearch");
gEnv->pConsole->RemoveCommand("mpjoin");
gEnv->pConsole->RemoveCommand("mphost");
}
}
}
//------------------------------------------------------------------------
static void UpdateServerName(ICVar* serverNameCVar)
{
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession,Multiplayer::MultiplayerRequestBus,GetSession);
if (!(gridSession && gridSession->IsHost()))
{
return;
}
AZ_TracePrintf("MultiplayerModule", "Updating session server name to: %s", serverNameCVar->GetString());
GridMate::GridSessionParam serverNameParam;
serverNameParam.m_id = "sv_name";
serverNameParam.SetValue(serverNameCVar->GetString());
gridSession->SetParam(serverNameParam);
}
//------------------------------------------------------------------------
// It would be more convenient to setup this CVar change event listener in RegisterCVars, however,
// it is currently not possible to do so. This is due to Gem CVars being registered in response to
// CryHooksModule::OnCrySystemInitialized, while CryAction CVars (such as sv_servername) are not registered
// until after that event completes. Instead, this method is called during the system event
// ESYSTEM_EVENT_GAME_POST_INIT, which does occur after CryAction's CVars have been registered.
void MultiplayerCVars::PostInitRegistration()
{
ISystem* system = nullptr;
CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem);
if (system && system->GetIConsole())
{
if (ICVar* serverNameCVar = system->GetIConsole()->GetCVar("sv_servername"))
{
SFunctor onServerNameChange;
onServerNameChange.Set(UpdateServerName, serverNameCVar);
serverNameCVar->AddOnChangeFunctor(onServerNameChange);
}
}
}
//------------------------------------------------------------------------
void MultiplayerCVars::MPHostLANCmd(IConsoleCmdArgs* args)
{
(void)args;
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (!gridMate)
{
CryLogAlways("GridMate has not been initialized.");
return;
}
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession,Multiplayer::MultiplayerRequestBus,GetSession);
if (gridSession)
{
CryLogAlways("You're already part of a session. Use 'mpdisconnect' first.");
return;
}
if (!GridMate::HasGridMateService<GridMate::LANSessionService>(gridMate))
{
Multiplayer::LAN::StartSessionService(gridMate);
}
// Attempt to start a hosted LAN session. If we do, we're now a server and in multiplayer mode.
GridMate::LANSessionParams sp;
sp.m_topology = GridMate::ST_CLIENT_SERVER;
sp.m_numPublicSlots = gEnv->pConsole->GetCVar("sv_maxplayers")->GetIVal() + (gEnv->IsDedicated() ? 1 : 0); // One slot for server member.
sp.m_numPrivateSlots = 0;
sp.m_port = gEnv->pConsole->GetCVar("sv_port")->GetIVal() + 1; // Listen for searches on sv_port + 1
sp.m_peerToPeerTimeout = 60000;
sp.m_flags = 0;
sp.m_numParams = 0;
ICVar* serverName = gEnv->pConsole->GetCVar("sv_servername");
if (serverName)
{
sp.m_params[sp.m_numParams].m_id = "sv_name";
sp.m_params[sp.m_numParams].SetValue(serverName->GetString());
sp.m_numParams++;
}
GridMate::CarrierDesc carrierDesc;
Multiplayer::Utils::InitCarrierDesc(carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForHost(carrierDesc);
carrierDesc.m_port = static_cast<uint16>(gEnv->pConsole->GetCVar("sv_port")->GetIVal());
carrierDesc.m_enableDisconnectDetection = !!gEnv->pConsole->GetCVar("gm_disconnectDetection")->GetIVal();
carrierDesc.m_connectionTimeoutMS = 10000;
carrierDesc.m_threadUpdateTimeMS = 30;
carrierDesc.m_disconnectDetectionRttThreshold = gEnv->pConsole->GetCVar("gm_disconnectDetectionRttThreshold")->GetFVal();
carrierDesc.m_disconnectDetectionPacketLossThreshold = gEnv->pConsole->GetCVar("gm_disconnectDetectionPacketLossThreshold")->GetFVal();
carrierDesc.m_maxConnections = gEnv->pConsole->GetCVar("sv_maxplayers")->GetIVal();
carrierDesc.m_recvPacketsLimit = gEnv->pConsole->GetCVar("gm_recvPacketsLimit")->GetIVal();
GridMate::GridSession* session = nullptr;
EBUS_EVENT_ID_RESULT(session,gridMate,GridMate::LANSessionServiceBus,HostSession,sp,carrierDesc);
if (session)
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus,RegisterSession,session);
}
}
//------------------------------------------------------------------------
void MultiplayerCVars::MPJoinLANCmd(IConsoleCmdArgs* args)
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (!gridMate)
{
CryLogAlways("GridMate has not been initialized.");
return;
}
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession,Multiplayer::MultiplayerRequestBus,GetSession);
if (gridSession)
{
CryLogAlways("You're already part of a session. Use 'mpdisconnect' first.");
return;
}
if (GridMate::LANSessionServiceBus::FindFirstHandler(gridMate) == nullptr)
{
Multiplayer::LAN::StartSessionService(gridMate);
}
// Parse optional arguments
if (args->GetArgCount() > 1)
{
gEnv->pConsole->GetCVar("cl_serveraddr")->Set(args->GetArg(1));
// check if a port was provided
if (args->GetArgCount()>2)
{
gEnv->pConsole->GetCVar("cl_serverport")->Set(args->GetArg(2));
}
}
const char* serveraddr = gEnv->pConsole->GetCVar("cl_serveraddr")->GetString();
// LANSession doesn't support names. At least handle localhost here.
if (!serveraddr || 0 == azstricmp("localhost", serveraddr))
{
serveraddr = "127.0.0.1";
}
const bool autoJoin = (nullptr != CryStringUtils::stristr(args->GetArg(0), "join"));
CryLogAlways("Attempting to '%s' server with search key \"%s\"...",
args->GetArg(0), serveraddr);
// Attempt to join the session at the specified address. Should we succeed, we're
// now a client and in multiplayer mode.
s_instance->BusConnect(gridMate);
s_instance->m_autoJoin = autoJoin;
GridMate::LANSearchParams searchParams;
searchParams.m_serverAddress = serveraddr;
searchParams.m_serverPort = gEnv->pConsole->GetCVar("cl_serverport")->GetIVal() + 1;
searchParams.m_version = gEnv->pConsole->GetCVar("gm_version")->GetIVal();
searchParams.m_listenPort = 0; // Always use ephemeral port for searches for the time being, until we change the API to allow users to customize this.
s_instance->m_search = nullptr;
EBUS_EVENT_ID_RESULT(s_instance->m_search,gridMate,GridMate::LANSessionServiceBus,StartGridSearch,searchParams);
}
#if defined(BUILD_GAMELIFT_CLIENT)
//------------------------------------------------------------------------
void MultiplayerCVars::MPHostGameLiftCmd(IConsoleCmdArgs* args)
{
if (args->GetArgCount() != 4)
{
AZ_TracePrintf("MultiplayerModule", "gamelift_host: Invalid number of arguments.");
return;
}
const char* serverName = args->GetArg(1);
const char* mapName = args->GetArg(2);
AZ::u32 maxPlayers = strtoul(args->GetArg(3), nullptr, 0);
if (maxPlayers == 0 || maxPlayers == std::numeric_limits<AZ::u32>::max())
{
AZ_TracePrintf("MultiplayerModule", "Invalid value for maxPlayers");
return;
}
MultiplayerGameLiftClientBus::Broadcast(
&MultiplayerGameLiftClientBus::Events::HostGameLiftSession, serverName, mapName, maxPlayers);
}
//------------------------------------------------------------------------
void MultiplayerCVars::MPJoinGameLiftCmd(IConsoleCmdArgs* args)
{
AZ_UNUSED(args);
MultiplayerGameLiftClientBus::Broadcast(
&MultiplayerGameLiftClientBus::Events::JoinGameLiftSession);
}
//------------------------------------------------------------------------
void MultiplayerCVars::StopGameLiftClient(IConsoleCmdArgs *args)
{
AZ_UNUSED(args);
MultiplayerGameLiftClientBus::Broadcast(
&MultiplayerGameLiftClientBus::Events::StopGameLiftClientService);
}
//------------------------------------------------------------------------
void MultiplayerCVars::MPMatchmakingGameLiftCmd(IConsoleCmdArgs *args)
{
if (args->GetArgCount() != 2)
{
AZ_TracePrintf("MultiplayerModule", "gamelift_flexmatch: Invalid number of arguments. Expected gamelift_flexmatch <configName>");
return;
}
const char* configName = args->GetArg(1);
MultiplayerGameLiftClientBus::Broadcast(
&MultiplayerGameLiftClientBus::Events::StartGameLiftMatchmaking, configName);
}
#endif
//------------------------------------------------------------------------
void MultiplayerCVars::MPDisconnectCmd(IConsoleCmdArgs* args)
{
(void)args;
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession,Multiplayer::MultiplayerRequestBus,GetSession);
if (!gridSession)
{
CryLogAlways("You're not in any MP session.");
return;
}
gridSession->Leave(false);
}
//------------------------------------------------------------------------
void MultiplayerCVars::OnGridSearchComplete(GridMate::GridSearch* search)
{
if (search == m_search)
{
m_search = nullptr;
GridMate::SessionEventBus::Handler::BusDisconnect();
if (m_autoJoin)
{
m_autoJoin = false;
if (search->GetNumResults() > 0)
{
const GridMate::SearchInfo* searchInfo = search->GetResult(0);
GridMate::GridSession* session = nullptr;
GridMate::CarrierDesc carrierDesc;
Multiplayer::Utils::InitCarrierDesc(carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForJoin(carrierDesc);
GridMate::JoinParams joinParams;
const GridMate::LANSearchInfo& lanSearchInfo = static_cast<const GridMate::LANSearchInfo&>((*searchInfo));
EBUS_EVENT_ID_RESULT(session,gEnv->pNetwork->GetGridMate(),GridMate::LANSessionServiceBus,JoinSessionBySearchInfo,lanSearchInfo,joinParams,carrierDesc);
if (session != nullptr)
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus,RegisterSession,session);
CryLogAlways("Successfully joined game session.");
}
else
{
CryLogAlways("Found a game session, but failed to join.");
}
}
else
{
CryLogAlways("No game sessions found.");
}
}
}
}
} // namespace Multiplayer
@@ -0,0 +1,100 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#ifndef INCLUDE_MULTIPLAYERCVARS_HEADER
#define INCLUDE_MULTIPLAYERCVARS_HEADER
#include <MultiplayerGameLiftClient.h>
#include <INetwork.h>
#include <CertificateManager/ICertificateManagerGem.h>
#include <GridMate/Session/Session.h>
struct IConsole;
struct IConsoleCmdArgs;
namespace GridMate
{
class GridSearch;
}
namespace CertificateManager
{
class FileDataSource;
}
namespace Multiplayer
{
/*!
* GridMate-specific network cvars.
*/
class MultiplayerCVars
: public GridMate::SessionEventBus::Handler
{
public:
MultiplayerCVars();
~MultiplayerCVars();
void RegisterCVars();
void UnregisterCVars();
void PostInitRegistration();
private:
//! Host a session (LAN).
static void MPHostLANCmd(IConsoleCmdArgs* args);
//! Attempt to join an existing session (LAN).
static void MPJoinLANCmd(IConsoleCmdArgs* args);
#if defined(BUILD_GAMELIFT_CLIENT)
//! Attempt to host a session on GameLift and join it.
static void MPHostGameLiftCmd(IConsoleCmdArgs* args);
//! Attempt to join an existing GameLift session.
static void MPJoinGameLiftCmd(IConsoleCmdArgs* args);
static void StopGameLiftClient(IConsoleCmdArgs* args);
static void MPMatchmakingGameLiftCmd(IConsoleCmdArgs* args);
#endif
//! Shut down current server or client session.
static void MPDisconnectCmd(IConsoleCmdArgs* args);
static void VerifyMaxPlayers(ICVar* pVar);
private:
void OnGridSearchComplete(GridMate::GridSearch* gridSearch) override;
#if defined(NET_SUPPORT_SECURE_SOCKET_DRIVER)
static void OnPrivateKeyChanged(ICVar* cvar);
static void OnCertificateChanged(ICVar* cvar);
static void OnCAChanged(ICVar* cvar);
static void CreateFileDataSource();
#endif
bool m_autoJoin;
GridMate::GridSearch* m_search;
#if defined(BUILD_GAMELIFT_CLIENT)
MultiplayerGameLiftClient m_gameLift;
#endif
static MultiplayerCVars* s_instance;
};
} // namespace GridMate
#endif // INCLUDE_NETWORKGRIDMATECVARS_HEADER
@@ -0,0 +1,203 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Multiplayer/MultiplayerEventsComponent.h"
#include "Multiplayer/BehaviorContext/GridSystemContext.h"
#include <AzCore/Serialization/SerializeContext.h>
#include <GridMate/NetworkGridMate.h>
#include <GridMate/NetworkGridMateSessionEvents.h>
#include <GridMate/Session/Session.h>
#include <GridMate/Online/UserServiceTypes.h>
#include <AzFramework/Network/NetBindingHandlerBus.h>
#include <Multiplayer_Traits_Platform.h>
namespace Multiplayer
{
///////////////////////////////////
// SessionEventBusBehaviorHandler
///////////////////////////////////
void SessionEventBusBehaviorHandler::OnSessionServiceReady()
{
Call(FN_OnSessionServiceReady);
}
void SessionEventBusBehaviorHandler::OnSessionCreated(GridMate::GridSession* gs)
{
Call(FN_OnSessionCreated, gs);
}
void SessionEventBusBehaviorHandler::OnSessionDelete(GridMate::GridSession* gs)
{
Call(FN_OnSessionDelete, gs);
}
void SessionEventBusBehaviorHandler::OnMemberJoined(GridMate::GridSession* gs, GridMate::GridMember* member)
{
Call(FN_OnMemberJoined, gs, member);
}
void SessionEventBusBehaviorHandler::OnMemberLeaving(GridMate::GridSession* gs, GridMate::GridMember* member)
{
Call(FN_OnMemberLeaving, gs, member);
}
void SessionEventBusBehaviorHandler::OnMemberKicked(GridMate::GridSession* gs, GridMate::GridMember* member, AZ::u8 kickreason)
{
Call(FN_OnMemberKicked, gs, member, kickreason);
}
void SessionEventBusBehaviorHandler::OnSessionJoined(GridMate::GridSession* gs)
{
Call(FN_OnSessionJoined, gs);
}
void SessionEventBusBehaviorHandler::OnSessionStart(GridMate::GridSession* gs)
{
Call(FN_OnSessionStart, gs);
}
void SessionEventBusBehaviorHandler::OnSessionEnd(GridMate::GridSession* gs)
{
Call(FN_OnSessionEnd, gs);
}
void SessionEventBusBehaviorHandler::OnSessionError(GridMate::GridSession* gs, const GridMate::string& msg)
{
Call(FN_OnSessionError, gs, msg);
}
///////////////////////////////
// MultiplayerEventsComponent
///////////////////////////////
void MultiplayerEventsComponent::Init()
{
}
void MultiplayerEventsComponent::Activate()
{
}
void MultiplayerEventsComponent::Deactivate()
{
}
/**
* helper class to allow a constructor and destructor for MultiplayerEventsComponent
*/
struct InternalMultiplayerEvents
: public SessionEventBusBehaviorHandler
{
InternalMultiplayerEvents()
{
AZ_Assert(gEnv->pNetwork, "gEnv->pNetwork is nullptr");
AZ_Assert(gEnv->pNetwork->GetGridMate(), "GridMate is nullptr");
GridMate::SessionEventBus::Handler::BusConnect(gEnv->pNetwork->GetGridMate());
}
~InternalMultiplayerEvents()
{
GridMate::SessionEventBus::Handler::BusDisconnect();
}
bool Connect(AZ::BehaviorValueParameter* id) override
{
AZ_UNUSED(id);
AZ::BehaviorValueParameter thisGridMate(gEnv->pNetwork->GetGridMate());
return AZ::Internal::EBusConnector<InternalMultiplayerEvents>::Connect(this, &thisGridMate);
}
};
/**
* helper functions to wrap a naked GridMate::PlayerId pointer
* Note: it is valid for the GridMember to return a nullptr PlayerId for LAN connections
*/
struct GridMatePlayerId
{
static GridMate::gridmate_string ToString(GridMate::PlayerId* playerId)
{
if (playerId)
{
return playerId->ToString();
}
static GridMate::gridmate_string s_blank("NOT_SUPPORTED");
return s_blank;
}
static GridMate::ServiceType GetType(GridMate::PlayerId* playerId)
{
if (playerId)
{
return playerId->GetType();
}
return GridMate::ST_MAX;
}
};
void MultiplayerEventsComponent::Reflect(AZ::ReflectContext* reflectContext)
{
GridMateSystemContext::Reflect(reflectContext);
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(reflectContext))
{
serializeContext->Class<MultiplayerEventsComponent, AZ::Component>()
->Version(1);
}
AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(reflectContext);
if (behaviorContext)
{
behaviorContext->EBus<GridMate::SessionEventBus>("MultiplayerEvents")
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Handler<InternalMultiplayerEvents>()
;
behaviorContext->Class<GridMate::GridSession>()
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::RuntimeOwn)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Method("IsHost", &GridMate::GridSession::IsHost)
->Method("IsReady", &GridMate::GridSession::IsReady)
->Method("GetNumberOfMembers", &GridMate::GridSession::GetNumberOfMembers)
->Method("Leave", &GridMate::GridSession::Leave)
;
behaviorContext->Class<GridMate::GridMember>()
->Attribute(AZ::Script::Attributes::Storage, AZ::Script::Attributes::StorageType::RuntimeOwn)
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Method("GetName", &GridMate::GridMember::GetName)
->Method("IsHost", &GridMate::GridMember::IsHost)
->Method("IsLocal", &GridMate::GridMember::IsLocal)
->Method("IsInvited", &GridMate::GridMember::IsInvited)
->Method("IsReady", &GridMate::GridMember::IsReady)
->Method("IsTalking", &GridMate::GridMember::IsTalking)
->Method("GetPlayerId", &GridMate::GridMember::GetPlayerId)
;
behaviorContext->Class<GridMate::PlayerId>()
->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List)
->Property("playerId", &GridMatePlayerId::ToString, nullptr)
->Property("type", &GridMatePlayerId::GetType, nullptr)
;
// GridMate::ServiceType
behaviorContext
->Enum<GridMate::ST_LAN>("ST_LAN")
#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\
->Enum<GridMate::ST_##CODENAME>("ST_"#CODENAME)
AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS
#undef AZ_RESTRICTED_PLATFORM_EXPANSION
#endif
->Enum<GridMate::ST_STEAM>("ST_STEAM")
;
behaviorContext->Class<AzFramework::NetQuery>("NetQuery")
->Method("IsEntityAuthoritative", &AzFramework::NetQuery::IsEntityAuthoritative)
;
}
}
}
@@ -0,0 +1,389 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Multiplayer_precompiled.h>
#include "MultiplayerGameLiftClient.h"
#include <GameLift/Session/GameLiftClientService.h>
#include <GameLift/Session/GameLiftSearch.h>
#include <GameLift/Session/GameLiftSessionRequest.h>
#include <CrySystemBus.h>
#include <INetwork.h>
#include <Multiplayer/MultiplayerUtils.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_CLIENT)
static const char* GameLiftSessionAlreadyConnectedErrorMessage = "Already connected to a session. Use 'mpdisconnect' to leave current session";
MultiplayerGameLiftClient::MultiplayerGameLiftClient()
: m_mode(Mode::None)
, m_serviceStatus(ServiceStatus::Stopped)
, m_console(nullptr)
, m_gridMate(nullptr)
, m_search(nullptr)
, m_maxPlayers(0)
{
MultiplayerGameLiftClientBus::Handler::BusConnect();
}
MultiplayerGameLiftClient::~MultiplayerGameLiftClient()
{
MultiplayerGameLiftClientBus::Handler::BusDisconnect();
}
void MultiplayerGameLiftClient::HostGameLiftSession(const char* serverName, const char* mapName,
const AZ::u32 maxPlayers)
{
GridMate::GridSession* session = nullptr;
MultiplayerRequestBus::BroadcastResult(session, &MultiplayerRequestBus::Events::GetSession);
if (session)
{
AZ_TracePrintf("MultiplayerModule", GameLiftSessionAlreadyConnectedErrorMessage);
return;
}
if (m_serviceStatus == ServiceStatus::Starting)
{
AZ_TracePrintf("MultiplayerModule", "GameLift client service startup is already in-progress");
return;
}
m_mode = Mode::Host;
m_serverName = serverName;
m_mapName = mapName;
m_maxPlayers = maxPlayers;
if (m_serviceStatus == ServiceStatus::Stopped)
{
StartGameLiftClientService();
}
else
{
HandleGameLiftRequestByMode();
}
}
void MultiplayerGameLiftClient::JoinGameLiftSession()
{
GridMate::GridSession* session = nullptr;
MultiplayerRequestBus::BroadcastResult(session, &MultiplayerRequestBus::Events::GetSession);
if (session)
{
AZ_TracePrintf("MultiplayerModule", GameLiftSessionAlreadyConnectedErrorMessage);
return;
}
if (m_serviceStatus == ServiceStatus::Starting)
{
AZ_TracePrintf("MultiplayerModule", "GameLift client service startup is already in-progress");
return;
}
m_mode = Mode::Join;
if (m_serviceStatus == ServiceStatus::Stopped)
{
StartGameLiftClientService();
}
else
{
HandleGameLiftRequestByMode();
}
}
void MultiplayerGameLiftClient::StartGameLiftMatchmaking(const char* matchmakingConfigName)
{
GridMate::GridSession* session = nullptr;
MultiplayerRequestBus::BroadcastResult(session, &MultiplayerRequestBus::Events::GetSession);
if (session)
{
AZ_TracePrintf("MultiplayerModule", GameLiftSessionAlreadyConnectedErrorMessage);
return;
}
if (m_serviceStatus == ServiceStatus::Starting)
{
AZ_TracePrintf("MultiplayerModule", "GameLift client service startup is already in-progress");
return;
}
m_mode = Mode::FlexMatch;
m_matchmakingConfigName = matchmakingConfigName;
if (m_serviceStatus == ServiceStatus::Stopped)
{
StartGameLiftClientService();
}
else
{
HandleGameLiftRequestByMode();
}
}
void MultiplayerGameLiftClient::StopGameLiftClientService()
{
GameLift::GameLiftRequestBus::Broadcast(&GameLift::GameLiftRequestBus::Events::StopClientService);
m_serviceStatus = ServiceStatus::Stopped;
}
IConsole* MultiplayerGameLiftClient::GetConsole()
{
if (!m_console)
{
ISystem* system = nullptr;
CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem);
if (system)
{
m_console = system->GetIConsole();
}
}
return m_console;
}
GridMate::IGridMate* MultiplayerGameLiftClient::GetGridMate()
{
if (!m_gridMate)
{
ISystem* system = nullptr;
CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem);
if (system && system->GetINetwork())
{
m_gridMate = system->GetINetwork()->GetGridMate();
}
}
return m_gridMate;
}
const char* MultiplayerGameLiftClient::GetConsoleParam(const char* paramName)
{
const char* value = "";
IConsole* console = GetConsole();
if (console)
{
ICVar* cvar = console->GetCVar(paramName);
if (cvar)
{
value = cvar->GetString();
}
}
else
{
AZ_TracePrintf("MultiplayerModule", "Console has not been initialized.");
}
return value;
}
const bool MultiplayerGameLiftClient::GetConsoleBoolParam(const char* paramName)
{
bool value = false;
IConsole* console = GetConsole();
if (console)
{
ICVar* cvar = GetConsole()->GetCVar(paramName);
value = cvar && cvar->GetI64Val();
}
else
{
AZ_TracePrintf("MultiplayerModule", "Console has not been initialized.");
}
return value;
}
void MultiplayerGameLiftClient::AddRequestParameter(GridMate::GameLiftSessionRequestParams& params,
const char* name, const char* value)
{
if (params.m_numParams < params.k_maxNumParams)
{
params.m_params[params.m_numParams].m_id = name;
params.m_params[params.m_numParams].m_value = value;
params.m_numParams++;
}
else
{
AZ_TracePrintf("MultiplayerModule", "Failed to add parameter to request; request contains maximum number of parameters.");
}
}
void MultiplayerGameLiftClient::StartGameLiftClientService()
{
GridMate::IGridMate* gridMate = GetGridMate();
if (!gridMate)
{
AZ_TracePrintf("MultiplayerModule", "GridMate has not been initialized.");
return;
}
bool netSecEnabled = false;
MultiplayerRequestBus::BroadcastResult(netSecEnabled, &MultiplayerRequestBus::Events::IsNetSecEnabled);
if (netSecEnabled)
{
if (!Multiplayer::NetSec::CanCreateSecureSocketForJoining())
{
m_serviceStatus = ServiceStatus::Stopped;
AZ_TracePrintf("MultiplayerModule", "Invalid Secure Socket Configuration.");
return;
}
}
GridMate::GameLiftClientServiceEventsBus::Handler::BusConnect(gridMate);
GridMate::GameLiftClientServiceDesc serviceDesc;
serviceDesc.m_accessKey = GetConsoleParam("gamelift_aws_access_key");
serviceDesc.m_secretKey = GetConsoleParam("gamelift_aws_secret_key");
serviceDesc.m_endpoint = GetConsoleParam("gamelift_endpoint");
serviceDesc.m_region = GetConsoleParam("gamelift_aws_region");
serviceDesc.m_playerId = GetConsoleParam("gamelift_player_id");
serviceDesc.m_useGameLiftLocalServer = GetConsoleBoolParam("gamelift_uselocalserver");
m_serviceStatus = ServiceStatus::Starting;
GameLift::GameLiftRequestBus::Broadcast(
&GameLift::GameLiftRequestBus::Events::StartClientService, serviceDesc);
}
void MultiplayerGameLiftClient::HostGameLiftSessionInternal()
{
GridMate::GameLiftSessionRequestParams params;
params.m_instanceName = m_serverName;
params.m_numPublicSlots = m_maxPlayers;
params.m_numParams = 0;
AddRequestParameter(params, "sv_name", m_serverName.c_str());
AddRequestParameter(params, "sv_map", m_mapName.c_str());
params.m_fleetId = GetConsoleParam("gamelift_fleet_id");
params.m_aliasId = GetConsoleParam("gamelift_alias_id");
params.m_queueName = GetConsoleParam("gamelift_queue_name");
params.m_useFleetId = !params.m_fleetId.empty();
GridMate::GameLiftClientServiceBus::BroadcastResult(m_search,
&GridMate::GameLiftClientServiceBus::Events::RequestSession, params);
}
void MultiplayerGameLiftClient::StartGameLiftMatchmakingInternal()
{
GridMate::GameLiftClientServiceBus::BroadcastResult(m_search,
&GridMate::GameLiftClientServiceBus::Events::StartMatchmaking, m_matchmakingConfigName);
}
void MultiplayerGameLiftClient::JoinGameLiftSessionInternal(const GridMate::GameLiftSearchInfo& searchInfo)
{
GridMate::GridSession* session = nullptr;
MultiplayerRequestBus::BroadcastResult(session, &MultiplayerRequestBus::Events::GetSession);
if (session)
{
AZ_TracePrintf("MultiplayerModule", GameLiftSessionAlreadyConnectedErrorMessage);
}
GridMate::CarrierDesc carrierDesc;
Multiplayer::Utils::InitCarrierDesc(carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForJoin(carrierDesc);
GridMate::GameLiftClientServiceBus::BroadcastResult(session,
&GridMate::GameLiftClientServiceBus::Events::JoinSessionBySearchInfo, searchInfo, carrierDesc);
if (session)
{
MultiplayerRequestBus::Broadcast(&MultiplayerRequestBus::Events::RegisterSession, session);
}
else
{
AZ_TracePrintf("MultiplayerModule", "Failed to create GameLift session.");
Multiplayer::NetSec::OnSessionFailedToCreate(carrierDesc);
}
}
void MultiplayerGameLiftClient::QueryGameLiftServers()
{
m_search = nullptr;
GridMate::GameLiftSearchParams searchParams;
searchParams.m_fleetId = GetConsoleParam("gamelift_fleet_id");
searchParams.m_aliasId = GetConsoleParam("gamelift_alias_id");
searchParams.m_queueName = GetConsoleParam("gamelift_queue_name");
searchParams.m_useFleetId = !searchParams.m_fleetId.empty();
GridMate::GameLiftClientServiceBus::BroadcastResult(m_search,
&GridMate::GameLiftClientServiceBus::Events::StartSearch, searchParams);
if (m_search == nullptr)
{
AZ_TracePrintf("MultiplayerModule", "Failed to start a GridSearch");
}
}
void MultiplayerGameLiftClient::HandleGameLiftRequestByMode()
{
GridMate::SessionEventBus::Handler::BusConnect(GetGridMate());
switch (m_mode)
{
case Mode::Join:
QueryGameLiftServers();
break;
case Mode::Host:
HostGameLiftSessionInternal();
break;
case Mode::FlexMatch:
StartGameLiftMatchmakingInternal();
break;
default:
break;
}
}
void MultiplayerGameLiftClient::OnGameLiftSessionServiceReady(GridMate::GameLiftClientService*)
{
GridMate::GameLiftClientServiceEventsBus::Handler::BusDisconnect();
m_serviceStatus = ServiceStatus::Started;
HandleGameLiftRequestByMode();
}
void MultiplayerGameLiftClient::OnGameLiftSessionServiceFailed(GridMate::GameLiftClientService*, [[maybe_unused]] const AZStd::string& message)
{
GridMate::GameLiftClientServiceEventsBus::Handler::BusDisconnect();
AZ_TracePrintf("MultiplayerModule", "GameLift Error: %s", message.c_str());
StopGameLiftClientService();
}
void MultiplayerGameLiftClient::OnGridSearchComplete(GridMate::GridSearch* gridSearch)
{
// When connecting the SessionEventBus, we will be notified when any grid search completes.
// This check ensures that we are only handling grid searches that we initiated (which populate m_search).
if (gridSearch != m_search)
{
return;
}
if (m_search->GetNumResults() == 0)
{
AZ_TracePrintf("MultiplayerModule", "GridSearch returned no results.");
return;
}
const GridMate::GameLiftSearchInfo& gameliftSearchInfo =
static_cast<const GridMate::GameLiftSearchInfo&>(*m_search->GetResult(0));
JoinGameLiftSessionInternal(gameliftSearchInfo);
m_search->Release();
m_search = nullptr;
GridMate::SessionEventBus::Handler::BusDisconnect(GetGridMate());
}
#endif
}
@@ -0,0 +1,105 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_precompiled.h>
#include <GameLift/Session/GameLiftClientService.h>
#include <GameLift/GameLiftBus.h>
#include <Multiplayer/MultiplayerUtils.h>
namespace Multiplayer
{
#if defined(BUILD_GAMELIFT_CLIENT)
class MultiplayerGameLiftClientRequests : public AZ::EBusTraits
{
public:
// EBus Configuration
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
virtual ~MultiplayerGameLiftClientRequests() = default;
// Handler Interface
virtual void HostGameLiftSession(const char* serverName, const char* mapName, const AZ::u32 maxPlayers) = 0;
virtual void JoinGameLiftSession() = 0;
virtual void StopGameLiftClientService() = 0;
virtual void StartGameLiftMatchmaking(const char* matchmakingConfigName) = 0;
};
using MultiplayerGameLiftClientBus = AZ::EBus<MultiplayerGameLiftClientRequests>;
class MultiplayerGameLiftClient
: public MultiplayerGameLiftClientBus::Handler
, public GridMate::GameLiftClientServiceEventsBus::Handler
, public GridMate::SessionEventBus::Handler
{
public:
MultiplayerGameLiftClient();
virtual ~MultiplayerGameLiftClient();
// MultiplayerGameLiftClientBus
void HostGameLiftSession(const char* serverName, const char* mapName, const AZ::u32 maxPlayers) override;
void JoinGameLiftSession() override;
void StopGameLiftClientService() override;
void StartGameLiftMatchmaking(const char* matchmakingConfigName) override;
private:
enum class Mode
{
None,
Join,
Host,
FlexMatch
};
enum class ServiceStatus
{
Stopped,
Starting,
Started,
};
virtual IConsole* GetConsole();
virtual GridMate::IGridMate* GetGridMate();
const char* GetConsoleParam(const char* paramName);
const bool GetConsoleBoolParam(const char* paramName);
void AddRequestParameter(GridMate::GameLiftSessionRequestParams& params, const char* name, const char* value);
void StartGameLiftClientService();
void HostGameLiftSessionInternal();
void JoinGameLiftSessionInternal(const GridMate::GameLiftSearchInfo& searchInfo);
void QueryGameLiftServers();
void HandleGameLiftRequestByMode();
void StartGameLiftMatchmakingInternal();
// GameLiftClientServiceEventsBus
void OnGameLiftSessionServiceReady(GridMate::GameLiftClientService*) override;
void OnGameLiftSessionServiceFailed(GridMate::GameLiftClientService*, const AZStd::string& message) override;
// SessionEventBus
void OnGridSearchComplete(GridMate::GridSearch* gridSearch) override;
Mode m_mode;
ServiceStatus m_serviceStatus;
IConsole* m_console;
GridMate::IGridMate* m_gridMate;
GridMate::GridSearch* m_search;
AZStd::string m_serverName;
AZStd::string m_mapName;
AZ::u32 m_maxPlayers;
AZStd::string m_matchmakingConfigName;
};
#endif
}
@@ -0,0 +1,281 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "MultiplayerGem.h"
#include "GameLiftListener.h"
#include <GridMate/NetworkGridMate.h>
#include <GridMate/Carrier/Driver.h>
#include <CertificateManager/ICertificateManagerGem.h>
#include <GridMate/Carrier/DefaultSimulator.h>
#include <AzFramework/Network/NetBindingSystemBus.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include "Multiplayer/MultiplayerLobbyComponent.h"
#include "Multiplayer/MultiplayerEventsComponent.h"
#include "Multiplayer/BehaviorContext/GridSystemContext.h"
#include <AzFramework/Metrics/MetricsPlainTextNameRegistration.h>
#include <AzCore/Script/ScriptSystemComponent.h>
#include "Source/GameLift/GameLiftMatchmakingComponent.h"
#ifdef NET_SUPPORT_SECURE_SOCKET_DRIVER
# include <GridMate/Carrier/SecureSocketDriver.h>
#endif
namespace
{
void ApplyDisconnectDetectionSettings(GridMate::CarrierDesc& carrierDesc)
{
carrierDesc.m_enableDisconnectDetection = !!gEnv->pConsole->GetCVar("gm_disconnectDetection")->GetIVal();
if (gEnv->pConsole->GetCVar("gm_disconnectDetectionRttThreshold"))
{
carrierDesc.m_disconnectDetectionRttThreshold = gEnv->pConsole->GetCVar("gm_disconnectDetectionRttThreshold")->GetFVal();
}
if (gEnv->pConsole->GetCVar("gm_disconnectDetectionPacketLossThreshold"))
{
carrierDesc.m_disconnectDetectionPacketLossThreshold = gEnv->pConsole->GetCVar("gm_disconnectDetectionPacketLossThreshold")->GetFVal();
}
}
}
namespace Multiplayer
{
int MultiplayerModule::s_NetsecEnabled = 0;
int MultiplayerModule::s_NetsecVerifyClient = 0;
MultiplayerModule::MultiplayerModule()
: CryHooksModule()
, m_session(nullptr)
, m_secureDriver(nullptr)
, m_simulator(nullptr)
, m_gameLiftListener(nullptr)
, m_matchmakingComponent(nullptr)
{
m_descriptors.push_back(MultiplayerLobbyComponent::CreateDescriptor());
m_descriptors.push_back(MultiplayerEventsComponent::CreateDescriptor());
// This is an internal Amazon gem, so register it's components for metrics tracking, otherwise the name of the component won't get sent back.
// IF YOU ARE A THIRDPARTY WRITING A GEM, DO NOT REGISTER YOUR COMPONENTS WITH EditorMetricsComponentRegistrationBus
AZStd::vector<AZ::Uuid> typeIds;
typeIds.reserve(m_descriptors.size());
for (AZ::ComponentDescriptor* descriptor : m_descriptors)
{
typeIds.emplace_back(descriptor->GetUuid());
}
EBUS_EVENT(AzFramework::MetricsPlainTextNameRegistrationBus, RegisterForNameSending, typeIds);
}
MultiplayerModule::~MultiplayerModule()
{
delete m_simulator;
}
void MultiplayerModule::OnCrySystemInitialized(ISystem& system, const SSystemInitParams& systemInitParams)
{
CryHooksModule::OnCrySystemInitialized(system, systemInitParams);
m_cvars.RegisterCVars();
}
void MultiplayerModule::OnSystemEvent(ESystemEvent event, [[maybe_unused]] UINT_PTR wparam, [[maybe_unused]] UINT_PTR lparam)
{
switch (event)
{
case ESYSTEM_EVENT_GAME_POST_INIT:
{
#if defined(BUILD_GAMELIFT_SERVER)
m_gameLiftListener = aznew GameLiftListener();
#endif
AZ_Assert(gEnv->pNetwork->GetGridMate(), "No GridMate");
GridMate::SessionEventBus::Handler::BusConnect(gEnv->pNetwork->GetGridMate());
MultiplayerRequestBus::Handler::BusConnect();
m_cvars.PostInitRegistration();
}
break;
case ESYSTEM_EVENT_FULL_SHUTDOWN:
case ESYSTEM_EVENT_FAST_SHUTDOWN:
MultiplayerRequestBus::Handler::BusDisconnect();
GridMate::SessionEventBus::Handler::BusDisconnect();
m_cvars.UnregisterCVars();
#if defined(BUILD_GAMELIFT_SERVER)
delete m_gameLiftListener;
m_gameLiftListener = nullptr;
#endif
break;
default:
(void)event;
}
}
bool MultiplayerModule::IsNetSecEnabled() const
{
return NetSec::s_NetsecEnabled != 0;
}
bool MultiplayerModule::IsNetSecVerifyClient() const
{
return NetSec::s_NetsecVerifyClient != 0;
}
void MultiplayerModule::RegisterSecureDriver(GridMate::SecureSocketDriver* driver)
{
#if defined(NET_SUPPORT_SECURE_SOCKET_DRIVER)
AZ_Assert(driver != nullptr || m_session == nullptr, "Trying to Unregister secure driver with an active session. Once a session is active, MultiplayerGem will clean up the driver once the session terminates.");
AZ_Assert(m_secureDriver == nullptr || driver == nullptr,"Trying to Register two secure driver's at once. Unsupported behavior");
m_secureDriver = driver;
#else
(void)driver;
AZ_Error("MultiplayerModule", false, "Attempt to set SecureSocketDriver for unsupported platform\n");
#endif
}
GridMate::GridSession* MultiplayerModule::GetSession()
{
return m_session;
}
void MultiplayerModule::RegisterSession(GridMate::GridSession* session)
{
if (m_session != nullptr && session != nullptr)
{
CryLog("Already participating in the session '%s'. Leave existing session first!", m_session->GetId().c_str());
return;
}
m_session = session;
#if defined(BUILD_GAMELIFT_SERVER)
m_matchmakingComponent = aznew GameLiftMatchmakingComponent(m_session);
#endif
}
void MultiplayerModule::OnSessionCreated(GridMate::GridSession* session)
{
AZ_TracePrintf("MultiplayerModule", "Session %s has been created.\n", session->GetId().c_str());
if (session == m_session)
{
EBUS_EVENT(AzFramework::NetBindingSystemEventsBus, OnNetworkSessionCreated, session);
}
}
void MultiplayerModule::OnSessionHosted(GridMate::GridSession* session)
{
AZ_TracePrintf("MultiplayerModule", "Session %s has been hosted.\n", session->GetId().c_str());
if (session == m_session)
{
ActivateNetworkSession(session);
}
}
void MultiplayerModule::OnSessionJoined(GridMate::GridSession* session)
{
AZ_TracePrintf("MultiplayerModule", "Session %s has been joined.\n", session->GetId().c_str());
if (session == m_session)
{
ActivateNetworkSession(session);
}
}
void MultiplayerModule::ActivateNetworkSession(GridMate::GridSession* session)
{
AZ_Assert(session, "Invalid session");
session->GetReplicaMgr()->SetSendTimeInterval(gEnv->pConsole->GetCVar("gm_replicasSendTime")->GetIVal());
if (gEnv->pConsole->GetCVar("gm_replicasSendLimit"))
{
session->GetReplicaMgr()->SetSendLimit(gEnv->pConsole->GetCVar("gm_replicasSendLimit")->GetIVal());
}
if (gEnv->pConsole->GetCVar("gm_burstTimeLimit"))
{
session->GetReplicaMgr()->SetSendLimitBurstRange(gEnv->pConsole->GetCVar("gm_burstTimeLimit")->GetFVal());
}
EBUS_EVENT(AzFramework::NetBindingSystemEventsBus, OnNetworkSessionActivated, session);
}
//-----------------------------------------------------------------------------
void MultiplayerModule::OnSessionDelete(GridMate::GridSession* session)
{
CryLog("Session %s has been deleted.", session->GetId().c_str());
if (session == m_session)
{
EBUS_EVENT(AzFramework::NetBindingSystemEventsBus, OnNetworkSessionDeactivated, session);
m_session = nullptr;
#if defined(BUILD_GAMELIFT_SERVER)
delete m_matchmakingComponent;
m_matchmakingComponent = nullptr;
#endif
#ifdef NET_SUPPORT_SECURE_SOCKET_DRIVER
delete m_secureDriver;
m_secureDriver = nullptr;
#endif
}
}
//-----------------------------------------------------------------------------
void MultiplayerModule::OnCrySystemPostShutdown()
{
#ifdef NET_SUPPORT_SECURE_SOCKET_DRIVER
delete m_secureDriver;
m_secureDriver = nullptr;
#endif
CryHooksModule::OnCrySystemPostShutdown();
}
//-----------------------------------------------------------------------------
GridMate::Simulator* MultiplayerModule::GetSimulator()
{
return m_simulator;
}
//-----------------------------------------------------------------------------
void MultiplayerModule::EnableSimulator()
{
if (!m_simulator)
{
m_simulator = aznew GridMate::DefaultSimulator();
}
m_simulator->Enable();
}
//-----------------------------------------------------------------------------
void MultiplayerModule::DisableSimulator()
{
if (m_simulator)
{
m_simulator->Disable();
}
}
}
AZ_DECLARE_MODULE_CLASS(Gem_Multiplayer, Multiplayer::MultiplayerModule)
@@ -0,0 +1,87 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include "Multiplayer/IMultiplayerGem.h"
#include "MultiplayerCVars.h"
#include "CrySystemBus.h"
namespace GridMate
{
class SecureSocketDriver;
}
namespace Multiplayer
{
class GameLiftListener;
class GameLiftMatchmakingComponent;
class MultiplayerModule
: public CryHooksModule
, public MultiplayerRequestBus::Handler
, public GridMate::SessionEventBus::Handler
{
friend class MultiplayerCVars;
public:
AZ_RTTI(MultiplayerModule, "{946D16FF-7C9D-4134-88F9-03FAE5D5803A}", CryHooksModule);
MultiplayerModule();
~MultiplayerModule() override;
////////////////////
// IMultiplayerGem
bool IsNetSecEnabled() const override;
bool IsNetSecVerifyClient() const override;
void RegisterSecureDriver(GridMate::SecureSocketDriver* driver) override;
GridMate::GridSession* GetSession() override;
void RegisterSession(GridMate::GridSession* session) override;
GridMate::Simulator* GetSimulator() override;
void EnableSimulator() override;
void DisableSimulator() override;
////////////////////
private:
void OnCrySystemInitialized(ISystem&, const SSystemInitParams&) override;
void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam) override;
void OnSessionCreated(GridMate::GridSession* session) override;
void OnSessionHosted(GridMate::GridSession* session) override;
void OnSessionJoined(GridMate::GridSession* session) override;
void OnSessionDelete(GridMate::GridSession* session) override;
void OnCrySystemPostShutdown() override;
void ActivateNetworkSession(GridMate::GridSession* session);
//! Current game session
GridMate::GridSession* m_session;
//! Secure driver
GridMate::SecureSocketDriver* m_secureDriver;
//! Network specific commands and cvars.
MultiplayerCVars m_cvars;
GridMate::DefaultSimulator* m_simulator;
GameLiftListener* m_gameLiftListener;
static int s_NetsecEnabled;
static int s_NetsecVerifyClient;
GameLiftMatchmakingComponent* m_matchmakingComponent;
};
} // namespace Multiplayer
@@ -0,0 +1,995 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/std/string/string.h>
#include <GameLift/GameLiftBus.h>
#include <GameLift/Session/GameLiftClientService.h>
#include <GameLift/Session/GameLiftSessionDefs.h>
#include <GameLift/Session/GameLiftSessionRequest.h>
#include <GridMate/Carrier/Driver.h>
#include <GridMate/NetworkGridMate.h>
#include <LyShine/Bus/UiCursorBus.h>
#include "Multiplayer/IMultiplayerGem.h"
#include "Multiplayer/MultiplayerLobbyServiceWrapper/MultiplayerLobbyLANServiceWrapper.h"
#include "Source/Canvas/MultiplayerDedicatedHostTypeSelectionCanvas.h"
#include "Source/Canvas/MultiplayerGameLiftLobbyCanvas.h"
#include "Source/Canvas/MultiplayerLANGameLobbyCanvas.h"
#include "Source/Canvas/MultiplayerBusyAndErrorCanvas.h"
#include "Multiplayer/MultiplayerLobbyComponent.h"
#include <Multiplayer_Traits_Platform.h>
#include "Multiplayer/MultiplayerUtils.h"
#include <Source/Canvas/MultiplayerCanvasHelper.h>
namespace Platform
{
bool ListServers(const AZStd::string& actionName, const AZ::EntityId& entityId, Multiplayer::MultiplayerLobbyServiceWrapper*& multiplayerLobbyServiceWrapper);
}
namespace Multiplayer
{
void MultiplayerLobbyComponent::Reflect(AZ::ReflectContext* reflectContext)
{
AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(reflectContext);
if (serialize)
{
serialize->Class<MultiplayerLobbyComponent,AZ::Component>()
->Version(1)
->Field("MaxPlayers",&MultiplayerLobbyComponent::m_maxPlayers)
->Field("Port",&MultiplayerLobbyComponent::m_port)
->Field("EnableDisconnectDetection",&MultiplayerLobbyComponent::m_enableDisconnectDetection)
->Field("ConnectionTimeout",&MultiplayerLobbyComponent::m_connectionTimeoutMS)
->Field("DefaultMap",&MultiplayerLobbyComponent::m_defaultMap)
->Field("DefaultServer",&MultiplayerLobbyComponent::m_defaultServerName)
->Field("DefaultMatchmakingConfig",&MultiplayerLobbyComponent::m_defaultMatchmakingConfig)
;
AZ::EditContext* editContext = serialize->GetEditContext();
if (editContext)
{
editContext->Class<MultiplayerLobbyComponent>("Multiplayer Lobby Component","This component will load up and manage a simple lobby for connecting for LAN and GameLift sessions.")
->ClassElement(AZ::Edit::ClassElements::EditorData,"")
->Attribute(AZ::Edit::Attributes::Category,"MultiplayerSample")
->Attribute(AZ::Edit::Attributes::AutoExpand,true)
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game"))
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_maxPlayers,"Max Players","The total number of players that can join in the game.")
->Attribute(AZ::Edit::Attributes::Min,0)
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_port,"Port","The port on which the game service will create connections through.")
->Attribute(AZ::Edit::Attributes::Min,1)
->Attribute(AZ::Edit::Attributes::Max,65534)
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_enableDisconnectDetection,"Enable Disconnect Detection","Enables disconnecting players if they do not respond within the Timeout window.")
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_connectionTimeoutMS,"Timeout","The length of time a client has to respond before being disconnected(if disconnection detection is enabled.")
->Attribute(AZ::Edit::Attributes::Suffix,"ms")
->Attribute(AZ::Edit::Attributes::Min,0)
->Attribute(AZ::Edit::Attributes::Max,60000)
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_defaultMap,"DefaultMap", "The default value that will be added to the map field when loading the lobby.")
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_defaultServerName,"DefaultServerName","The default value that will be added to the server name field when loading the lobby.")
->DataElement(AZ::Edit::UIHandlers::Default, &MultiplayerLobbyComponent::m_defaultMatchmakingConfig,"DefaultMatchmaking","The default value that will be used for matchmaking in the GameLift lobby.")
;
}
}
}
MultiplayerLobbyComponent::MultiplayerLobbyComponent()
: m_maxPlayers(8)
, m_port(SERVER_DEFAULT_PORT)
, m_enableDisconnectDetection(true)
, m_connectionTimeoutMS(500)
, m_defaultMap("")
, m_defaultServerName("MyServer")
, m_defaultMatchmakingConfig("MyConfig")
, m_unregisterGameliftServiceOnErrorDismiss(false)
, m_hasGameliftSession(false)
, m_lobbyMode(LobbyMode::Unknown)
, m_listSearch(nullptr)
, m_multiplayerLobbyServiceWrapper(nullptr)
, m_gameliftCreationSearch(nullptr)
{
}
MultiplayerLobbyComponent::~MultiplayerLobbyComponent()
{
}
void MultiplayerLobbyComponent::Activate()
{
Multiplayer::MultiplayerLobbyBus::Handler::BusConnect(GetEntityId());
MultiplayerDedicatedHostTypeSelectionCanvasContext dedicatedHostTypeSelectionCanvasContext;
dedicatedHostTypeSelectionCanvasContext.OnLANButtonClicked = std::bind(&MultiplayerLobbyComponent::SelectLANServerType, this);
dedicatedHostTypeSelectionCanvasContext.OnGameLiftConnectButtonClicked = std::bind(&MultiplayerLobbyComponent::SelectGameLiftServerType, this);
m_dedicatedHostTypeSelectionCanvas = aznew MultiplayerDedicatedHostTypeSelectionCanvas(dedicatedHostTypeSelectionCanvasContext);
MultiplayerLANGameLobbyCanvasContext lanGameLobbyCanvasContext;
lanGameLobbyCanvasContext.CreateServerViewContext.OnCreateServerButtonClicked = std::bind(&MultiplayerLobbyComponent::CreateServer, this);
lanGameLobbyCanvasContext.OnReturnButtonClicked = std::bind(&MultiplayerLobbyComponent::ShowSelectionLobby, this);
lanGameLobbyCanvasContext.JoinServerViewContext.OnJoinButtonClicked = std::bind(&MultiplayerLobbyComponent::JoinServer, this);
lanGameLobbyCanvasContext.JoinServerViewContext.OnRefreshButtonClicked = std::bind(&MultiplayerLobbyComponent::ListServers, this);
lanGameLobbyCanvasContext.CreateServerViewContext.DefaultMapName = m_defaultMap;
lanGameLobbyCanvasContext.CreateServerViewContext.DefaultServerName = m_defaultServerName;
m_lanGameLobbyCanvas = aznew MultiplayerLANGameLobbyCanvas(lanGameLobbyCanvasContext);
m_lanGameLobbyCanvas->Hide();
MultiplayerGameLiftLobbyCanvasContext gameLiftLobbyCanvasContext;
gameLiftLobbyCanvasContext.CreateServerViewContext.OnCreateServerButtonClicked = std::bind(&MultiplayerLobbyComponent::CreateServer, this);
gameLiftLobbyCanvasContext.OnReturnButtonClicked = std::bind(&MultiplayerLobbyComponent::ShowSelectionLobby, this);
gameLiftLobbyCanvasContext.JoinServerViewContext.OnJoinButtonClicked = std::bind(&MultiplayerLobbyComponent::JoinServer, this);
gameLiftLobbyCanvasContext.JoinServerViewContext.OnRefreshButtonClicked = std::bind(&MultiplayerLobbyComponent::ListServers, this);
#if defined(BUILD_GAMELIFT_CLIENT)
gameLiftLobbyCanvasContext.GameLiftFlexMatchViewContext.OnStartMatchmakingButtonClicked = std::bind(&MultiplayerLobbyComponent::StartGameLiftMatchmaking, this);
#endif
gameLiftLobbyCanvasContext.CreateServerViewContext.DefaultMapName = m_defaultMap;
gameLiftLobbyCanvasContext.CreateServerViewContext.DefaultServerName = m_defaultServerName;
gameLiftLobbyCanvasContext.GameLiftFlexMatchViewContext.DefaultMatchmakingConfig = m_defaultMatchmakingConfig;
m_gameLiftLobbyCanvas = aznew MultiplayerGameLiftLobbyCanvas(gameLiftLobbyCanvasContext);
m_gameLiftLobbyCanvas->Hide();
MultiplayerBusyAndErrorCanvasContext busyAndErrorCanvasContext;
busyAndErrorCanvasContext.OnDismissErrroWindowButtonClicked = std::bind(&MultiplayerLobbyComponent::DismissError, this, false);
m_busyAndErrorCanvas = aznew MultiplayerBusyAndErrorCanvas(busyAndErrorCanvasContext);
ShowSelectionLobby();
UiCursorBus::Broadcast(&UiCursorInterface::IncrementVisibleCounter);
if (gEnv->pNetwork)
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (gridMate)
{
GridMate::SessionEventBus::Handler::BusConnect(gridMate);
}
}
AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT(AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT_VALUE);
}
void MultiplayerLobbyComponent::Deactivate()
{
GridMate::SessionEventBus::Handler::BusDisconnect();
delete m_dedicatedHostTypeSelectionCanvas;
m_dedicatedHostTypeSelectionCanvas = nullptr;
delete m_lanGameLobbyCanvas;
m_lanGameLobbyCanvas = nullptr;
delete m_gameLiftLobbyCanvas;
m_gameLiftLobbyCanvas = nullptr;
UiCursorBus::Broadcast(&UiCursorInterface::DecrementVisibleCounter);
ClearSearches();
delete m_multiplayerLobbyServiceWrapper;
m_multiplayerLobbyServiceWrapper = nullptr;
}
void MultiplayerLobbyComponent::SelectLANServerType()
{
if (m_multiplayerLobbyServiceWrapper)
{
delete m_multiplayerLobbyServiceWrapper;
}
m_multiplayerLobbyServiceWrapper = aznew MultiplayerLobbyLANServiceWrapper(GetEntityId());
ShowLobby(LobbyMode::ServiceWrapperLobby);
}
void MultiplayerLobbyComponent::SelectGameLiftServerType()
{
#if defined(BUILD_GAMELIFT_CLIENT)
ShowLobby(LobbyMode::GameliftLobby);
#else
AZ_Assert(false, "Trying to use GameLift on unsupported Platform.");
#endif
}
void MultiplayerLobbyComponent::OnSessionCreated(GridMate::GridSession* session)
{
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession,Multiplayer::MultiplayerRequestBus,GetSession);
if (gridSession == session && session->IsHost())
{
Multiplayer::Utils::SynchronizeSessionState(session);
}
}
void MultiplayerLobbyComponent::OnSessionError([[maybe_unused]] GridMate::GridSession* session,const GridMate::string& errorMsg)
{
ShowError(errorMsg.c_str());
}
void MultiplayerLobbyComponent::OnGridSearchComplete(GridMate::GridSearch* search)
{
if (search == m_gameliftCreationSearch)
{
DismissBusyScreen();
GridMate::Network* network = static_cast<GridMate::Network*>(gEnv->pNetwork);
if (network)
{
if (search->GetNumResults() == 0)
{
ShowError("Error creating GameLift Session");
}
else
{
const GridMate::SearchInfo* searchInfo = m_gameliftCreationSearch->GetResult(0);
JoinSession(searchInfo);
}
}
m_gameliftCreationSearch->Release();
m_gameliftCreationSearch = nullptr;
}
else if (search == m_listSearch)
{
if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
m_lanGameLobbyCanvas->DisplaySearchResults(m_listSearch);
}
else if(m_lobbyMode == LobbyMode::GameliftLobby)
{
m_gameLiftLobbyCanvas->DisplaySearchResults(m_listSearch);
}
DismissBusyScreen();
}
}
int MultiplayerLobbyComponent::GetGamePort() const
{
return m_port;
}
void MultiplayerLobbyComponent::ConfigureSessionParams(GridMate::SessionParams& sessionParams)
{
sessionParams.m_topology = GridMate::ST_CLIENT_SERVER;
sessionParams.m_numPublicSlots = m_maxPlayers + (gEnv->IsDedicated() ? 1 : 0); // One slot for server member.
sessionParams.m_numPrivateSlots = 0;
sessionParams.m_peerToPeerTimeout = 60000;
sessionParams.m_flags = 0;
sessionParams.m_numParams = 0;
sessionParams.m_params[sessionParams.m_numParams].m_id = "sv_name";
sessionParams.m_params[sessionParams.m_numParams].SetValue(GetServerName().c_str());
sessionParams.m_numParams++;
sessionParams.m_params[sessionParams.m_numParams].m_id = "sv_map";
sessionParams.m_params[sessionParams.m_numParams].SetValue(GetMapName().c_str());
sessionParams.m_numParams++;
}
void MultiplayerLobbyComponent::ShowSelectionLobby()
{
const bool forceHide = true;
if (m_lobbyMode != LobbyMode::LobbySelection)
{
ClearSearches();
StopSessionService();
if (m_multiplayerLobbyServiceWrapper)
{
delete m_multiplayerLobbyServiceWrapper;
m_multiplayerLobbyServiceWrapper = nullptr;
}
HideLobby();
m_lobbyMode = LobbyMode::LobbySelection;
m_dedicatedHostTypeSelectionCanvas->Show();
DismissError(forceHide);
DismissBusyScreen(forceHide);
}
}
void MultiplayerLobbyComponent::ShowLobby(LobbyMode lobbyMode)
{
if (lobbyMode == LobbyMode::LobbySelection)
{
ShowSelectionLobby();
}
else if (m_lobbyMode == LobbyMode::LobbySelection)
{
bool showLobby = StartSessionService(lobbyMode);
if (showLobby)
{
HideLobby();
m_lobbyMode = lobbyMode;
if (lobbyMode == LobbyMode::ServiceWrapperLobby)
{
m_lanGameLobbyCanvas->ClearSearchResults();
m_lanGameLobbyCanvas->Show();
}
else if (lobbyMode == LobbyMode::GameliftLobby)
{
m_gameLiftLobbyCanvas->ClearSearchResults();
m_gameLiftLobbyCanvas->Show();
}
const bool forceHide = true;
DismissError(forceHide);
DismissBusyScreen(forceHide);
}
}
}
void MultiplayerLobbyComponent::HideLobby()
{
switch (m_lobbyMode)
{
case LobbyMode::ServiceWrapperLobby:
m_lanGameLobbyCanvas->Hide();
break;
case LobbyMode::GameliftLobby:
m_gameLiftLobbyCanvas->Hide();
break;
case LobbyMode::LobbySelection:
m_dedicatedHostTypeSelectionCanvas->Hide();
break;
default:
break;
}
m_lobbyMode = LobbyMode::Unknown;
}
bool MultiplayerLobbyComponent::StartSessionService(LobbyMode lobbyMode)
{
bool startedService = false;
if (lobbyMode == LobbyMode::ServiceWrapperLobby)
{
if (gEnv->pNetwork && gEnv->pNetwork->GetGridMate())
{
if (SanityCheckWrappedSessionService())
{
startedService = m_multiplayerLobbyServiceWrapper->StartSessionService(gEnv->pNetwork->GetGridMate());
}
}
}
else if (lobbyMode == LobbyMode::GameliftLobby)
{
#if defined(BUILD_GAMELIFT_CLIENT)
startedService = StartGameLiftSession();
#else
startedService = false;
#endif
}
return startedService;
}
void MultiplayerLobbyComponent::StopSessionService()
{
// Stop whatever session we may have been using, if any
if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
if (gEnv->pNetwork && gEnv->pNetwork->GetGridMate())
{
if (SanityCheckWrappedSessionService())
{
m_multiplayerLobbyServiceWrapper->StopSessionService(gEnv->pNetwork->GetGridMate());
}
}
}
else if (m_lobbyMode == LobbyMode::GameliftLobby)
{
#if defined(BUILD_GAMELIFT_CLIENT)
StopGameLiftSession();
m_hasGameliftSession = false;
#else
AZ_Assert(false,"Trying to use Gamelift on Unsupported platform.");
#endif
}
}
void MultiplayerLobbyComponent::CreateServer()
{
if (m_lobbyMode == LobbyMode::LobbySelection)
{
return;
}
else if (SanityCheck())
{
if (GetMapName().empty())
{
ShowError("Invalid Map Name");
}
else if (GetServerName().empty())
{
ShowError("Invalid Server Name");
}
else
{
bool netSecEnabled = false;
EBUS_EVENT_RESULT(netSecEnabled, Multiplayer::MultiplayerRequestBus,IsNetSecEnabled);
if (netSecEnabled)
{
if (!NetSec::CanCreateSecureSocketForHosting())
{
ShowError("Invalid Secure Socket configuration given for hosting a session.\nEnsure that a Public and Private key are being supplied.");
return;
}
}
if (m_lobbyMode == LobbyMode::GameliftLobby)
{
#if defined(BUILD_GAMELIFT_CLIENT)
if (SanityCheckGameLift())
{
CreateServerForGameLift();
}
#else
AZ_Assert(false,"Trying to use Gamelift on unsupported platform.");
#endif
}
else if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
if (SanityCheckWrappedSessionService())
{
CreateServerForWrappedService();
}
}
}
}
}
void MultiplayerLobbyComponent::ListServers()
{
if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
m_lanGameLobbyCanvas->ClearSearchResults();
}
else if (m_lobbyMode == LobbyMode::GameliftLobby)
{
m_gameLiftLobbyCanvas->ClearSearchResults();
}
if (m_lobbyMode == LobbyMode::GameliftLobby)
{
#if defined(BUILD_GAMELIFT_CLIENT)
if (SanityCheckGameLift())
{
ListServersForGameLift();
}
#else
AZ_Assert(false,"Trying to use Gamelift lobby on unsupported platform.")
#endif
}
else if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
ListServersForWrappedService();
}
}
void MultiplayerLobbyComponent::ClearSearches()
{
if (m_listSearch)
{
if (!m_listSearch->IsDone())
{
m_listSearch->AbortSearch();
}
m_listSearch->Release();
m_listSearch = nullptr;
}
if (m_gameliftCreationSearch)
{
if (!m_gameliftCreationSearch->IsDone())
{
m_gameliftCreationSearch->AbortSearch();
}
m_gameliftCreationSearch->Release();
m_gameliftCreationSearch = nullptr;
}
}
void MultiplayerLobbyComponent::JoinServer()
{
if (m_lobbyMode == LobbyMode::LobbySelection)
{
return;
}
int selectedServerResult = -1;
if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
selectedServerResult = m_lanGameLobbyCanvas->GetSelectedServerResult();
}
else if (m_lobbyMode == LobbyMode::GameliftLobby)
{
selectedServerResult = m_gameLiftLobbyCanvas->GetSelectedServerResult();
}
if ( m_listSearch == nullptr
|| !m_listSearch->IsDone()
|| selectedServerResult < 0
|| m_listSearch->GetNumResults() <= selectedServerResult)
{
ShowError("No Server Selected to Join.");
return;
}
const GridMate::SearchInfo* searchInfo = m_listSearch->GetResult(selectedServerResult);
if (!SanityCheck())
{
return;
}
else if (searchInfo == nullptr)
{
ShowError("Invalid Server Selection.");
return;
}
else
{
bool netSecEnabled = false;
EBUS_EVENT_RESULT(netSecEnabled, Multiplayer::MultiplayerRequestBus,IsNetSecEnabled);
if (netSecEnabled)
{
if (!NetSec::CanCreateSecureSocketForJoining())
{
ShowError("Invalid Secure Socket configuration given for joining an encrypted session.\nEnsure that a Certificate Authority is being supplied.");
return;
}
}
if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
if (!SanityCheckWrappedSessionService())
{
return;
}
}
else if (m_lobbyMode == LobbyMode::GameliftLobby)
{
#if defined(BUILD_GAMELIFT_CLIENT)
if (!SanityCheckGameLift())
{
return;
}
#else
AZ_Assert(false,"Trying to use Gamelift lobby on unsupported platform.")
return;
#endif
}
}
ShowBusyScreen();
if (!JoinSession(searchInfo))
{
ShowError("Found a game session, but failed to join.");
}
}
bool MultiplayerLobbyComponent::JoinSession(const GridMate::SearchInfo* searchInfo)
{
GridMate::GridSession* session = nullptr;
GridMate::CarrierDesc carrierDesc;
Multiplayer::Utils::InitCarrierDesc(carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForJoin(carrierDesc);
GridMate::JoinParams joinParams;
if (m_lobbyMode == LobbyMode::ServiceWrapperLobby)
{
if (SanityCheckWrappedSessionService())
{
session = m_multiplayerLobbyServiceWrapper->JoinSession(gEnv->pNetwork->GetGridMate(),carrierDesc,searchInfo);
}
}
else if (m_lobbyMode == LobbyMode::GameliftLobby)
{
#if defined(BUILD_GAMELIFT_CLIENT)
const GridMate::GameLiftSearchInfo& gameliftSearchInfo = static_cast<const GridMate::GameLiftSearchInfo&>(*searchInfo);
EBUS_EVENT_ID_RESULT(session, gEnv->pNetwork->GetGridMate(), GridMate::GameLiftClientServiceBus, JoinSessionBySearchInfo, gameliftSearchInfo, carrierDesc);
#endif
}
if (session != nullptr)
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus,RegisterSession,session);
}
else
{
Multiplayer::NetSec::OnSessionFailedToCreate(carrierDesc);
}
return session != nullptr;
}
bool MultiplayerLobbyComponent::SanityCheck()
{
if (gEnv->IsEditor())
{
ShowError("Unsupported action inside of Editor.");
return false;
}
else if (gEnv->pNetwork == nullptr)
{
ShowError("Network Environment is null");
return false;
}
else
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (gridMate == nullptr)
{
ShowError("GridMate is null.");
return false;
}
}
return true;
}
bool MultiplayerLobbyComponent::SanityCheckWrappedSessionService()
{
return m_multiplayerLobbyServiceWrapper != nullptr;
}
void MultiplayerLobbyComponent::CreateServerForWrappedService()
{
GridMate::GridSession* gridSession = nullptr;
EBUS_EVENT_RESULT(gridSession,Multiplayer::MultiplayerRequestBus,GetSession);
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (!gridSession && SanityCheckWrappedSessionService())
{
GridMate::CarrierDesc carrierDesc;
Multiplayer::Utils::InitCarrierDesc(carrierDesc);
Multiplayer::NetSec::ConfigureCarrierDescForHost(carrierDesc);
carrierDesc.m_port = m_port;
carrierDesc.m_enableDisconnectDetection = m_enableDisconnectDetection;
carrierDesc.m_connectionTimeoutMS = m_connectionTimeoutMS;
carrierDesc.m_threadUpdateTimeMS = 30;
ShowBusyScreen();
GridMate::GridSession* session = m_multiplayerLobbyServiceWrapper->CreateServer(gridMate,carrierDesc);
if (session == nullptr)
{
Multiplayer::NetSec::OnSessionFailedToCreate(carrierDesc);
ShowError("Error while hosting Session.");
}
else
{
EBUS_EVENT(Multiplayer::MultiplayerRequestBus,RegisterSession,session);
}
}
else
{
ShowError("Invalid Gem Session");
}
}
void MultiplayerLobbyComponent::ListServersForWrappedService()
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (gridMate && SanityCheck() && SanityCheckWrappedSessionService())
{
ShowBusyScreen();
if (m_listSearch)
{
m_listSearch->AbortSearch();
m_listSearch->Release();
m_listSearch = nullptr;
}
m_listSearch = m_multiplayerLobbyServiceWrapper->ListServers(gridMate);
if (m_listSearch == nullptr)
{
ShowError("ListServers failed to start a GridSearch.");
}
}
else
{
ShowError("Missing Online Service.");
}
}
bool MultiplayerLobbyComponent::SanityCheckGameLift()
{
#if defined(BUILD_GAMELIFT_CLIENT)
if (!ValidateGameLiftConfig())
{
return false;
}
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
// This should already be errored by the previous sanity check.
if (gridMate == nullptr)
{
return false;
}
else if (!GridMate::HasGridMateService<GridMate::GameLiftClientService>(gridMate))
{
ShowError("MultiplayerService is missing.");
return false;
}
return true;
#else
return false;
#endif
}
bool MultiplayerLobbyComponent::ValidateGameLiftConfig()
{
const AZStd::string fleetId = GetConsoleVarValue("gamelift_fleet_id");
const AZStd::string aliasId = GetConsoleVarValue("gamelift_alias_id");
const AZStd::string queueName = GetConsoleVarValue("gamelift_queue_name");
//Validation on inputs.
//Service still supports the use of developers credentials on top of the player credentials.
if (fleetId.empty() && aliasId.empty() && queueName.empty())
{
AZ_TracePrintf("GameLift", "You need to provide at least [gamelift_aliasid, gamelift_aws_access_key, gamelift_aws_secret_key] or [gamelift_fleetid, gamelift_aws_access_key, gamelift_aws_secret_key] or [gamelift_queue_name, gamelift_aws_access_key, gamelift_aws_secret_key]\n");
return false;
}
if (!fleetId.empty())
{
if (!aliasId.empty() || !queueName.empty())
{
AZ_TracePrintf("GameLift", "Initialize failed. Cannot use fleet id with aliasId/queueName.\n");
return false;
}
}
if (!aliasId.empty()) {
if (!fleetId.empty() || !queueName.empty())
{
AZ_TracePrintf("GameLift", "Initialize failed. Cannot use alias id with fleetId/queueName.\n");
return false;
}
}
//If the using queues.
if (!queueName.empty())
{
if (!fleetId.empty() || !aliasId.empty())
{
AZ_TracePrintf("GameLift", "Initialize failed. Cannot use queue name with fleetId/aliasId.\n");
return false;
}
}
return true;
}
#if defined(BUILD_GAMELIFT_CLIENT)
bool MultiplayerLobbyComponent::StartGameLiftSession()
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
// Not sure what happens if we start this once and it fails to be created...
// calling it again causes an assert.
if (gridMate && !m_hasGameliftSession)
{
ShowBusyScreen();
GridMate::GameLiftClientServiceEventsBus::Handler::BusConnect(gridMate);
GridMate::GameLiftClientServiceDesc serviceDesc;
serviceDesc.m_accessKey = GetConsoleVarValue("gamelift_aws_access_key");
serviceDesc.m_secretKey = GetConsoleVarValue("gamelift_aws_secret_key");
serviceDesc.m_endpoint = GetConsoleVarValue("gamelift_endpoint");
serviceDesc.m_region = GetConsoleVarValue("gamelift_aws_region");
serviceDesc.m_playerId = GetConsoleVarValue("gamelift_player_id");
serviceDesc.m_useGameLiftLocalServer = GetGetConsoleVarBoolValue("gamelift_uselocalserver");
EBUS_EVENT(GameLift::GameLiftRequestBus, StartClientService, serviceDesc);
}
return m_hasGameliftSession;
}
void MultiplayerLobbyComponent::StopGameLiftSession()
{
EBUS_EVENT(GameLift::GameLiftRequestBus, StopClientService);
}
void MultiplayerLobbyComponent::StartGameLiftMatchmaking()
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (m_gameliftCreationSearch)
{
m_gameliftCreationSearch->AbortSearch();
m_gameliftCreationSearch->Release();
m_gameliftCreationSearch = nullptr;
}
ShowBusyScreen();
EBUS_EVENT_ID_RESULT(m_gameliftCreationSearch, gridMate, GridMate::GameLiftClientServiceBus, StartMatchmaking, GetConsoleVarValue("gamelift_matchmaking_config_name"));
}
void MultiplayerLobbyComponent::CreateServerForGameLift()
{
GridMate::IGridMate* gridMate = gEnv->pNetwork->GetGridMate();
if (m_gameliftCreationSearch)
{
m_gameliftCreationSearch->AbortSearch();
m_gameliftCreationSearch->Release();
m_gameliftCreationSearch = nullptr;
}
GridMate::GameLiftSessionRequestParams reqParams;
ConfigureSessionParams(reqParams);
reqParams.m_instanceName = m_gameLiftLobbyCanvas->GetServerName().c_str();
reqParams.m_fleetId = GetConsoleVarValue("gamelift_fleet_id");
reqParams.m_queueName = GetConsoleVarValue("gamelift_queue_name");
reqParams.m_aliasId = GetConsoleVarValue("gamelift_alias_id");
reqParams.m_useFleetId = !reqParams.m_fleetId.empty();
ShowBusyScreen();
EBUS_EVENT_ID_RESULT(m_gameliftCreationSearch, gridMate, GridMate::GameLiftClientServiceBus, RequestSession, reqParams);
if (m_gameliftCreationSearch == nullptr)
{
ShowError("Failed to create Server for GameLift");
}
}
void MultiplayerLobbyComponent::ListServersForGameLift()
{
ShowBusyScreen();
GridMate::Network* network = static_cast<GridMate::Network*>(gEnv->pNetwork);
GridMate::IGridMate* gridMate = network->GetGridMate();
if (m_listSearch)
{
m_listSearch->AbortSearch();
m_listSearch->Release();
m_listSearch = nullptr;
}
GridMate::GameLiftSearchParams searchParams;
searchParams.m_fleetId = GetConsoleVarValue("gamelift_fleet_id");
searchParams.m_queueName = GetConsoleVarValue("gamelift_queue_name");
searchParams.m_aliasId = GetConsoleVarValue("gamelift_alias_id");
searchParams.m_useFleetId = !searchParams.m_fleetId.empty();
EBUS_EVENT_ID_RESULT(m_listSearch,gridMate,GridMate::GameLiftClientServiceBus, StartSearch, searchParams);
if (m_listSearch == nullptr)
{
ShowError("Failed to start a GridSearch");
}
}
void MultiplayerLobbyComponent::OnGameLiftSessionServiceReady(GridMate::GameLiftClientService* service)
{
AZ_UNUSED(service);
DismissBusyScreen();
m_hasGameliftSession = true;
ShowLobby(LobbyMode::GameliftLobby);
}
void MultiplayerLobbyComponent::OnGameLiftSessionServiceFailed(GridMate::GameLiftClientService* service, const AZStd::string& message)
{
AZ_UNUSED(service);
DismissBusyScreen();
m_hasGameliftSession = false;
m_unregisterGameliftServiceOnErrorDismiss = true;
AZStd::string errorMessage("GameLift Error: ");
errorMessage += message;
ShowError(errorMessage.c_str());
}
#endif
void MultiplayerLobbyComponent::ShowError(const char* error)
{
m_busyAndErrorCanvas->ShowError(error);
}
void MultiplayerLobbyComponent::DismissError([[maybe_unused]] bool force)
{
m_busyAndErrorCanvas->DismissError();
if (m_unregisterGameliftServiceOnErrorDismiss)
{
m_unregisterGameliftServiceOnErrorDismiss = false;
#if defined(BUILD_GAMELIFT_CLIENT)
StopGameLiftSession();
#endif
}
}
void MultiplayerLobbyComponent::ShowBusyScreen()
{
m_busyAndErrorCanvas->ShowBusyScreen();
}
void MultiplayerLobbyComponent::DismissBusyScreen(bool force)
{
m_busyAndErrorCanvas->DismissBusyScreen(force);
}
LyShine::StringType MultiplayerLobbyComponent::GetMapName() const
{
switch (m_lobbyMode)
{
case LobbyMode::ServiceWrapperLobby:
return m_lanGameLobbyCanvas->GetMapName();
case LobbyMode::GameliftLobby:
return m_gameLiftLobbyCanvas->GetMapName();
default:
return "";
}
}
LyShine::StringType MultiplayerLobbyComponent::GetServerName() const
{
switch (m_lobbyMode)
{
case LobbyMode::ServiceWrapperLobby:
return m_lanGameLobbyCanvas->GetServerName();
case LobbyMode::GameliftLobby:
return m_gameLiftLobbyCanvas->GetServerName();
default:
return "";
}
}
}
@@ -0,0 +1,110 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <GridMate/Session/LANSession.h>
#include "Multiplayer/MultiplayerLobbyServiceWrapper/MultiplayerLobbyLANServiceWrapper.h"
#include "Multiplayer/MultiplayerUtils.h"
#include <Multiplayer_Traits_Platform.h>
namespace Multiplayer
{
MultiplayerLobbyLANServiceWrapper::MultiplayerLobbyLANServiceWrapper(const AZ::EntityId& multiplayerLobbyEntityId)
: MultiplayerLobbyServiceWrapper(multiplayerLobbyEntityId)
{
}
MultiplayerLobbyLANServiceWrapper::~MultiplayerLobbyLANServiceWrapper()
{
}
bool MultiplayerLobbyLANServiceWrapper::SanityCheck([[maybe_unused]] GridMate::IGridMate* gridMate)
{
// Nothing in LAN Session Service we need to sanity check
return true;
}
bool MultiplayerLobbyLANServiceWrapper::StartSessionService(GridMate::IGridMate* gridMate)
{
Multiplayer::LAN::StartSessionService(gridMate);
return GridMate::HasGridMateService<GridMate::LANSessionService>(gridMate);
}
void MultiplayerLobbyLANServiceWrapper::StopSessionService(GridMate::IGridMate* gridMate)
{
Multiplayer::LAN::StopSessionService(gridMate);
}
GridMate::GridSession* MultiplayerLobbyLANServiceWrapper::CreateServerForService(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc)
{
GridMate::GridSession* gridSession = nullptr;
// Setup and create the LANSessionParams
GridMate::LANSessionParams sessionParams;
sessionParams.m_port = GetServerPort();
// Collect the shared session params from the MultiplayerLobby
EBUS_EVENT_ID(GetTargetEntityId(),Multiplayer::MultiplayerLobbyBus,ConfigureSessionParams,sessionParams);
EBUS_EVENT_ID_RESULT(gridSession,gridMate,GridMate::LANSessionServiceBus,HostSession,sessionParams,carrierDesc);
return gridSession;
}
GridMate::GridSearch* MultiplayerLobbyLANServiceWrapper::ListServersForService(GridMate::IGridMate* gridMate)
{
GridMate::GridSearch* retVal = nullptr;
GridMate::LANSearchParams searchParams;
searchParams.m_serverPort = GetServerPort();
searchParams.m_listenPort = 0;
searchParams.m_maxSessions = gEnv->pConsole->GetCVar("gm_maxSearchResults")->GetIVal();
AZ_TracePrintf("MultiplayerModule", "Limiting search results to a maximum of %d sessions.\n", searchParams.m_maxSessions);
searchParams.m_version = gEnv->pConsole->GetCVar("gm_version")->GetIVal();
searchParams.m_familyType = Multiplayer::Utils::CVarToFamilyType(gEnv->pConsole->GetCVar("gm_ipversion")->GetString());
#if AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY
AZ_Error(AZ_TRAIT_MULTIPLAYER_SESSION_NAME, searchParams.m_familyType == AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE, AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE);
searchParams.m_familyType = AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE;
#endif
EBUS_EVENT_ID_RESULT(retVal, gridMate, GridMate::LANSessionServiceBus, StartGridSearch, searchParams);
return retVal;
}
GridMate::GridSession* MultiplayerLobbyLANServiceWrapper::JoinSessionForService(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc, const GridMate::SearchInfo* searchInfo)
{
GridMate::GridSession* gridSession = nullptr;
const GridMate::LANSearchInfo& lanSearchInfo = static_cast<const GridMate::LANSearchInfo&>(*searchInfo);
GridMate::JoinParams joinParams;
EBUS_EVENT_ID_RESULT(gridSession, gridMate, GridMate::LANSessionServiceBus, JoinSessionBySearchInfo, lanSearchInfo, joinParams, carrierDesc);
return gridSession;
}
int MultiplayerLobbyLANServiceWrapper::GetServerPort() const
{
// GamePort is reserved for game traffic, we want to go 1 above it to manage our server duties. i.e. Responding to search requests.
int port = 0;
EBUS_EVENT_ID_RESULT(port,GetTargetEntityId(),MultiplayerLobbyBus,GetGamePort);
port += 1;
return port;
}
}
@@ -0,0 +1,61 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Multiplayer/MultiplayerLobbyServiceWrapper/MultiplayerLobbyServiceWrapper.h"
namespace Multiplayer
{
MultiplayerLobbyServiceWrapper::MultiplayerLobbyServiceWrapper(const AZ::EntityId& multiplayerLobbyEntityId)
: m_multiplayerLobbyEntityId(multiplayerLobbyEntityId)
{
}
MultiplayerLobbyServiceWrapper::~MultiplayerLobbyServiceWrapper()
{
}
GridMate::GridSession* MultiplayerLobbyServiceWrapper::CreateServer(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc)
{
GridMate::GridSession* gridSession = nullptr;
if (StartSessionService(gridMate) && SanityCheck(gridMate))
{
gridSession = CreateServerForService(gridMate,carrierDesc);
}
return gridSession;
}
GridMate::GridSearch* MultiplayerLobbyServiceWrapper::ListServers(GridMate::IGridMate* gridMate)
{
GridMate::GridSearch* gridSearch = nullptr;
if (StartSessionService(gridMate) && SanityCheck(gridMate))
{
gridSearch = ListServersForService(gridMate);
}
return gridSearch;
}
GridMate::GridSession* MultiplayerLobbyServiceWrapper::JoinSession(GridMate::IGridMate* gridMate, GridMate::CarrierDesc& carrierDesc, const GridMate::SearchInfo* searchInfo)
{
GridMate::GridSession* gridSession = nullptr;
if (StartSessionService(gridMate) && SanityCheck(gridMate))
{
gridSession = JoinSessionForService(gridMate, carrierDesc, searchInfo);
}
return gridSession;
}
}
@@ -0,0 +1,19 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include "Multiplayer/MultiplayerUtils.h"
namespace Multiplayer
{
int NetSec::s_NetsecEnabled = 0;
int NetSec::s_NetsecVerifyClient = 0;
}
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
@@ -0,0 +1,18 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <platform.h>
#include <CryName.h>
#include <I3DEngine.h>
#include <ISerialize.h>
#include <IGem.h>
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_GridMateServiceWrapper_Android.h>
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#define AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE GridMate::Driver::BSD_AF_INET
#define AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY 0
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(...) static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE 0
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_TYPE_CLASS static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_WRAPPER 0
#define AZ_TRAIT_MULTIPLAYER_GRIDMATE_SERVICE_TYPE_ENUM static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT(...) // not implemented //
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT_VALUE 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_PROVO_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_XENIA_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_REGISTER_CVAR_SECURITY_DATA_DESC "Security data for session."
#define AZ_TRAIT_MULTIPLAYER_SESSION_NAME static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS 0
@@ -0,0 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_Traits_Android.h>
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,19 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Multiplayer/BehaviorContext/GridSystemContext_Unimplemented.cpp
../Common/Multiplayer/MultiplayerLobbyComponent_Unimplemented.cpp
Multiplayer_GridMateServiceWrapper_Platform.h
Multiplayer_GridMateServiceWrapper_Android.h
Multiplayer_Traits_Platform.h
Multiplayer_Traits_Android.h
)
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
namespace Multiplayer
{
struct SessionDesc;
}
namespace GridMate
{
struct GridSessionParam;
}
namespace Platform
{
bool FetchParam(const char* key, const Multiplayer::SessionDesc& sessionDesc, GridMate::GridSessionParam& p)
{
AZ_UNUSED(key);
AZ_UNUSED(sessionDesc);
AZ_UNUSED(p);
return false;
}
}
@@ -0,0 +1,40 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "Multiplayer_precompiled.h"
#include <AzCore/Component/EntityId.h>
namespace Multiplayer
{
class MultiplayerLobbyServiceWrapper;
}
namespace GridMate
{
struct CarrierDesc;
}
namespace Platform
{
bool ListServers(const AZStd::string& actionName, const AZ::EntityId& entityId, Multiplayer::MultiplayerLobbyServiceWrapper*& multiplayerLobbyServiceWrapper)
{
AZ_UNUSED(actionName);
AZ_UNUSED(entityId);
AZ_UNUSED(multiplayerLobbyServiceWrapper);
return false;
}
void InitCarrierDesc(GridMate::CarrierDesc& carrierDesc)
{
AZ_UNUSED(carrierDesc);
}
}
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_GridMateServiceWrapper_Linux.h>
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#define AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE GridMate::Driver::BSD_AF_INET
#define AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY 0
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(...) static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE 0
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_TYPE_CLASS static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_WRAPPER 0
#define AZ_TRAIT_MULTIPLAYER_GRIDMATE_SERVICE_TYPE_ENUM static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT(...) // not implemented //
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT_VALUE 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_PROVO_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_XENIA_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_REGISTER_CVAR_SECURITY_DATA_DESC "Security data for session."
#define AZ_TRAIT_MULTIPLAYER_SESSION_NAME static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS 0
@@ -0,0 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_Traits_Linux.h>
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(LY_COMPILE_DEFINITIONS
PUBLIC
NET_SUPPORT_SECURE_SOCKET_DRIVER=1
)
@@ -0,0 +1,24 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Multiplayer/BehaviorContext/GridSystemContext_Unimplemented.cpp
../Common/Multiplayer/MultiplayerLobbyComponent_Unimplemented.cpp
Multiplayer_GridMateServiceWrapper_Platform.h
Multiplayer_GridMateServiceWrapper_Linux.h
Multiplayer_Traits_Platform.h
Multiplayer_Traits_Linux.h
)
set(LY_COMPILE_DEFINITIONS
PRIVATE
NET_SUPPORT_SECURE_SOCKET_DRIVER=1
)
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_GridMateServiceWrapper_Mac.h>
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#define AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE GridMate::Driver::BSD_AF_INET
#define AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY 0
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(...) static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE 0
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_TYPE_CLASS static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_WRAPPER 0
#define AZ_TRAIT_MULTIPLAYER_GRIDMATE_SERVICE_TYPE_ENUM static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT(...) // not implemented //
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT_VALUE 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_PROVO_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_XENIA_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_REGISTER_CVAR_SECURITY_DATA_DESC "Security data for session."
#define AZ_TRAIT_MULTIPLAYER_SESSION_NAME static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS 0
@@ -0,0 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_Traits_Mac.h>
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,19 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Multiplayer/BehaviorContext/GridSystemContext_Unimplemented.cpp
../Common/Multiplayer/MultiplayerLobbyComponent_Unimplemented.cpp
Multiplayer_GridMateServiceWrapper_Platform.h
Multiplayer_GridMateServiceWrapper_Mac.h
Multiplayer_Traits_Platform.h
Multiplayer_Traits_Mac.h
)
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_GridMateServiceWrapper_Windows.h>
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -0,0 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_Traits_Windows.h>
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#define AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE GridMate::Driver::BSD_AF_INET
#define AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY 0
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(...) static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE 0
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_TYPE_CLASS static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_WRAPPER 0
#define AZ_TRAIT_MULTIPLAYER_GRIDMATE_SERVICE_TYPE_ENUM static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT(...) // not implemented //
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT_VALUE 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_PROVO_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_XENIA_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_REGISTER_CVAR_SECURITY_DATA_DESC "Security data for session."
#define AZ_TRAIT_MULTIPLAYER_SESSION_NAME static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS 0
@@ -0,0 +1,14 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(LY_COMPILE_DEFINITIONS
PUBLIC
NET_SUPPORT_SECURE_SOCKET_DRIVER=1
)
@@ -0,0 +1,24 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Multiplayer/BehaviorContext/GridSystemContext_Unimplemented.cpp
../Common/Multiplayer/MultiplayerLobbyComponent_Unimplemented.cpp
Multiplayer_GridMateServiceWrapper_Platform.h
Multiplayer_GridMateServiceWrapper_Windows.h
Multiplayer_Traits_Platform.h
Multiplayer_Traits_Windows.h
)
set(LY_COMPILE_DEFINITIONS
PRIVATE
NET_SUPPORT_SECURE_SOCKET_DRIVER=1
)
@@ -0,0 +1,14 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_GridMateServiceWrapper_iOS.h>
@@ -0,0 +1,12 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
@@ -0,0 +1,15 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Multiplayer_Traits_iOS.h>
@@ -0,0 +1,33 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#define AZ_TRAIT_MULTIPLAYER_ADDRESS_TYPE GridMate::Driver::BSD_AF_INET
#define AZ_TRAIT_MULTIPLAYER_ASSIGN_NETWORK_FAMILY 0
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_ID_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_CVAR_MATCH_MAKER_SESSION_TEMPLATE_DESC static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_DRIVER_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA(...) static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_ENABLE 0
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_CHECK_SECURITY_DATA_MESSAGE static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_TYPE_CLASS static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_GRID_SYSTEM_HAS_PLATFORM_SERVICE_WRAPPER 0
#define AZ_TRAIT_MULTIPLAYER_GRIDMATE_SERVICE_TYPE_ENUM static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT(...) // not implemented //
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ASSIGN_DEFAULT_PORT_VALUE 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_PROVO_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_LOBBY_SERVICE_ENABLE_XENIA_BUTTON 0
#define AZ_TRAIT_MULTIPLAYER_REGISTER_CVAR_SECURITY_DATA_DESC "Security data for session."
#define AZ_TRAIT_MULTIPLAYER_SESSION_NAME static_assert(false, "Unused")
#define AZ_TRAIT_MULTIPLAYER_USE_MATCH_MAKER_CVARS 0
@@ -0,0 +1,10 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
@@ -0,0 +1,19 @@
#
# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
# its licensors.
#
# For complete copyright and license terms please see the LICENSE at the root of this
# distribution (the "License"). All use of this software is governed by the License,
# or, if provided, by the license below or the license accompanying this file. Do not
# remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#
set(FILES
../Common/Multiplayer/BehaviorContext/GridSystemContext_Unimplemented.cpp
../Common/Multiplayer/MultiplayerLobbyComponent_Unimplemented.cpp
Multiplayer_GridMateServiceWrapper_Platform.h
Multiplayer_GridMateServiceWrapper_iOS.h
Multiplayer_Traits_Platform.h
Multiplayer_Traits_iOS.h
)