Changeset View
Standalone View
source/network/NetServer.cpp
Show First 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | private: | ||||
u32 m_RejoinerHostID; | u32 m_RejoinerHostID; | ||||
}; | }; | ||||
/* | /* | ||||
* XXX: We use some non-threadsafe functions from the worker thread. | * XXX: We use some non-threadsafe functions from the worker thread. | ||||
* See http://trac.wildfiregames.com/ticket/654 | * See http://trac.wildfiregames.com/ticket/654 | ||||
*/ | */ | ||||
CNetServerWorker::CNetServerWorker(int autostartPlayers) : | CNetServerWorker::CNetServerWorker(bool useLobbyAuth, int autostartPlayers) : | ||||
m_AutostartPlayers(autostartPlayers), | m_AutostartPlayers(autostartPlayers), | ||||
m_LobbyAuth(useLobbyAuth), | |||||
m_Shutdown(false), | m_Shutdown(false), | ||||
m_ScriptInterface(NULL), | m_ScriptInterface(NULL), | ||||
m_NextHostID(1), m_Host(NULL), m_HostGUID(), m_Stats(NULL), | m_NextHostID(1), m_Host(NULL), m_HostGUID(), m_Stats(NULL), | ||||
m_LastConnectionCheck(0) | m_LastConnectionCheck(0) | ||||
{ | { | ||||
m_State = SERVER_STATE_UNCONNECTED; | m_State = SERVER_STATE_UNCONNECTED; | ||||
m_ServerTurnManager = NULL; | m_ServerTurnManager = NULL; | ||||
▲ Show 20 Lines • Show All 262 Lines • ▼ Show 20 Lines | bool CNetServerWorker::RunStep() | ||||
m_ScriptInterface->GetRuntime()->MaybeIncrementalGC(0.5f); | m_ScriptInterface->GetRuntime()->MaybeIncrementalGC(0.5f); | ||||
JSContext* cx = m_ScriptInterface->GetContext(); | JSContext* cx = m_ScriptInterface->GetContext(); | ||||
JSAutoRequest rq(cx); | JSAutoRequest rq(cx); | ||||
std::vector<bool> newStartGame; | std::vector<bool> newStartGame; | ||||
std::vector<std::string> newGameAttributes; | std::vector<std::string> newGameAttributes; | ||||
std::vector<std::pair<CStr, CStr>> newLobbyAuths; | |||||
elexis: Thanks, much better | |||||
std::vector<u32> newTurnLength; | std::vector<u32> newTurnLength; | ||||
{ | { | ||||
CScopeLock lock(m_WorkerMutex); | CScopeLock lock(m_WorkerMutex); | ||||
if (m_Shutdown) | if (m_Shutdown) | ||||
return false; | return false; | ||||
newStartGame.swap(m_StartGameQueue); | newStartGame.swap(m_StartGameQueue); | ||||
newGameAttributes.swap(m_GameAttributesQueue); | newGameAttributes.swap(m_GameAttributesQueue); | ||||
newLobbyAuths.swap(m_LobbyAuthQueue); | |||||
newTurnLength.swap(m_TurnLengthQueue); | newTurnLength.swap(m_TurnLengthQueue); | ||||
} | } | ||||
if (!newGameAttributes.empty()) | if (!newGameAttributes.empty()) | ||||
{ | { | ||||
JS::RootedValue gameAttributesVal(cx); | JS::RootedValue gameAttributesVal(cx); | ||||
GetScriptInterface().ParseJSON(newGameAttributes.back(), &gameAttributesVal); | GetScriptInterface().ParseJSON(newGameAttributes.back(), &gameAttributesVal); | ||||
UpdateGameAttributes(&gameAttributesVal); | UpdateGameAttributes(&gameAttributesVal); | ||||
} | } | ||||
if (!newTurnLength.empty()) | if (!newTurnLength.empty()) | ||||
SetTurnLength(newTurnLength.back()); | SetTurnLength(newTurnLength.back()); | ||||
// Do StartGame last, so we have the most up-to-date game attributes when we start | // Do StartGame last, so we have the most up-to-date game attributes when we start | ||||
if (!newStartGame.empty()) | if (!newStartGame.empty()) | ||||
StartGame(); | StartGame(); | ||||
while (!newLobbyAuths.empty()) | |||||
Done Inline ActionsThis function is becoming too long and complex, better move it to a helper function. elexis: This function is becoming too long and complex, better move it to a helper function. | |||||
Done Inline Actionsthx elexis: thx | |||||
{ | |||||
const std::pair<CStr, CStr>& auth = newLobbyAuths.back(); | |||||
ProcessLobbyAuth(auth.first, auth.second); | |||||
newLobbyAuths.pop_back(); | |||||
} | |||||
// Perform file transfers | // Perform file transfers | ||||
for (CNetServerSession* session : m_Sessions) | for (CNetServerSession* session : m_Sessions) | ||||
session->GetFileTransferer().Poll(); | session->GetFileTransferer().Poll(); | ||||
Done Inline Actions\n\n elexis: \n\n | |||||
CheckClientConnections(); | CheckClientConnections(); | ||||
Done Inline ActionsEither +1 tab or return on one line as in the other place. My \n request was posted when there were multiple statements within this function. elexis: Either +1 tab or return on one line as in the other place. My \n request was posted when there… | |||||
// Process network events: | // Process network events: | ||||
ENetEvent event; | ENetEvent event; | ||||
int status = enet_host_service(m_Host, &event, HOST_SERVICE_TIMEOUT); | int status = enet_host_service(m_Host, &event, HOST_SERVICE_TIMEOUT); | ||||
Done Inline ActionsOne place of the patch uses utf8_from_wstring here it uses FromUTF8, decide on one style, use the one that's most predominant. elexis: One place of the patch uses `utf8_from_wstring` here it uses FromUTF8, decide on one style, use… | |||||
if (status < 0) | if (status < 0) | ||||
{ | { | ||||
LOGERROR("CNetServerWorker: enet_host_service failed (%d)", status); | LOGERROR("CNetServerWorker: enet_host_service failed (%d)", status); | ||||
// TODO: notify game that the server has shut down | // TODO: notify game that the server has shut down | ||||
return false; | return false; | ||||
} | } | ||||
if (status == 0) | if (status == 0) | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | void CNetServerWorker::SetupSession(CNetServerSession* session) | ||||
// Set up transitions for session | // Set up transitions for session | ||||
session->AddTransition(NSS_UNCONNECTED, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | session->AddTransition(NSS_UNCONNECTED, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | ||||
session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | ||||
session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CLIENT_HANDSHAKE, NSS_AUTHENTICATE, (void*)&OnClientHandshake, context); | session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CLIENT_HANDSHAKE, NSS_AUTHENTICATE, (void*)&OnClientHandshake, context); | ||||
session->AddTransition(NSS_LOBBY_AUTHENTICATE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | |||||
session->AddTransition(NSS_LOBBY_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, (void*)&OnAuthenticate, context); | |||||
session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED); | ||||
session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, (void*)&OnAuthenticate, context); | session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, (void*)&OnAuthenticate, context); | ||||
session->AddTransition(NSS_PREGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); | session->AddTransition(NSS_PREGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, (void*)&OnDisconnect, context); | ||||
session->AddTransition(NSS_PREGAME, (uint)NMT_CHAT, NSS_PREGAME, (void*)&OnChat, context); | session->AddTransition(NSS_PREGAME, (uint)NMT_CHAT, NSS_PREGAME, (void*)&OnChat, context); | ||||
session->AddTransition(NSS_PREGAME, (uint)NMT_READY, NSS_PREGAME, (void*)&OnReady, context); | session->AddTransition(NSS_PREGAME, (uint)NMT_READY, NSS_PREGAME, (void*)&OnReady, context); | ||||
session->AddTransition(NSS_PREGAME, (uint)NMT_CLEAR_ALL_READY, NSS_PREGAME, (void*)&OnClearAllReady, context); | session->AddTransition(NSS_PREGAME, (uint)NMT_CLEAR_ALL_READY, NSS_PREGAME, (void*)&OnClearAllReady, context); | ||||
session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_SETUP, NSS_PREGAME, (void*)&OnGameSetup, context); | session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_SETUP, NSS_PREGAME, (void*)&OnGameSetup, context); | ||||
▲ Show 20 Lines • Show All 208 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void CNetServerWorker::SetTurnLength(u32 msecs) | void CNetServerWorker::SetTurnLength(u32 msecs) | ||||
{ | { | ||||
if (m_ServerTurnManager) | if (m_ServerTurnManager) | ||||
m_ServerTurnManager->SetTurnLength(msecs); | m_ServerTurnManager->SetTurnLength(msecs); | ||||
} | } | ||||
void CNetServerWorker::ProcessLobbyAuth(const CStr& name, const CStr& token) | |||||
{ | |||||
LOGMESSAGE("Net Server: Received lobby auth message from %s with %s", name, token); | |||||
// Find the user with that guid | |||||
std::vector<CNetServerSession*>::iterator it = std::find_if(m_Sessions.begin(), m_Sessions.end(), | |||||
[&](CNetServerSession* session) | |||||
{ return session->GetGUID() == token; }); | |||||
elexisUnsubmitted Not Done Inline ActionsThis means we can send this packet to other clients whose GUID we learnt after the join? elexis: This means we can send this packet to other clients whose GUID we learnt after the join?
| |||||
Done Inline ActionsWhitespace comment from last time still applies. Either compress the last 3 lines in one, or something with tabs that looks similar to what we have in the other find_if place. elexis: Whitespace comment from last time still applies. Either compress the last 3 lines in one, or… | |||||
if (it == m_Sessions.end()) | |||||
return; | |||||
(*it)->SetUserName(name.FromUTF8()); | |||||
// Send an empty mesage to request authentication from client | |||||
elexisUnsubmitted Not Done Inline ActionsThis comment cost me some time to understand. We have just finished the lobby authentication, so it's a response to a successful authentication. What the comment means is the UDP password based authentication that is not implemented yet! elexis: This comment cost me some time to understand.
We have just finished the lobby authentication… | |||||
ImarokAuthorUnsubmitted Not Done Inline ActionsNot only that, just the Authenticate message in general. Imarok: Not only that, just the Authenticate message in general. | |||||
CAuthenticateMessage emptyMessage; | |||||
(*it)->SendMessage(&emptyMessage); | |||||
} | |||||
bool CNetServerWorker::OnClientHandshake(void* context, CFsmEvent* event) | bool CNetServerWorker::OnClientHandshake(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_CLIENT_HANDSHAKE); | ENSURE(event->GetType() == (uint)NMT_CLIENT_HANDSHAKE); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
CCliHandshakeMessage* message = (CCliHandshakeMessage*)event->GetParamRef(); | CCliHandshakeMessage* message = (CCliHandshakeMessage*)event->GetParamRef(); | ||||
Show All 12 Lines | while(std::find_if( | ||||
{ return session->GetGUID() == guid; }) != server.m_Sessions.end()) | { return session->GetGUID() == guid; }) != server.m_Sessions.end()) | ||||
{ | { | ||||
if (++count > 100) | if (++count > 100) | ||||
{ | { | ||||
session->Disconnect(NDR_UNKNOWN); | session->Disconnect(NDR_UNKNOWN); | ||||
return true; | return true; | ||||
} | } | ||||
guid = ps_generate_guid(); | guid = ps_generate_guid(); | ||||
} | } | ||||
Done Inline Actions(lambdas are a bit ugly IMO. only sometimes they can do things that a range based loop cant (like removing while iterating)) elexis: (lambdas are a bit ugly IMO. only sometimes they can do things that a range based loop cant… | |||||
Done Inline ActionsI just copied the code committed by you ;P Imarok: I just copied the code committed by you ;P | |||||
session->SetGUID(guid); | session->SetGUID(guid); | ||||
CSrvHandshakeResponseMessage handshakeResponse; | CSrvHandshakeResponseMessage handshakeResponse; | ||||
handshakeResponse.m_UseProtocolVersion = PS_PROTOCOL_VERSION; | handshakeResponse.m_UseProtocolVersion = PS_PROTOCOL_VERSION; | ||||
handshakeResponse.m_GUID = guid; | handshakeResponse.m_GUID = guid; | ||||
handshakeResponse.m_Flags = 0; | handshakeResponse.m_Flags = 0; | ||||
if (server.m_LobbyAuth) | |||||
{ | |||||
handshakeResponse.m_Flags = PS_REQUIRE_LOBBYAUTH_FLAG; | |||||
elexisUnsubmitted Done Inline Actions|= to keep it easily extensible elexis: `|=` to keep it easily extensible | |||||
session->SetNextState(NSS_LOBBY_AUTHENTICATE); | |||||
Done Inline Actions(This seemed suspicious. elexis: (This seemed suspicious.
The `AddTransition` call states that the session state is set to… | |||||
} | |||||
session->SendMessage(&handshakeResponse); | session->SendMessage(&handshakeResponse); | ||||
return true; | return true; | ||||
} | } | ||||
bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event) | bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event) | ||||
{ | { | ||||
ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE); | ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE); | ||||
CNetServerSession* session = (CNetServerSession*)context; | CNetServerSession* session = (CNetServerSession*)context; | ||||
CNetServerWorker& server = session->GetServer(); | CNetServerWorker& server = session->GetServer(); | ||||
// Prohibit joins while the game is loading | // Prohibit joins while the game is loading | ||||
if (server.m_State == SERVER_STATE_LOADING) | if (server.m_State == SERVER_STATE_LOADING) | ||||
{ | { | ||||
LOGMESSAGE("Refused connection while the game is loading"); | LOGMESSAGE("Refused connection while the game is loading"); | ||||
session->Disconnect(NDR_SERVER_LOADING); | session->Disconnect(NDR_SERVER_LOADING); | ||||
return true; | return true; | ||||
} | } | ||||
CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef(); | CAuthenticateMessage* message = (CAuthenticateMessage*)event->GetParamRef(); | ||||
CStrW username = SanitisePlayerName(message->m_Name); | CStrW username = SanitisePlayerName(message->m_Name); | ||||
CStrW usernameWithoutRating(username.substr(0, username.find(L" ("))); | |||||
Not Done Inline Actions(yikes rating in nickname) elexis: (yikes rating in nickname) | |||||
Not Done Inline Actionsyeah, we need to get rid of that sometimes... Imarok: yeah, we need to get rid of that sometimes... | |||||
Done Inline Actionswhy LowerCase? elexis: why LowerCase? | |||||
Done Inline Actions
because xmpp names are caseinsensitive Imarok: > why LowerCase?
because xmpp names are caseinsensitive | |||||
Not Done Inline ActionsIs that so? If so, why? See irc discussion today.
Could not confirm, maybe ejabberd does that. https://xmpp.org/extensions/xep-0029.html#sect-
is the only thing I found. When implementing a protocol and relying on some defined behavior, post a link to the specs defining that behavior. elexis: Is that so? If so, why? See irc discussion today.
> (17:24:19) Imarok: elexis: because xmpp… | |||||
Not Done Inline Actionsbump elexis: bump | |||||
Not Done Inline ActionsWhat do you want from me? Imarok: What do you want from me? | |||||
Not Done Inline ActionsThis is not a matter between me and you but between the reader and the code.
elexis: This is not a matter between me and you but between the reader and the code.
> "When… | |||||
if (server.m_LobbyAuth && usernameWithoutRating.LowerCase() != session->GetUserName().LowerCase()) | |||||
{ | |||||
Done Inline Actionsmake it red even? (if we hadnt had removed the string IP function and replaced it with an u32 IP getter, it would have been trivial to expose the IP of the attacker even) elexis: make it red even? (if we hadnt had removed the string IP function and replaced it with an u32… | |||||
Done Inline ActionsMake it red = LOGERROR (Ask if you don't comprehend something and say no thank you if you disagree) elexis: Make it red = LOGERROR (Ask if you don't comprehend something and say no thank you if you… | |||||
Not Done Inline ActionsSorry, looks like I forgot that. Imarok: Sorry, looks like I forgot that. | |||||
LOGERROR("Net server: lobby auth: %s tried joining as %s", | |||||
usernameWithoutRating.ToUTF8(), | |||||
session->GetUserName().ToUTF8()); | |||||
Not Done Inline Actions(Note to self: People can that to inform the host that they want to join as a spec) elexis: (Note to self: People can that to inform the host that they want to join as a spec) | |||||
session->Disconnect(NDR_LOBBY_AUTH_FAILED); | |||||
return true; | |||||
} | |||||
// Either deduplicate or prohibit join if name is in use | // Either deduplicate or prohibit join if name is in use | ||||
bool duplicatePlayernames = false; | bool duplicatePlayernames = false; | ||||
CFG_GET_VAL("network.duplicateplayernames", duplicatePlayernames); | CFG_GET_VAL("network.duplicateplayernames", duplicatePlayernames); | ||||
if (duplicatePlayernames) | if (duplicatePlayernames) | ||||
username = server.DeduplicatePlayerName(username); | username = server.DeduplicatePlayerName(username); | ||||
else if (std::find_if( | else | ||||
{ | |||||
std::vector<CNetServerSession*>::iterator it = std::find_if( | |||||
server.m_Sessions.begin(), server.m_Sessions.end(), | server.m_Sessions.begin(), server.m_Sessions.end(), | ||||
[&username] (const CNetServerSession* session) | [&username] (const CNetServerSession* session) | ||||
{ return session->GetUserName() == username; }) | { return session->GetUserName() == username; }); | ||||
!= server.m_Sessions.end()) | |||||
if (it != server.m_Sessions.end() && (*it) != session) | |||||
elexisUnsubmitted Not Done Inline ActionsI do read now that (*it) != session is indeed needed, as the OnAuthenticate occurs after the lobby auth processing which sets the username earlier than before! elexis: I do read now that `(*it) != session` is indeed needed, as the OnAuthenticate occurs after the… | |||||
{ | { | ||||
Done Inline ActionsWould have said -1 tab, but why is this code changed in the first place? Do it in a separate commit if needed. elexis: Would have said -1 tab, but why is this code changed in the first place? Do it in a separate… | |||||
Done Inline ActionsIt's changed, cause we need this && (*it) != sessionfor the patch (as said already on irc) Imarok: It's changed, cause we need this `&& (*it) != session`for the patch (as said already on irc) | |||||
Done Inline Actions
Waiting. elexis: > 18:05 < Imarok> maybe because previously session had no username in this state, but may have… | |||||
Not Done Inline Actions(*it)->SetUserName(name.FromUTF8()); (L883) Imarok: `(*it)->SetUserName(name.FromUTF8());` (L883) | |||||
session->Disconnect(NDR_PLAYERNAME_IN_USE); | session->Disconnect(NDR_PLAYERNAME_IN_USE); | ||||
return true; | return true; | ||||
} | } | ||||
} | |||||
// Disconnect banned usernames | // Disconnect banned usernames | ||||
if (std::find(server.m_BannedPlayers.begin(), server.m_BannedPlayers.end(), username) != server.m_BannedPlayers.end()) | if (std::find(server.m_BannedPlayers.begin(), server.m_BannedPlayers.end(), username) != server.m_BannedPlayers.end()) | ||||
{ | { | ||||
session->Disconnect(NDR_BANNED); | session->Disconnect(NDR_BANNED); | ||||
return true; | return true; | ||||
} | } | ||||
Show All 39 Lines | if (!isRejoining) | ||||
CFG_GET_VAL("network.lateobservers", observerLateJoin); | CFG_GET_VAL("network.lateobservers", observerLateJoin); | ||||
if (observerLateJoin == "everyone") | if (observerLateJoin == "everyone") | ||||
{ | { | ||||
isRejoining = true; | isRejoining = true; | ||||
} | } | ||||
else if (observerLateJoin == "buddies") | else if (observerLateJoin == "buddies") | ||||
{ | { | ||||
CStrW usernameWithoutRating(username.substr(0, username.find(L" ("))); | |||||
CStr buddies; | CStr buddies; | ||||
CFG_GET_VAL("lobby.buddies", buddies); | CFG_GET_VAL("lobby.buddies", buddies); | ||||
std::wstringstream buddiesStream(wstring_from_utf8(buddies)); | std::wstringstream buddiesStream(wstring_from_utf8(buddies)); | ||||
CStrW buddy; | CStrW buddy; | ||||
while (std::getline(buddiesStream, buddy, L',')) | while (std::getline(buddiesStream, buddy, L',')) | ||||
{ | { | ||||
if (buddy == usernameWithoutRating) | if (buddy == usernameWithoutRating) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 480 Lines • ▼ Show 20 Lines | |||||
void CNetServerWorker::SendHolePunchingMessage(const CStr& ipStr, u16 port) | void CNetServerWorker::SendHolePunchingMessage(const CStr& ipStr, u16 port) | ||||
{ | { | ||||
StunClient::SendHolePunchingMessages(m_Host, ipStr.c_str(), port); | StunClient::SendHolePunchingMessages(m_Host, ipStr.c_str(), port); | ||||
} | } | ||||
CNetServer::CNetServer(int autostartPlayers) : | CNetServer::CNetServer(bool useLobbyAuth, int autostartPlayers) : | ||||
m_Worker(new CNetServerWorker(autostartPlayers)) | m_Worker(new CNetServerWorker(useLobbyAuth, autostartPlayers)) | ||||
{ | { | ||||
} | } | ||||
CNetServer::~CNetServer() | CNetServer::~CNetServer() | ||||
{ | { | ||||
delete m_Worker; | delete m_Worker; | ||||
} | } | ||||
Show All 13 Lines | void CNetServer::UpdateGameAttributes(JS::MutableHandleValue attrs, const ScriptInterface& scriptInterface) | ||||
// Pass the attributes as JSON, since that's the easiest safe | // Pass the attributes as JSON, since that's the easiest safe | ||||
// cross-thread way of passing script data | // cross-thread way of passing script data | ||||
std::string attrsJSON = scriptInterface.StringifyJSON(attrs, false); | std::string attrsJSON = scriptInterface.StringifyJSON(attrs, false); | ||||
CScopeLock lock(m_Worker->m_WorkerMutex); | CScopeLock lock(m_Worker->m_WorkerMutex); | ||||
m_Worker->m_GameAttributesQueue.push_back(attrsJSON); | m_Worker->m_GameAttributesQueue.push_back(attrsJSON); | ||||
} | } | ||||
void CNetServer::OnLobbyAuth(const CStr& name, const CStr& token) | |||||
{ | |||||
CScopeLock lock(m_Worker->m_WorkerMutex); | |||||
m_Worker->m_LobbyAuthQueue.push_back(std::make_pair(name, token)); | |||||
} | |||||
Done Inline ActionsWould be cleaner to push a std::pair, this way it were impossible to consume the wrong number of items per batch elexis: Would be cleaner to push a `std::pair`, this way it were impossible to consume the wrong number… | |||||
Not Done Inline Actionsgood idea. Imarok: good idea. | |||||
void CNetServer::SetTurnLength(u32 msecs) | void CNetServer::SetTurnLength(u32 msecs) | ||||
{ | { | ||||
CScopeLock lock(m_Worker->m_WorkerMutex); | CScopeLock lock(m_Worker->m_WorkerMutex); | ||||
m_Worker->m_TurnLengthQueue.push_back(msecs); | m_Worker->m_TurnLengthQueue.push_back(msecs); | ||||
} | } | ||||
void CNetServer::SendHolePunchingMessage(const CStr& ip, u16 port) | void CNetServer::SendHolePunchingMessage(const CStr& ip, u16 port) | ||||
{ | { | ||||
m_Worker->SendHolePunchingMessage(ip, port); | m_Worker->SendHolePunchingMessage(ip, port); | ||||
} | } |
Thanks, much better