forked from 0ad/0ad
Netcode: Identify controller client via a secret key
The 'controller' of an MP game (the host in general, though dedicated
servers would change that) is currently whoever first tells the server
that it is. This can be abused since it relies on trusting the clients.
This changes that logic: the server defines a 'controller secret', and
the first client to sent the correct controller secret is the
controller. This is safe assuming the secret is unknowable enough (the
current solution wouldn't pass strict cryptography tests, but it's
likely good enough).
Reverts 1a3fb29ff3
, which introduced the 'trust the clients' mechanic,
as a change over 'the first local IP is controller'.
Necessary step towards dedicated server, if we want to use the regular
gamesetup (Refs #3556)
Differential Revision: https://code.wildfiregames.com/D3075
This was SVN commit r24952.
This commit is contained in:
parent
32c3f4fb90
commit
113fefeeb7
@ -20,7 +20,7 @@ const g_IsNetworked = Engine.HasNetClient();
|
||||
/**
|
||||
* Is this user in control of game settings (i.e. is a network server, or offline player).
|
||||
*/
|
||||
const g_IsController = !g_IsNetworked || Engine.HasNetServer();
|
||||
const g_IsController = !g_IsNetworked || Engine.IsNetController();
|
||||
|
||||
/**
|
||||
* Central data storing all settings relevant to the map generation and simulation.
|
||||
|
@ -33,7 +33,7 @@ class QuitConfirmationDefeat extends QuitConfirmation
|
||||
|
||||
unregisterSimulationUpdateHandler(this.confirmHandler);
|
||||
|
||||
// Don't ask for exit if other humans are still playing.
|
||||
// Don't invite the host to exit if other humans are still playing.
|
||||
let askExit = !Engine.HasNetServer() || g_Players.every((player, i) =>
|
||||
i == 0 ||
|
||||
player.state != "active" ||
|
||||
|
@ -48,7 +48,7 @@ const g_IsNetworked = Engine.HasNetClient();
|
||||
/**
|
||||
* Is this user in control of game settings (i.e. is a network server, or offline player).
|
||||
*/
|
||||
var g_IsController = !g_IsNetworked || Engine.HasNetServer();
|
||||
var g_IsController = !g_IsNetworked || Engine.IsNetController();
|
||||
|
||||
/**
|
||||
* Whether we have finished the synchronization and
|
||||
|
@ -71,12 +71,11 @@ private:
|
||||
CNetClient& m_Client;
|
||||
};
|
||||
|
||||
CNetClient::CNetClient(CGame* game, bool isLocalClient) :
|
||||
CNetClient::CNetClient(CGame* game) :
|
||||
m_Session(NULL),
|
||||
m_UserName(L"anonymous"),
|
||||
m_HostID((u32)-1), m_ClientTurnManager(NULL), m_Game(game),
|
||||
m_GameAttributes(game->GetSimulation2()->GetScriptInterface().GetGeneralJSContext()),
|
||||
m_IsLocalClient(isLocalClient),
|
||||
m_LastConnectionCheck(0),
|
||||
m_ServerAddress(),
|
||||
m_ServerPort(0),
|
||||
@ -180,10 +179,16 @@ void CNetClient::SetGamePassword(const CStr& hashedPassword)
|
||||
m_Password = hashedPassword;
|
||||
}
|
||||
|
||||
void CNetClient::SetControllerSecret(const std::string& secret)
|
||||
{
|
||||
m_ControllerSecret = secret;
|
||||
}
|
||||
|
||||
|
||||
bool CNetClient::SetupConnection(ENetHost* enetClient)
|
||||
{
|
||||
CNetClientSession* session = new CNetClientSession(*this);
|
||||
bool ok = session->Connect(m_ServerAddress, m_ServerPort, m_IsLocalClient, enetClient);
|
||||
bool ok = session->Connect(m_ServerAddress, m_ServerPort, enetClient);
|
||||
SetAndOwnSession(session);
|
||||
m_PollingThread = std::thread(Threading::HandleExceptions<CNetClientSession::RunNetLoop>::Wrapper, m_Session);
|
||||
return ok;
|
||||
@ -576,7 +581,7 @@ void CNetClient::SendAuthenticateMessage()
|
||||
CAuthenticateMessage authenticate;
|
||||
authenticate.m_Name = m_UserName;
|
||||
authenticate.m_Password = m_Password;
|
||||
authenticate.m_IsLocalClient = m_IsLocalClient;
|
||||
authenticate.m_ControllerSecret = m_ControllerSecret;
|
||||
SendMessage(&authenticate);
|
||||
}
|
||||
|
||||
@ -657,6 +662,7 @@ bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
|
||||
|
||||
client->m_HostID = message->m_HostID;
|
||||
client->m_Rejoin = message->m_Code == ARC_OK_REJOINING;
|
||||
client->m_IsController = message->m_IsController;
|
||||
|
||||
client->PushGuiMessage(
|
||||
"type", "netstatus",
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
* Construct a client associated with the given game object.
|
||||
* The game must exist for the lifetime of this object.
|
||||
*/
|
||||
CNetClient(CGame* game, bool isLocalClient);
|
||||
CNetClient(CGame* game);
|
||||
|
||||
virtual ~CNetClient();
|
||||
|
||||
@ -99,6 +99,10 @@ public:
|
||||
*/
|
||||
void SetHostingPlayerName(const CStr& hostingPlayerName);
|
||||
|
||||
void SetControllerSecret(const std::string& secret);
|
||||
|
||||
bool IsController() const { return m_IsController; }
|
||||
|
||||
/**
|
||||
* Set the game password.
|
||||
*/
|
||||
@ -303,6 +307,12 @@ private:
|
||||
*/
|
||||
CStr m_Password;
|
||||
|
||||
/// The 'secret' used to identify the controller of the game.
|
||||
std::string m_ControllerSecret;
|
||||
|
||||
/// Note that this is just a "gui hint" with no actual impact on being controller.
|
||||
bool m_IsController = false;
|
||||
|
||||
/// Current network session (or NULL if not connected)
|
||||
CNetClientSession* m_Session;
|
||||
|
||||
@ -317,9 +327,6 @@ private:
|
||||
/// True if the player is currently rejoining or has already rejoined the game.
|
||||
bool m_Rejoin;
|
||||
|
||||
/// Whether to prevent the client of the host from timing out
|
||||
bool m_IsLocalClient;
|
||||
|
||||
/// Latest copy of game setup attributes heard from the server
|
||||
JS::PersistentRootedValue m_GameAttributes;
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#define PS_PROTOCOL_MAGIC 0x5073013f // 'P', 's', 0x01, '?'
|
||||
#define PS_PROTOCOL_MAGIC_RESPONSE 0x50630121 // 'P', 'c', 0x01, '!'
|
||||
#define PS_PROTOCOL_VERSION 0x01010016 // Arbitrary protocol
|
||||
#define PS_PROTOCOL_VERSION 0x01010017 // Arbitrary protocol
|
||||
#define PS_DEFAULT_PORT 0x5073 // 'P', 's'
|
||||
|
||||
// Set when lobby authentication is required. Used in the SrvHandshakeResponseMessage.
|
||||
@ -122,12 +122,13 @@ END_NMT_CLASS()
|
||||
START_NMT_CLASS_(Authenticate, NMT_AUTHENTICATE)
|
||||
NMT_FIELD(CStrW, m_Name)
|
||||
NMT_FIELD_SECRET(CStr, m_Password)
|
||||
NMT_FIELD_INT(m_IsLocalClient, u8, 1)
|
||||
NMT_FIELD_SECRET(CStr, m_ControllerSecret)
|
||||
END_NMT_CLASS()
|
||||
|
||||
START_NMT_CLASS_(AuthenticateResult, NMT_AUTHENTICATE_RESULT)
|
||||
NMT_FIELD_INT(m_Code, u32, 4)
|
||||
NMT_FIELD_INT(m_HostID, u32, 2)
|
||||
NMT_FIELD_INT(m_IsController, u8, 1)
|
||||
NMT_FIELD(CStrW, m_Message)
|
||||
END_NMT_CLASS()
|
||||
|
||||
|
@ -137,7 +137,7 @@ CNetServerWorker::CNetServerWorker(bool useLobbyAuth, int autostartPlayers) :
|
||||
m_LobbyAuth(useLobbyAuth),
|
||||
m_Shutdown(false),
|
||||
m_ScriptInterface(NULL),
|
||||
m_NextHostID(1), m_Host(NULL), m_HostGUID(), m_Stats(NULL),
|
||||
m_NextHostID(1), m_Host(NULL), m_ControllerGUID(), m_Stats(NULL),
|
||||
m_LastConnectionCheck(0)
|
||||
{
|
||||
m_State = SERVER_STATE_UNCONNECTED;
|
||||
@ -187,6 +187,13 @@ void CNetServerWorker::SetPassword(const CStr& hashedPassword)
|
||||
m_Password = hashedPassword;
|
||||
}
|
||||
|
||||
|
||||
void CNetServerWorker::SetControllerSecret(const std::string& secret)
|
||||
{
|
||||
m_ControllerSecret = secret;
|
||||
}
|
||||
|
||||
|
||||
bool CNetServerWorker::SetupConnection(const u16 port)
|
||||
{
|
||||
ENSURE(m_State == SERVER_STATE_UNCONNECTED);
|
||||
@ -714,9 +721,6 @@ void CNetServerWorker::OnUserJoin(CNetServerSession* session)
|
||||
{
|
||||
AddPlayer(session->GetGUID(), session->GetUserName());
|
||||
|
||||
if (m_HostGUID.empty() && session->IsLocalClient())
|
||||
m_HostGUID = session->GetGUID();
|
||||
|
||||
CGameSetupMessage gameSetupMessage(GetScriptInterface());
|
||||
gameSetupMessage.m_Data = m_GameAttributes;
|
||||
session->SendMessage(&gameSetupMessage);
|
||||
@ -814,7 +818,7 @@ void CNetServerWorker::KickPlayer(const CStrW& playerName, const bool ban)
|
||||
[&](CNetServerSession* session) { return session->GetUserName() == playerName; });
|
||||
|
||||
// and return if no one or the host has that name
|
||||
if (it == m_Sessions.end() || (*it)->GetGUID() == m_HostGUID)
|
||||
if (it == m_Sessions.end() || (*it)->GetGUID() == m_ControllerGUID)
|
||||
return;
|
||||
|
||||
if (ban)
|
||||
@ -1110,12 +1114,23 @@ bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
|
||||
|
||||
session->SetUserName(username);
|
||||
session->SetHostID(newHostID);
|
||||
session->SetLocalClient(message->m_IsLocalClient);
|
||||
|
||||
CAuthenticateResultMessage authenticateResult;
|
||||
authenticateResult.m_Code = isRejoining ? ARC_OK_REJOINING : ARC_OK;
|
||||
authenticateResult.m_HostID = newHostID;
|
||||
authenticateResult.m_Message = L"Logged in";
|
||||
authenticateResult.m_IsController = 0;
|
||||
|
||||
if (message->m_ControllerSecret == server.m_ControllerSecret)
|
||||
{
|
||||
if (server.m_ControllerGUID.empty())
|
||||
{
|
||||
server.m_ControllerGUID = session->GetGUID();
|
||||
authenticateResult.m_IsController = 1;
|
||||
}
|
||||
// TODO: we could probably handle having several controllers, or swapping?
|
||||
}
|
||||
|
||||
session->SendMessage(&authenticateResult);
|
||||
|
||||
server.OnUserJoin(session);
|
||||
@ -1247,7 +1262,7 @@ bool CNetServerWorker::OnClearAllReady(void* context, CFsmEvent* event)
|
||||
CNetServerSession* session = (CNetServerSession*)context;
|
||||
CNetServerWorker& server = session->GetServer();
|
||||
|
||||
if (session->GetGUID() == server.m_HostGUID)
|
||||
if (session->GetGUID() == server.m_ControllerGUID)
|
||||
server.ClearAllPlayerReady();
|
||||
|
||||
return true;
|
||||
@ -1265,7 +1280,7 @@ bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event)
|
||||
if (server.m_State != SERVER_STATE_PREGAME)
|
||||
return true;
|
||||
|
||||
if (session->GetGUID() == server.m_HostGUID)
|
||||
if (session->GetGUID() == server.m_ControllerGUID)
|
||||
{
|
||||
CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef();
|
||||
server.UpdateGameAttributes(&(message->m_Data));
|
||||
@ -1279,7 +1294,7 @@ bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event)
|
||||
CNetServerSession* session = (CNetServerSession*)context;
|
||||
CNetServerWorker& server = session->GetServer();
|
||||
|
||||
if (session->GetGUID() == server.m_HostGUID)
|
||||
if (session->GetGUID() == server.m_ControllerGUID)
|
||||
{
|
||||
CAssignPlayerMessage* message = (CAssignPlayerMessage*)event->GetParamRef();
|
||||
server.AssignPlayer(message->m_PlayerID, message->m_GUID);
|
||||
@ -1293,7 +1308,7 @@ bool CNetServerWorker::OnStartGame(void* context, CFsmEvent* event)
|
||||
CNetServerSession* session = (CNetServerSession*)context;
|
||||
CNetServerWorker& server = session->GetServer();
|
||||
|
||||
if (session->GetGUID() == server.m_HostGUID)
|
||||
if (session->GetGUID() == server.m_ControllerGUID)
|
||||
server.StartGame();
|
||||
|
||||
return true;
|
||||
@ -1413,7 +1428,7 @@ bool CNetServerWorker::OnKickPlayer(void* context, CFsmEvent* event)
|
||||
CNetServerSession* session = (CNetServerSession*)context;
|
||||
CNetServerWorker& server = session->GetServer();
|
||||
|
||||
if (session->GetGUID() == server.m_HostGUID)
|
||||
if (session->GetGUID() == server.m_ControllerGUID)
|
||||
{
|
||||
CKickedMessage* message = (CKickedMessage*)event->GetParamRef();
|
||||
server.KickPlayer(message->m_Name, message->m_Ban);
|
||||
@ -1659,6 +1674,12 @@ void CNetServer::SetPassword(const CStr& password)
|
||||
m_Worker->SetPassword(password);
|
||||
}
|
||||
|
||||
void CNetServer::SetControllerSecret(const std::string& secret)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_Worker->m_WorkerMutex);
|
||||
m_Worker->SetControllerSecret(secret);
|
||||
}
|
||||
|
||||
void CNetServer::StartGame()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_Worker->m_WorkerMutex);
|
||||
|
@ -109,7 +109,7 @@ class CNetServer
|
||||
public:
|
||||
/**
|
||||
* Construct a new network server.
|
||||
* @param autostartPlayers if positive then StartGame will be called automatically
|
||||
* @param autostartPlayers - if positive then StartGame will be called automatically
|
||||
* once this many players are connected (intended for the command-line testing mode).
|
||||
*/
|
||||
CNetServer(bool useLobbyAuth = false, int autostartPlayers = -1);
|
||||
@ -173,6 +173,8 @@ public:
|
||||
|
||||
void SetPassword(const CStr& password);
|
||||
|
||||
void SetControllerSecret(const std::string& secret);
|
||||
|
||||
private:
|
||||
CNetServerWorker* m_Worker;
|
||||
const bool m_LobbyAuth;
|
||||
@ -226,6 +228,8 @@ private:
|
||||
|
||||
void SetPassword(const CStr& hashedPassword);
|
||||
|
||||
void SetControllerSecret(const std::string& secret);
|
||||
|
||||
/**
|
||||
* Begin listening for network connections.
|
||||
* @return true on success, false on error (e.g. port already in use)
|
||||
@ -369,7 +373,15 @@ private:
|
||||
|
||||
CNetServerTurnManager* m_ServerTurnManager;
|
||||
|
||||
CStr m_HostGUID;
|
||||
/**
|
||||
* The GUID of the client in control of the game (the 'host' from the players' perspective).
|
||||
*/
|
||||
CStr m_ControllerGUID;
|
||||
|
||||
/**
|
||||
* The 'secret' used to identify the controller of the game.
|
||||
*/
|
||||
std::string m_ControllerSecret;
|
||||
|
||||
/**
|
||||
* A copy of all simulation commands received so far, indexed by
|
||||
|
@ -33,7 +33,7 @@ constexpr int CHANNEL_COUNT = 1;
|
||||
|
||||
CNetClientSession::CNetClientSession(CNetClient& client) :
|
||||
m_Client(client), m_FileTransferer(this), m_Host(nullptr), m_Server(nullptr),
|
||||
m_Stats(nullptr), m_IsLocalClient(false), m_IncomingMessages(16), m_OutgoingMessages(16),
|
||||
m_Stats(nullptr), m_IncomingMessages(16), m_OutgoingMessages(16),
|
||||
m_LoopRunning(false), m_ShouldShutdown(false), m_MeanRTT(0), m_LastReceivedTime(0)
|
||||
{
|
||||
}
|
||||
@ -55,7 +55,7 @@ CNetClientSession::~CNetClientSession()
|
||||
}
|
||||
}
|
||||
|
||||
bool CNetClientSession::Connect(const CStr& server, const u16 port, const bool isLocalClient, ENetHost* enetClient)
|
||||
bool CNetClientSession::Connect(const CStr& server, const u16 port, ENetHost* enetClient)
|
||||
{
|
||||
ENSURE(!m_LoopRunning);
|
||||
ENSURE(!m_Host);
|
||||
@ -84,7 +84,6 @@ bool CNetClientSession::Connect(const CStr& server, const u16 port, const bool i
|
||||
|
||||
m_Host = host;
|
||||
m_Server = peer;
|
||||
m_IsLocalClient = isLocalClient;
|
||||
|
||||
m_Stats = new CNetStatsTable(m_Server);
|
||||
if (CProfileViewer::IsInitialised())
|
||||
@ -236,7 +235,7 @@ u32 CNetClientSession::GetMeanRTT() const
|
||||
}
|
||||
|
||||
CNetServerSession::CNetServerSession(CNetServerWorker& server, ENetPeer* peer) :
|
||||
m_Server(server), m_FileTransferer(this), m_Peer(peer), m_IsLocalClient(false), m_HostID(0), m_GUID(), m_UserName()
|
||||
m_Server(server), m_FileTransferer(this), m_Peer(peer), m_HostID(0), m_GUID(), m_UserName()
|
||||
{
|
||||
}
|
||||
|
||||
@ -283,16 +282,3 @@ bool CNetServerSession::SendMessage(const CNetMessage* message)
|
||||
{
|
||||
return m_Server.SendMessage(m_Peer, message);
|
||||
}
|
||||
|
||||
bool CNetServerSession::IsLocalClient() const
|
||||
{
|
||||
return m_IsLocalClient;
|
||||
}
|
||||
|
||||
void CNetServerSession::SetLocalClient(bool isLocalClient)
|
||||
{
|
||||
m_IsLocalClient = isLocalClient;
|
||||
|
||||
if (!isLocalClient)
|
||||
return;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
CNetClientSession(CNetClient& client);
|
||||
~CNetClientSession();
|
||||
|
||||
bool Connect(const CStr& server, const u16 port, const bool isLocalClient, ENetHost* enetClient);
|
||||
bool Connect(const CStr& server, const u16 port, ENetHost* enetClient);
|
||||
|
||||
/**
|
||||
* The client NetSession is threaded to avoid getting timeouts if the main thread hangs.
|
||||
@ -140,8 +140,6 @@ private:
|
||||
ENetHost* m_Host;
|
||||
ENetPeer* m_Server;
|
||||
CNetStatsTable* m_Stats;
|
||||
|
||||
bool m_IsLocalClient;
|
||||
};
|
||||
|
||||
|
||||
@ -173,11 +171,6 @@ public:
|
||||
|
||||
u32 GetIPAddress() const;
|
||||
|
||||
/**
|
||||
* Whether this client is running in the same process as the server.
|
||||
*/
|
||||
bool IsLocalClient() const;
|
||||
|
||||
/**
|
||||
* Number of milliseconds since the latest packet of that client was received.
|
||||
*/
|
||||
@ -203,11 +196,6 @@ public:
|
||||
*/
|
||||
void DisconnectNow(NetDisconnectReason reason);
|
||||
|
||||
/**
|
||||
* Prevent timeouts for the client running in the same process as the server.
|
||||
*/
|
||||
void SetLocalClient(bool isLocalClient);
|
||||
|
||||
/**
|
||||
* Send a message to the client.
|
||||
*/
|
||||
@ -226,8 +214,6 @@ private:
|
||||
CStrW m_UserName;
|
||||
u32 m_HostID;
|
||||
CStr m_Password;
|
||||
|
||||
bool m_IsLocalClient;
|
||||
};
|
||||
|
||||
#endif // NETSESSION_H
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "network/StunClient.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Game.h"
|
||||
#include "ps/GUID.h"
|
||||
#include "ps/Util.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
|
||||
@ -39,6 +40,11 @@ u16 JSI_Network::GetDefaultPort(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
|
||||
return PS_DEFAULT_PORT;
|
||||
}
|
||||
|
||||
bool JSI_Network::IsNetController(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
|
||||
{
|
||||
return !!g_NetClient && g_NetClient->IsController();
|
||||
}
|
||||
|
||||
bool JSI_Network::HasNetServer(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
|
||||
{
|
||||
return !!g_NetServer;
|
||||
@ -120,16 +126,21 @@ void JSI_Network::StartNetworkHost(ScriptInterface::CmptPrivate* pCmptPrivate, c
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate a secret to identify the host client.
|
||||
std::string secret = ps_generate_guid();
|
||||
|
||||
// We will get hashed password from clients, so hash it once for server
|
||||
CStr hashedPass = HashPassword(password);
|
||||
g_NetServer->SetPassword(hashedPass);
|
||||
g_NetServer->SetControllerSecret(secret);
|
||||
|
||||
g_Game = new CGame(true);
|
||||
g_NetClient = new CNetClient(g_Game, true);
|
||||
g_NetClient = new CNetClient(g_Game);
|
||||
g_NetClient->SetUserName(playerName);
|
||||
g_NetClient->SetHostingPlayerName(hostLobbyName);
|
||||
g_NetClient->SetGamePassword(hashedPass);
|
||||
g_NetClient->SetupServerData("127.0.0.1", serverPort, false);
|
||||
g_NetClient->SetControllerSecret(secret);
|
||||
|
||||
if (!g_NetClient->SetupConnection(nullptr))
|
||||
{
|
||||
@ -147,7 +158,7 @@ void JSI_Network::StartNetworkJoin(ScriptInterface::CmptPrivate* pCmptPrivate, c
|
||||
ENSURE(!g_Game);
|
||||
|
||||
g_Game = new CGame(true);
|
||||
g_NetClient = new CNetClient(g_Game, false);
|
||||
g_NetClient = new CNetClient(g_Game);
|
||||
g_NetClient->SetUserName(playerName);
|
||||
g_NetClient->SetHostingPlayerName(hostJID.substr(0, hostJID.find("@")));
|
||||
g_NetClient->SetupServerData(serverAddress, serverPort, useSTUN);
|
||||
@ -170,7 +181,7 @@ void JSI_Network::StartNetworkJoinLobby(ScriptInterface::CmptPrivate* UNUSED(pCm
|
||||
|
||||
CStr hashedPass = HashPassword(password);
|
||||
g_Game = new CGame(true);
|
||||
g_NetClient = new CNetClient(g_Game, false);
|
||||
g_NetClient = new CNetClient(g_Game);
|
||||
g_NetClient->SetUserName(playerName);
|
||||
g_NetClient->SetHostingPlayerName(hostJID.substr(0, hostJID.find("@")));
|
||||
g_NetClient->SetGamePassword(hashedPass);
|
||||
@ -269,6 +280,7 @@ void JSI_Network::SetTurnLength(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivat
|
||||
void JSI_Network::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
|
||||
{
|
||||
scriptInterface.RegisterFunction<u16, &GetDefaultPort>("GetDefaultPort");
|
||||
scriptInterface.RegisterFunction<bool, &IsNetController>("IsNetController");
|
||||
scriptInterface.RegisterFunction<bool, &HasNetServer>("HasNetServer");
|
||||
scriptInterface.RegisterFunction<bool, &HasNetClient>("HasNetClient");
|
||||
scriptInterface.RegisterFunction<void, CStrW, u16, CStr, bool, CStr, &StartNetworkHost>("StartNetworkHost");
|
||||
|
@ -25,6 +25,7 @@
|
||||
namespace JSI_Network
|
||||
{
|
||||
u16 GetDefaultPort(ScriptInterface::CmptPrivate* pCmptPrivate);
|
||||
bool IsNetController(ScriptInterface::CmptPrivate* pCmptPrivate);
|
||||
bool HasNetServer(ScriptInterface::CmptPrivate* pCmptPrivate);
|
||||
bool HasNetClient(ScriptInterface::CmptPrivate* pCmptPrivate);
|
||||
void StartNetworkGame(ScriptInterface::CmptPrivate* pCmptPrivate);
|
||||
|
@ -150,7 +150,7 @@ public:
|
||||
CGame client2Game(false);
|
||||
CGame client3Game(false);
|
||||
|
||||
CNetServer server;
|
||||
CNetServer server("no_secret");
|
||||
|
||||
JS::RootedValue attrs(rq.cx);
|
||||
ScriptInterface::CreateObject(
|
||||
@ -163,9 +163,9 @@ public:
|
||||
|
||||
server.UpdateGameAttributes(&attrs, scriptInterface);
|
||||
|
||||
CNetClient client1(&client1Game, false);
|
||||
CNetClient client2(&client2Game, false);
|
||||
CNetClient client3(&client3Game, false);
|
||||
CNetClient client1(&client1Game);
|
||||
CNetClient client2(&client2Game);
|
||||
CNetClient client3(&client3Game);
|
||||
|
||||
clients.push_back(&client1);
|
||||
clients.push_back(&client2);
|
||||
@ -229,7 +229,7 @@ public:
|
||||
CGame client2Game(false);
|
||||
CGame client3Game(false);
|
||||
|
||||
CNetServer server;
|
||||
CNetServer server("no_secret");
|
||||
|
||||
JS::RootedValue attrs(rq.cx);
|
||||
ScriptInterface::CreateObject(
|
||||
@ -242,9 +242,9 @@ public:
|
||||
|
||||
server.UpdateGameAttributes(&attrs, scriptInterface);
|
||||
|
||||
CNetClient client1(&client1Game, false);
|
||||
CNetClient client2(&client2Game, false);
|
||||
CNetClient client3(&client3Game, false);
|
||||
CNetClient client1(&client1Game);
|
||||
CNetClient client2(&client2Game);
|
||||
CNetClient client3(&client3Game);
|
||||
|
||||
client1.SetUserName(L"alice");
|
||||
client2.SetUserName(L"bob");
|
||||
@ -303,7 +303,7 @@ public:
|
||||
debug_printf("==== Connecting client 2B\n");
|
||||
|
||||
CGame client2BGame(false);
|
||||
CNetClient client2B(&client2BGame, false);
|
||||
CNetClient client2B(&client2BGame);
|
||||
client2B.SetUserName(L"bob");
|
||||
clients.push_back(&client2B);
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "ps/GameSetup/CmdLineArgs.h"
|
||||
#include "ps/GameSetup/HWDetect.h"
|
||||
#include "ps/Globals.h"
|
||||
#include "ps/GUID.h"
|
||||
#include "ps/Hotkey.h"
|
||||
#include "ps/Joystick.h"
|
||||
#include "ps/Loader.h"
|
||||
@ -1556,23 +1557,27 @@ bool Autostart(const CmdLineArgs& args)
|
||||
if (args.Has("autostart-host-players"))
|
||||
maxPlayers = args.Get("autostart-host-players").ToUInt();
|
||||
|
||||
g_NetServer = new CNetServer(false, maxPlayers);
|
||||
// Generate a secret to identify the host client.
|
||||
std::string secret = ps_generate_guid();
|
||||
|
||||
g_NetServer = new CNetServer(false, maxPlayers);
|
||||
g_NetServer->SetControllerSecret(secret);
|
||||
g_NetServer->UpdateGameAttributes(&attrs, scriptInterface);
|
||||
|
||||
bool ok = g_NetServer->SetupConnection(PS_DEFAULT_PORT);
|
||||
ENSURE(ok);
|
||||
|
||||
g_NetClient = new CNetClient(g_Game, true);
|
||||
g_NetClient = new CNetClient(g_Game);
|
||||
g_NetClient->SetUserName(userName);
|
||||
g_NetClient->SetupServerData("127.0.0.1", PS_DEFAULT_PORT, false);
|
||||
g_NetClient->SetControllerSecret(secret);
|
||||
g_NetClient->SetupConnection(nullptr);
|
||||
}
|
||||
else if (args.Has("autostart-client"))
|
||||
{
|
||||
InitPsAutostart(true, attrs);
|
||||
|
||||
g_NetClient = new CNetClient(g_Game, false);
|
||||
g_NetClient = new CNetClient(g_Game);
|
||||
g_NetClient->SetUserName(userName);
|
||||
|
||||
CStr ip = args.Get("autostart-client");
|
||||
|
Loading…
Reference in New Issue
Block a user