mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-06-20 23:24:16 +00:00
Remove UpdateInitAttributes from CNetClient
The init-attributes can only be changed before the worker runs. It isn't used before the worker runs. This changes it so that it has to be passed when the server starts. With this the `m_InitAttributesQueue` can be removed.
This commit is contained in:
@@ -162,7 +162,7 @@ bool CNetServerWorker::CheckPassword(const std::string& password, const std::str
|
||||
}
|
||||
|
||||
|
||||
bool CNetServerWorker::SetupConnection(const u16 port)
|
||||
bool CNetServerWorker::SetupConnection(const u16 port, std::string initAttributes)
|
||||
{
|
||||
ENSURE(m_State == SERVER_STATE_UNCONNECTED);
|
||||
ENSURE(!m_Host);
|
||||
@@ -187,7 +187,8 @@ bool CNetServerWorker::SetupConnection(const u16 port)
|
||||
m_State = SERVER_STATE_PREGAME;
|
||||
|
||||
// Launch the worker thread
|
||||
m_WorkerThread = std::thread(Threading::HandleExceptions<RunThread>::Wrapper, this);
|
||||
m_WorkerThread = std::thread{Threading::HandleExceptions<RunThread>::Wrapper, this,
|
||||
std::move(initAttributes)};
|
||||
|
||||
#if CONFIG2_MINIUPNPC
|
||||
// Launch the UPnP thread
|
||||
@@ -383,14 +384,14 @@ bool CNetServerWorker::Multicast(const CNetMessage* message,
|
||||
return ok;
|
||||
}
|
||||
|
||||
void CNetServerWorker::RunThread(CNetServerWorker* data)
|
||||
void CNetServerWorker::RunThread(CNetServerWorker* data, const std::string& initAttributes)
|
||||
{
|
||||
debug_SetThreadName("NetServer");
|
||||
|
||||
data->Run();
|
||||
data->Run(initAttributes);
|
||||
}
|
||||
|
||||
void CNetServerWorker::Run()
|
||||
void CNetServerWorker::Run(const std::string& initAttributes)
|
||||
{
|
||||
// The script context uses the profiler and therefore the thread must be registered before the context is created
|
||||
g_Profiler2.RegisterCurrentThread("Net server");
|
||||
@@ -400,6 +401,14 @@ void CNetServerWorker::Run()
|
||||
m_ScriptInterface = new ScriptInterface("Engine", "Net server", netServerContext);
|
||||
m_InitAttributes.init(m_ScriptInterface->GetGeneralJSContext(), JS::UndefinedValue());
|
||||
|
||||
if (!initAttributes.empty())
|
||||
{
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
JS::RootedValue gameAttributesVal(rq.cx);
|
||||
Script::ParseJSON(rq, std::move(initAttributes), &gameAttributesVal);
|
||||
m_InitAttributes = gameAttributesVal;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!RunStep())
|
||||
@@ -426,7 +435,6 @@ bool CNetServerWorker::RunStep()
|
||||
ScriptRequest rq(m_ScriptInterface);
|
||||
|
||||
std::vector<bool> newStartGame;
|
||||
std::vector<std::string> newGameAttributes;
|
||||
std::vector<std::pair<CStr, CStr>> newLobbyAuths;
|
||||
std::vector<u32> newTurnLength;
|
||||
|
||||
@@ -437,23 +445,10 @@ bool CNetServerWorker::RunStep()
|
||||
return false;
|
||||
|
||||
newStartGame.swap(m_StartGameQueue);
|
||||
newGameAttributes.swap(m_InitAttributesQueue);
|
||||
newLobbyAuths.swap(m_LobbyAuthQueue);
|
||||
newTurnLength.swap(m_TurnLengthQueue);
|
||||
}
|
||||
|
||||
if (!newGameAttributes.empty())
|
||||
{
|
||||
if (m_State != SERVER_STATE_UNCONNECTED && m_State != SERVER_STATE_PREGAME)
|
||||
LOGERROR("NetServer: Init Attributes cannot be changed after the server starts loading.");
|
||||
else
|
||||
{
|
||||
JS::RootedValue gameAttributesVal(rq.cx);
|
||||
Script::ParseJSON(rq, newGameAttributes.back(), &gameAttributesVal);
|
||||
m_InitAttributes = gameAttributesVal;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newTurnLength.empty())
|
||||
SetTurnLength(newTurnLength.back());
|
||||
|
||||
@@ -1703,9 +1698,9 @@ bool CNetServer::UseLobbyAuth() const
|
||||
return m_LobbyAuth;
|
||||
}
|
||||
|
||||
bool CNetServer::SetupConnection(const u16 port)
|
||||
bool CNetServer::SetupConnection(const u16 port, std::string initAttributes)
|
||||
{
|
||||
return m_Worker->SetupConnection(port);
|
||||
return m_Worker->SetupConnection(port, std::move(initAttributes));
|
||||
}
|
||||
|
||||
CStr CNetServer::GetPublicIp() const
|
||||
@@ -1762,16 +1757,6 @@ void CNetServer::StartGame()
|
||||
m_Worker->m_StartGameQueue.push_back(true);
|
||||
}
|
||||
|
||||
void CNetServer::UpdateInitAttributes(JS::MutableHandleValue attrs, const ScriptRequest& rq)
|
||||
{
|
||||
// Pass the attributes as JSON, since that's the easiest safe
|
||||
// cross-thread way of passing script data
|
||||
std::string attrsJSON = Script::StringifyJSON(rq, attrs, false);
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_Worker->m_WorkerMutex);
|
||||
m_Worker->m_InitAttributesQueue.push_back(attrsJSON);
|
||||
}
|
||||
|
||||
void CNetServer::OnLobbyAuth(const CStr& name, const CStr& token)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_Worker->m_WorkerMutex);
|
||||
|
||||
@@ -121,21 +121,14 @@ public:
|
||||
* This function is synchronous (it won't return until the connection is established).
|
||||
* @return true on success, false on error (e.g. port already in use)
|
||||
*/
|
||||
bool SetupConnection(const u16 port);
|
||||
bool SetupConnection(const u16 port, std::string initAttributes = {});
|
||||
|
||||
/**
|
||||
* Call from the GUI to asynchronously notify all clients that they should start loading the game.
|
||||
* UpdateInitAttributes must be called at least once.
|
||||
* SetupConnection must be called at least once.
|
||||
*/
|
||||
void StartGame();
|
||||
|
||||
/**
|
||||
* Call from the GUI to update the game setup attributes.
|
||||
* The changes won't be propagated to clients until game start.
|
||||
* @param attrs init attributes, in the script context of rq
|
||||
*/
|
||||
void UpdateInitAttributes(JS::MutableHandleValue attrs, const ScriptRequest& rq);
|
||||
|
||||
/**
|
||||
* Set the turn length to a fixed value.
|
||||
* TODO: we should replace this with some adapative lag-dependent computation.
|
||||
@@ -237,7 +230,7 @@ private:
|
||||
* Begin listening for network connections.
|
||||
* @return true on success, false on error (e.g. port already in use)
|
||||
*/
|
||||
bool SetupConnection(const u16 port);
|
||||
bool SetupConnection(const u16 port, std::string initAttributes);
|
||||
|
||||
/**
|
||||
* The given GUID will be (re)assigned to the given player ID.
|
||||
@@ -428,8 +421,8 @@ private:
|
||||
std::thread m_UPnPThread;
|
||||
#endif
|
||||
|
||||
static void RunThread(CNetServerWorker* data);
|
||||
void Run();
|
||||
static void RunThread(CNetServerWorker* data, const std::string& initAttributes);
|
||||
void Run(const std::string& initAttributes);
|
||||
bool RunStep();
|
||||
|
||||
std::thread m_WorkerThread;
|
||||
@@ -440,7 +433,6 @@ private:
|
||||
|
||||
// Queues for messages sent by the game thread (protected by m_WorkerMutex):
|
||||
std::vector<bool> m_StartGameQueue;
|
||||
std::vector<std::string> m_InitAttributesQueue;
|
||||
std::vector<std::pair<CStr, CStr>> m_LobbyAuthQueue;
|
||||
std::vector<u32> m_TurnLengthQueue;
|
||||
};
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "ps/Game.h"
|
||||
#include "ps/Loader.h"
|
||||
#include "ps/XML/Xeromyces.h"
|
||||
#include "scriptinterface/JSON.h"
|
||||
#include "scriptinterface/Object.h"
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/ScriptRequest.h"
|
||||
@@ -87,9 +88,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
void connect(CNetServer& server, const std::vector<CNetClient*>& clients)
|
||||
void connect(CNetServer& server, const std::vector<CNetClient*>& clients, std::string initAttributes)
|
||||
{
|
||||
TS_ASSERT(server.SetupConnection(PS_DEFAULT_PORT));
|
||||
TS_ASSERT(server.SetupConnection(PS_DEFAULT_PORT, std::move(initAttributes)));
|
||||
for (CNetClient* client: clients)
|
||||
{
|
||||
TS_ASSERT(client->SetupConnection(nullptr));
|
||||
@@ -179,8 +180,6 @@ public:
|
||||
"mapPath", "maps/scenarios/",
|
||||
"thing", "example");
|
||||
|
||||
server.UpdateInitAttributes(&attrs, scriptInterface);
|
||||
|
||||
CNetClient client1(&client1Game, "127.0.0.1", PS_DEFAULT_PORT);
|
||||
CNetClient client2(&client2Game, "127.0.0.1", PS_DEFAULT_PORT);
|
||||
CNetClient client3(&client3Game, "127.0.0.1", PS_DEFAULT_PORT);
|
||||
@@ -189,7 +188,7 @@ public:
|
||||
clients.push_back(&client2);
|
||||
clients.push_back(&client3);
|
||||
|
||||
connect(server, clients);
|
||||
connect(server, clients, Script::StringifyJSON(rq, &attrs, false));
|
||||
debug_printf("%s", client1.TestReadGuiMessages().c_str());
|
||||
|
||||
server.StartGame();
|
||||
@@ -258,8 +257,6 @@ public:
|
||||
"mapPath", "maps/scenarios/",
|
||||
"thing", "example");
|
||||
|
||||
server.UpdateInitAttributes(&attrs, scriptInterface);
|
||||
|
||||
CNetClient client1(&client1Game, "127.0.0.1", PS_DEFAULT_PORT, L"alice");
|
||||
CNetClient client2(&client2Game, "127.0.0.1", PS_DEFAULT_PORT, L"bob");
|
||||
CNetClient client3(&client3Game, "127.0.0.1", PS_DEFAULT_PORT, L"charlie");
|
||||
@@ -268,7 +265,7 @@ public:
|
||||
clients.push_back(&client2);
|
||||
clients.push_back(&client3);
|
||||
|
||||
connect(server, clients);
|
||||
connect(server, clients, Script::StringifyJSON(rq, &attrs, false));
|
||||
debug_printf("%s", client1.TestReadGuiMessages().c_str());
|
||||
|
||||
server.StartGame();
|
||||
|
||||
Reference in New Issue
Block a user