0ad/source/lobby/scripting/JSInterface_Lobby.cpp

521 lines
18 KiB
C++
Raw Normal View History

/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precompiled.h"
#include "JSInterface_Lobby.h"
#include "gui/GUIManager.h"
#include "lib/utf8.h"
#include "lobby/IXmppClient.h"
#include "network/NetServer.h"
#include "ps/CLogger.h"
#include "ps/CStr.h"
#include "ps/Util.h"
#include "scriptinterface/ScriptInterface.h"
#include "third_party/encryption/pkcs5_pbkdf2.h"
#include <string>
void JSI_Lobby::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
{
// Lobby functions
scriptInterface.RegisterFunction<bool, &JSI_Lobby::HasXmppClient>("HasXmppClient");
scriptInterface.RegisterFunction<void, bool, &JSI_Lobby::SetRankedGame>("SetRankedGame");
#if CONFIG2_LOBBY // Allow the lobby to be disabled
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, std::wstring, std::wstring, int, &JSI_Lobby::StartXmppClient>("StartXmppClient");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::StartRegisterXmppClient>("StartRegisterXmppClient");
scriptInterface.RegisterFunction<void, &JSI_Lobby::StopXmppClient>("StopXmppClient");
scriptInterface.RegisterFunction<void, &JSI_Lobby::ConnectXmppClient>("ConnectXmppClient");
scriptInterface.RegisterFunction<void, &JSI_Lobby::DisconnectXmppClient>("DisconnectXmppClient");
scriptInterface.RegisterFunction<bool, &JSI_Lobby::IsXmppClientConnected>("IsXmppClientConnected");
scriptInterface.RegisterFunction<void, &JSI_Lobby::SendGetBoardList>("SendGetBoardList");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::SendGetProfile>("SendGetProfile");
scriptInterface.RegisterFunction<void, JS::HandleValue, &JSI_Lobby::SendRegisterGame>("SendRegisterGame");
scriptInterface.RegisterFunction<void, JS::HandleValue, &JSI_Lobby::SendGameReport>("SendGameReport");
scriptInterface.RegisterFunction<void, &JSI_Lobby::SendUnregisterGame>("SendUnregisterGame");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::SendChangeStateGame>("SendChangeStateGame");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetPlayerList>("GetPlayerList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetGameList>("GetGameList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetBoardList>("GetBoardList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetProfile>("GetProfile");
Rewrite lobby page to use class semantics, add more gamedetails labels, improve performance using batch processing and caching and gain possibility for game creation/player-join/leave events, refs #5387. Game selection details features: * Display victory conditions following their sending but missing display following bffe917914, refs 7b0f6f530c. * Display the host of the match and the game name in the selected game details following 61261d14fc, refs D1666. * Display mods if the mods differ (without having to attempt to join the game prior) following eca956a513. Performance features: * Implement batch message processing in the XmppClient to rebuild GUI objects only once when receiving backlog or returning from a match. * Implement Game class to cache gamelist, filter and sorting values, as they rarely change but are accessed often. * Cache sprintf objects. Security fixes: * Add escapeText in lobby/ to avoid players breaking the lobby for every participant, supersedes D720, comments by bb. * Do not hide broadcasted unrecognized chat commands that mods used as leaking private channels, fixes #5615. Defect fixes: * Fix XmppClient.cpp storing unused historic message types resulting in memory waste and unintentional replay of for instance disconnect/announcements messages following both e8dfde9ba6/D819 and 6bf74902a7/D2265, refs #3306. * Fix XmppClient.cpp victoryCondition -> victoryConditions gamesetup.js change from 6d54ab4c1f/D1240. * Fix leaderboard/profile page cancel hotkey closing the lobby dialog as well and removes cancel hotkey note from lobby_panels.xml from 960f2d7c31/D817 since the described issue was fixed by f9b529f2fb/D1701. * Fix lobby playing menu sound in a running game after having closed the lobby dialog following introduction in 960f2d7c31/D817. * Fix GUI on nick change by updating g_Username. * Update profile panel only with data matching the player requested. Hack erasure: * Object semantics make it cheap to add state and cache values, storing literals in properties while removing globals, adding events while decoupling components and gaining moddability. * Erase comments and translation comments stating that this would be IRC!!, supersedes D1136. * Introduce Status chat message type to supersede "/special" chat command + "isSpecial" property from bffe917914 (formerly g_specialKey e6840f5fca) deluxe hack. * Introduce System chat message type to supersede system errors disguising as chat from a mock user called "system". Code cleanups: * Move code from XML to JS. * Move size values from JS to XML, especially following 960f2d7c31/D817 and 7752219cef/D1051. * Rename "user" to "player". * Fix lobby/ eslint warnings, refs D2261. * Remove message.nick emptiness check from 0940db3fc0/D835, since XEP-0045 dictates that it is non-empty. * Add translated string for deleted subjects. * Add TODOs for some evident COList issues, refs #5638. Differential Revision: https://code.wildfiregames.com/D2412 This was SVN commit r23172.
2019-11-21 14:44:41 +01:00
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollNewMessages>("LobbyGuiPollNewMessages");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollHistoricMessages>("LobbyGuiPollHistoricMessages");
scriptInterface.RegisterFunction<bool, &JSI_Lobby::LobbyGuiPollHasPlayerListUpdate>("LobbyGuiPollHasPlayerListUpdate");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySendMessage>("LobbySendMessage");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySetPlayerPresence>("LobbySetPlayerPresence");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySetNick>("LobbySetNick");
scriptInterface.RegisterFunction<std::wstring, &JSI_Lobby::LobbyGetNick>("LobbyGetNick");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::LobbyKick>("LobbyKick");
scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::LobbyBan>("LobbyBan");
Fix missing wstring_from_utf8 for multi-user-chat messages and translated strings following 9023f4bebb / D2264. The commit introduced support for arbitrary lobby CreateGUIMessage JS::Value arguments but didn't transfer wstring_from_utf8 appropriately. Instead of enlengthening the code by reintroducing utf8_from_wstring everyhwere, shorten the code and specialize ToJSVal for glooxwrapper::string and gloox enums. Avoid string copies for XmppClient getters, refs D1668: Change GetPresence() and GetRole() to return the pointer to the string literal instead of copy constructing a std::string each call. Don't reintroduce the unneeded utf8_from_wstring conversions for the untranslatable ASCII identifiers returned by GetPresence() and GetRole(). Change GetSubject() to return a const ref to the member instead of copy assigning the std::string to an output value. Change m_Subject to std::wstring to avoid constructing a copy using wstring_from_utf8 each GetSubject() call. Change gloox enum to translatable string functions to be static, so as to use them in the new ToJSVal functions (enabled by not calling CertificateErrorToString from ConnectionErrorToString anyymore in 92fc34c87c/D2274). Avoid per-player string copies in m_PlayerMap: Change m_PlayerMap value type from std::vector<std::string> to a new PlayerMap struct with named members for readability. Use gloox enums as PlayerMap values to avoid constructing (performance) and storing (memory footprint) std::strings. The JS String is created from the pointer to the ASCII string literal without intermediaries. Use glooxwrapper::string for nickname and m_Rating since it's the data source type received in relevant places, but that might be improved for performance with std::wstring. Construct map values in place where possible and post error instead of silently inserting if an existing value is to be modified. Avoid repeated std::map lookups on string keys by caching the PlayerMap::iterator where available. Remove some glooxwrapper::string to_string() calls redundant with its operator<< and improve DbgXMPP gloox enum output. Transfer rating too upon nickchange. Differential Revision: https://code.wildfiregames.com/D2271 Tested on: clang 8.0.1, Jenkins This was SVN commit r22891.
2019-09-12 19:23:33 +02:00
scriptInterface.RegisterFunction<const char*, std::wstring, &JSI_Lobby::LobbyGetPlayerPresence>("LobbyGetPlayerPresence");
scriptInterface.RegisterFunction<const char*, std::wstring, &JSI_Lobby::LobbyGetPlayerRole>("LobbyGetPlayerRole");
Rewrite lobby page to use class semantics, add more gamedetails labels, improve performance using batch processing and caching and gain possibility for game creation/player-join/leave events, refs #5387. Game selection details features: * Display victory conditions following their sending but missing display following bffe917914, refs 7b0f6f530c. * Display the host of the match and the game name in the selected game details following 61261d14fc, refs D1666. * Display mods if the mods differ (without having to attempt to join the game prior) following eca956a513. Performance features: * Implement batch message processing in the XmppClient to rebuild GUI objects only once when receiving backlog or returning from a match. * Implement Game class to cache gamelist, filter and sorting values, as they rarely change but are accessed often. * Cache sprintf objects. Security fixes: * Add escapeText in lobby/ to avoid players breaking the lobby for every participant, supersedes D720, comments by bb. * Do not hide broadcasted unrecognized chat commands that mods used as leaking private channels, fixes #5615. Defect fixes: * Fix XmppClient.cpp storing unused historic message types resulting in memory waste and unintentional replay of for instance disconnect/announcements messages following both e8dfde9ba6/D819 and 6bf74902a7/D2265, refs #3306. * Fix XmppClient.cpp victoryCondition -> victoryConditions gamesetup.js change from 6d54ab4c1f/D1240. * Fix leaderboard/profile page cancel hotkey closing the lobby dialog as well and removes cancel hotkey note from lobby_panels.xml from 960f2d7c31/D817 since the described issue was fixed by f9b529f2fb/D1701. * Fix lobby playing menu sound in a running game after having closed the lobby dialog following introduction in 960f2d7c31/D817. * Fix GUI on nick change by updating g_Username. * Update profile panel only with data matching the player requested. Hack erasure: * Object semantics make it cheap to add state and cache values, storing literals in properties while removing globals, adding events while decoupling components and gaining moddability. * Erase comments and translation comments stating that this would be IRC!!, supersedes D1136. * Introduce Status chat message type to supersede "/special" chat command + "isSpecial" property from bffe917914 (formerly g_specialKey e6840f5fca) deluxe hack. * Introduce System chat message type to supersede system errors disguising as chat from a mock user called "system". Code cleanups: * Move code from XML to JS. * Move size values from JS to XML, especially following 960f2d7c31/D817 and 7752219cef/D1051. * Rename "user" to "player". * Fix lobby/ eslint warnings, refs D2261. * Remove message.nick emptiness check from 0940db3fc0/D835, since XEP-0045 dictates that it is non-empty. * Add translated string for deleted subjects. * Add TODOs for some evident COList issues, refs #5638. Differential Revision: https://code.wildfiregames.com/D2412 This was SVN commit r23172.
2019-11-21 14:44:41 +01:00
scriptInterface.RegisterFunction<std::wstring, std::wstring, &JSI_Lobby::LobbyGetPlayerRating>("LobbyGetPlayerRating");
scriptInterface.RegisterFunction<std::wstring, std::wstring, std::wstring, &JSI_Lobby::EncryptPassword>("EncryptPassword");
scriptInterface.RegisterFunction<std::wstring, &JSI_Lobby::LobbyGetRoomSubject>("LobbyGetRoomSubject");
#endif // CONFIG2_LOBBY
}
bool JSI_Lobby::HasXmppClient(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate))
{
return g_XmppClient;
}
void JSI_Lobby::SetRankedGame(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), bool isRanked)
{
g_rankedGame = isRanked;
}
#if CONFIG2_LOBBY
void JSI_Lobby::StartXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password, const std::wstring& room, const std::wstring& nick, int historyRequestSize)
{
if (g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call StartXmppClient with an already initialized XmppClient!");
return;
}
g_XmppClient =
IXmppClient::create(
g_GUI->GetScriptInterface().get(),
utf8_from_wstring(username),
utf8_from_wstring(password),
utf8_from_wstring(room),
utf8_from_wstring(nick),
historyRequestSize);
g_rankedGame = true;
}
void JSI_Lobby::StartRegisterXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& username, const std::wstring& password)
{
if (g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call StartRegisterXmppClient with an already initialized XmppClient!");
return;
}
g_XmppClient =
IXmppClient::create(
g_GUI->GetScriptInterface().get(),
utf8_from_wstring(username),
utf8_from_wstring(password),
std::string(),
std::string(),
0,
true);
}
void JSI_Lobby::StopXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call StopXmppClient without an initialized XmppClient!");
return;
}
SAFE_DELETE(g_XmppClient);
g_rankedGame = false;
}
void JSI_Lobby::ConnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call ConnectXmppClient without an initialized XmppClient!");
return;
}
g_XmppClient->connect();
}
void JSI_Lobby::DisconnectXmppClient(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call DisconnectXmppClient without an initialized XmppClient!");
return;
}
g_XmppClient->disconnect();
}
bool JSI_Lobby::IsXmppClientConnected(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call IsXmppClientConnected without an initialized XmppClient!");
return false;
}
return g_XmppClient->isConnected();
}
void JSI_Lobby::SendGetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendGetBoardList without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqGetBoardList();
}
void JSI_Lobby::SendGetProfile(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& player)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendGetProfile without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqGetProfile(utf8_from_wstring(player));
}
void JSI_Lobby::SendGameReport(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendGameReport without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqGameReport(*(pCmptPrivate->pScriptInterface), data);
}
void JSI_Lobby::SendRegisterGame(ScriptInterface::CmptPrivate* pCmptPrivate, JS::HandleValue data)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendRegisterGame without an initialized XmppClient!");
return;
}
// Prevent JS mods to register matches in the lobby that were started with lobby authentication disabled
if (!g_NetServer || !g_NetServer->UseLobbyAuth())
{
LOGERROR("Registering games in the lobby requires lobby authentication to be enabled!");
return;
}
g_XmppClient->SendIqRegisterGame(*(pCmptPrivate->pScriptInterface), data);
}
void JSI_Lobby::SendUnregisterGame(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendUnregisterGame without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqUnregisterGame();
}
void JSI_Lobby::SendChangeStateGame(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nbp, const std::wstring& players)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call SendChangeStateGame without an initialized XmppClient!");
return;
}
g_XmppClient->SendIqChangeStateGame(utf8_from_wstring(nbp), utf8_from_wstring(players));
}
JS::Value JSI_Lobby::GetPlayerList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetPlayerList without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue playerList(rq.cx);
g_XmppClient->GUIGetPlayerList(*(pCmptPrivate->pScriptInterface), &playerList);
return playerList;
}
JS::Value JSI_Lobby::GetGameList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetGameList without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue gameList(rq.cx);
g_XmppClient->GUIGetGameList(*(pCmptPrivate->pScriptInterface), &gameList);
return gameList;
}
JS::Value JSI_Lobby::GetBoardList(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetBoardList without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue boardList(rq.cx);
g_XmppClient->GUIGetBoardList(*(pCmptPrivate->pScriptInterface), &boardList);
return boardList;
}
JS::Value JSI_Lobby::GetProfile(ScriptInterface::CmptPrivate* pCmptPrivate)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
if (!g_XmppClient)
{
ScriptException::Raise(rq, "Cannot call GetProfile without an initialized XmppClient!");
return JS::UndefinedValue();
}
JS::RootedValue profileFetch(rq.cx);
g_XmppClient->GUIGetProfile(*(pCmptPrivate->pScriptInterface), &profileFetch);
return profileFetch;
}
bool JSI_Lobby::LobbyGuiPollHasPlayerListUpdate(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGuiPollHasPlayerListUpdate without an initialized XmppClient!");
return false;
}
return g_XmppClient->GuiPollHasPlayerListUpdate();
}
JS::Value JSI_Lobby::LobbyGuiPollNewMessages(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
return JS::UndefinedValue();
return g_XmppClient->GuiPollNewMessages(*(pCmptPrivate->pScriptInterface));
}
JS::Value JSI_Lobby::LobbyGuiPollHistoricMessages(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGuiPollHistoricMessages without an initialized XmppClient!");
return JS::UndefinedValue();
}
return g_XmppClient->GuiPollHistoricMessages(*(pCmptPrivate->pScriptInterface));
}
void JSI_Lobby::LobbySendMessage(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& message)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbySendMessage without an initialized XmppClient!");
return;
}
g_XmppClient->SendMUCMessage(utf8_from_wstring(message));
}
void JSI_Lobby::LobbySetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& presence)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbySetPlayerPresence without an initialized XmppClient!");
return;
}
g_XmppClient->SetPresence(utf8_from_wstring(presence));
}
void JSI_Lobby::LobbySetNick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbySetNick without an initialized XmppClient!");
return;
}
g_XmppClient->SetNick(utf8_from_wstring(nick));
}
std::wstring JSI_Lobby::LobbyGetNick(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetNick without an initialized XmppClient!");
return std::wstring();
}
std::string nick;
g_XmppClient->GetNick(nick);
return wstring_from_utf8(nick);
}
void JSI_Lobby::LobbyKick(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyKick without an initialized XmppClient!");
return;
}
g_XmppClient->kick(utf8_from_wstring(nick), utf8_from_wstring(reason));
}
void JSI_Lobby::LobbyBan(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nick, const std::wstring& reason)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyBan without an initialized XmppClient!");
return;
}
g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason));
}
const char* JSI_Lobby::LobbyGetPlayerPresence(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetPlayerPresence without an initialized XmppClient!");
Fix missing wstring_from_utf8 for multi-user-chat messages and translated strings following 9023f4bebb / D2264. The commit introduced support for arbitrary lobby CreateGUIMessage JS::Value arguments but didn't transfer wstring_from_utf8 appropriately. Instead of enlengthening the code by reintroducing utf8_from_wstring everyhwere, shorten the code and specialize ToJSVal for glooxwrapper::string and gloox enums. Avoid string copies for XmppClient getters, refs D1668: Change GetPresence() and GetRole() to return the pointer to the string literal instead of copy constructing a std::string each call. Don't reintroduce the unneeded utf8_from_wstring conversions for the untranslatable ASCII identifiers returned by GetPresence() and GetRole(). Change GetSubject() to return a const ref to the member instead of copy assigning the std::string to an output value. Change m_Subject to std::wstring to avoid constructing a copy using wstring_from_utf8 each GetSubject() call. Change gloox enum to translatable string functions to be static, so as to use them in the new ToJSVal functions (enabled by not calling CertificateErrorToString from ConnectionErrorToString anyymore in 92fc34c87c/D2274). Avoid per-player string copies in m_PlayerMap: Change m_PlayerMap value type from std::vector<std::string> to a new PlayerMap struct with named members for readability. Use gloox enums as PlayerMap values to avoid constructing (performance) and storing (memory footprint) std::strings. The JS String is created from the pointer to the ASCII string literal without intermediaries. Use glooxwrapper::string for nickname and m_Rating since it's the data source type received in relevant places, but that might be improved for performance with std::wstring. Construct map values in place where possible and post error instead of silently inserting if an existing value is to be modified. Avoid repeated std::map lookups on string keys by caching the PlayerMap::iterator where available. Remove some glooxwrapper::string to_string() calls redundant with its operator<< and improve DbgXMPP gloox enum output. Transfer rating too upon nickchange. Differential Revision: https://code.wildfiregames.com/D2271 Tested on: clang 8.0.1, Jenkins This was SVN commit r22891.
2019-09-12 19:23:33 +02:00
return "";
}
Fix missing wstring_from_utf8 for multi-user-chat messages and translated strings following 9023f4bebb / D2264. The commit introduced support for arbitrary lobby CreateGUIMessage JS::Value arguments but didn't transfer wstring_from_utf8 appropriately. Instead of enlengthening the code by reintroducing utf8_from_wstring everyhwere, shorten the code and specialize ToJSVal for glooxwrapper::string and gloox enums. Avoid string copies for XmppClient getters, refs D1668: Change GetPresence() and GetRole() to return the pointer to the string literal instead of copy constructing a std::string each call. Don't reintroduce the unneeded utf8_from_wstring conversions for the untranslatable ASCII identifiers returned by GetPresence() and GetRole(). Change GetSubject() to return a const ref to the member instead of copy assigning the std::string to an output value. Change m_Subject to std::wstring to avoid constructing a copy using wstring_from_utf8 each GetSubject() call. Change gloox enum to translatable string functions to be static, so as to use them in the new ToJSVal functions (enabled by not calling CertificateErrorToString from ConnectionErrorToString anyymore in 92fc34c87c/D2274). Avoid per-player string copies in m_PlayerMap: Change m_PlayerMap value type from std::vector<std::string> to a new PlayerMap struct with named members for readability. Use gloox enums as PlayerMap values to avoid constructing (performance) and storing (memory footprint) std::strings. The JS String is created from the pointer to the ASCII string literal without intermediaries. Use glooxwrapper::string for nickname and m_Rating since it's the data source type received in relevant places, but that might be improved for performance with std::wstring. Construct map values in place where possible and post error instead of silently inserting if an existing value is to be modified. Avoid repeated std::map lookups on string keys by caching the PlayerMap::iterator where available. Remove some glooxwrapper::string to_string() calls redundant with its operator<< and improve DbgXMPP gloox enum output. Transfer rating too upon nickchange. Differential Revision: https://code.wildfiregames.com/D2271 Tested on: clang 8.0.1, Jenkins This was SVN commit r22891.
2019-09-12 19:23:33 +02:00
return g_XmppClient->GetPresence(utf8_from_wstring(nickname));
}
const char* JSI_Lobby::LobbyGetPlayerRole(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetPlayerRole without an initialized XmppClient!");
Fix missing wstring_from_utf8 for multi-user-chat messages and translated strings following 9023f4bebb / D2264. The commit introduced support for arbitrary lobby CreateGUIMessage JS::Value arguments but didn't transfer wstring_from_utf8 appropriately. Instead of enlengthening the code by reintroducing utf8_from_wstring everyhwere, shorten the code and specialize ToJSVal for glooxwrapper::string and gloox enums. Avoid string copies for XmppClient getters, refs D1668: Change GetPresence() and GetRole() to return the pointer to the string literal instead of copy constructing a std::string each call. Don't reintroduce the unneeded utf8_from_wstring conversions for the untranslatable ASCII identifiers returned by GetPresence() and GetRole(). Change GetSubject() to return a const ref to the member instead of copy assigning the std::string to an output value. Change m_Subject to std::wstring to avoid constructing a copy using wstring_from_utf8 each GetSubject() call. Change gloox enum to translatable string functions to be static, so as to use them in the new ToJSVal functions (enabled by not calling CertificateErrorToString from ConnectionErrorToString anyymore in 92fc34c87c/D2274). Avoid per-player string copies in m_PlayerMap: Change m_PlayerMap value type from std::vector<std::string> to a new PlayerMap struct with named members for readability. Use gloox enums as PlayerMap values to avoid constructing (performance) and storing (memory footprint) std::strings. The JS String is created from the pointer to the ASCII string literal without intermediaries. Use glooxwrapper::string for nickname and m_Rating since it's the data source type received in relevant places, but that might be improved for performance with std::wstring. Construct map values in place where possible and post error instead of silently inserting if an existing value is to be modified. Avoid repeated std::map lookups on string keys by caching the PlayerMap::iterator where available. Remove some glooxwrapper::string to_string() calls redundant with its operator<< and improve DbgXMPP gloox enum output. Transfer rating too upon nickchange. Differential Revision: https://code.wildfiregames.com/D2271 Tested on: clang 8.0.1, Jenkins This was SVN commit r22891.
2019-09-12 19:23:33 +02:00
return "";
}
Fix missing wstring_from_utf8 for multi-user-chat messages and translated strings following 9023f4bebb / D2264. The commit introduced support for arbitrary lobby CreateGUIMessage JS::Value arguments but didn't transfer wstring_from_utf8 appropriately. Instead of enlengthening the code by reintroducing utf8_from_wstring everyhwere, shorten the code and specialize ToJSVal for glooxwrapper::string and gloox enums. Avoid string copies for XmppClient getters, refs D1668: Change GetPresence() and GetRole() to return the pointer to the string literal instead of copy constructing a std::string each call. Don't reintroduce the unneeded utf8_from_wstring conversions for the untranslatable ASCII identifiers returned by GetPresence() and GetRole(). Change GetSubject() to return a const ref to the member instead of copy assigning the std::string to an output value. Change m_Subject to std::wstring to avoid constructing a copy using wstring_from_utf8 each GetSubject() call. Change gloox enum to translatable string functions to be static, so as to use them in the new ToJSVal functions (enabled by not calling CertificateErrorToString from ConnectionErrorToString anyymore in 92fc34c87c/D2274). Avoid per-player string copies in m_PlayerMap: Change m_PlayerMap value type from std::vector<std::string> to a new PlayerMap struct with named members for readability. Use gloox enums as PlayerMap values to avoid constructing (performance) and storing (memory footprint) std::strings. The JS String is created from the pointer to the ASCII string literal without intermediaries. Use glooxwrapper::string for nickname and m_Rating since it's the data source type received in relevant places, but that might be improved for performance with std::wstring. Construct map values in place where possible and post error instead of silently inserting if an existing value is to be modified. Avoid repeated std::map lookups on string keys by caching the PlayerMap::iterator where available. Remove some glooxwrapper::string to_string() calls redundant with its operator<< and improve DbgXMPP gloox enum output. Transfer rating too upon nickchange. Differential Revision: https://code.wildfiregames.com/D2271 Tested on: clang 8.0.1, Jenkins This was SVN commit r22891.
2019-09-12 19:23:33 +02:00
return g_XmppClient->GetRole(utf8_from_wstring(nickname));
}
std::wstring JSI_Lobby::LobbyGetPlayerRating(ScriptInterface::CmptPrivate* pCmptPrivate, const std::wstring& nickname)
Rewrite lobby page to use class semantics, add more gamedetails labels, improve performance using batch processing and caching and gain possibility for game creation/player-join/leave events, refs #5387. Game selection details features: * Display victory conditions following their sending but missing display following bffe917914, refs 7b0f6f530c. * Display the host of the match and the game name in the selected game details following 61261d14fc, refs D1666. * Display mods if the mods differ (without having to attempt to join the game prior) following eca956a513. Performance features: * Implement batch message processing in the XmppClient to rebuild GUI objects only once when receiving backlog or returning from a match. * Implement Game class to cache gamelist, filter and sorting values, as they rarely change but are accessed often. * Cache sprintf objects. Security fixes: * Add escapeText in lobby/ to avoid players breaking the lobby for every participant, supersedes D720, comments by bb. * Do not hide broadcasted unrecognized chat commands that mods used as leaking private channels, fixes #5615. Defect fixes: * Fix XmppClient.cpp storing unused historic message types resulting in memory waste and unintentional replay of for instance disconnect/announcements messages following both e8dfde9ba6/D819 and 6bf74902a7/D2265, refs #3306. * Fix XmppClient.cpp victoryCondition -> victoryConditions gamesetup.js change from 6d54ab4c1f/D1240. * Fix leaderboard/profile page cancel hotkey closing the lobby dialog as well and removes cancel hotkey note from lobby_panels.xml from 960f2d7c31/D817 since the described issue was fixed by f9b529f2fb/D1701. * Fix lobby playing menu sound in a running game after having closed the lobby dialog following introduction in 960f2d7c31/D817. * Fix GUI on nick change by updating g_Username. * Update profile panel only with data matching the player requested. Hack erasure: * Object semantics make it cheap to add state and cache values, storing literals in properties while removing globals, adding events while decoupling components and gaining moddability. * Erase comments and translation comments stating that this would be IRC!!, supersedes D1136. * Introduce Status chat message type to supersede "/special" chat command + "isSpecial" property from bffe917914 (formerly g_specialKey e6840f5fca) deluxe hack. * Introduce System chat message type to supersede system errors disguising as chat from a mock user called "system". Code cleanups: * Move code from XML to JS. * Move size values from JS to XML, especially following 960f2d7c31/D817 and 7752219cef/D1051. * Rename "user" to "player". * Fix lobby/ eslint warnings, refs D2261. * Remove message.nick emptiness check from 0940db3fc0/D835, since XEP-0045 dictates that it is non-empty. * Add translated string for deleted subjects. * Add TODOs for some evident COList issues, refs #5638. Differential Revision: https://code.wildfiregames.com/D2412 This was SVN commit r23172.
2019-11-21 14:44:41 +01:00
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetPlayerRating without an initialized XmppClient!");
Rewrite lobby page to use class semantics, add more gamedetails labels, improve performance using batch processing and caching and gain possibility for game creation/player-join/leave events, refs #5387. Game selection details features: * Display victory conditions following their sending but missing display following bffe917914, refs 7b0f6f530c. * Display the host of the match and the game name in the selected game details following 61261d14fc, refs D1666. * Display mods if the mods differ (without having to attempt to join the game prior) following eca956a513. Performance features: * Implement batch message processing in the XmppClient to rebuild GUI objects only once when receiving backlog or returning from a match. * Implement Game class to cache gamelist, filter and sorting values, as they rarely change but are accessed often. * Cache sprintf objects. Security fixes: * Add escapeText in lobby/ to avoid players breaking the lobby for every participant, supersedes D720, comments by bb. * Do not hide broadcasted unrecognized chat commands that mods used as leaking private channels, fixes #5615. Defect fixes: * Fix XmppClient.cpp storing unused historic message types resulting in memory waste and unintentional replay of for instance disconnect/announcements messages following both e8dfde9ba6/D819 and 6bf74902a7/D2265, refs #3306. * Fix XmppClient.cpp victoryCondition -> victoryConditions gamesetup.js change from 6d54ab4c1f/D1240. * Fix leaderboard/profile page cancel hotkey closing the lobby dialog as well and removes cancel hotkey note from lobby_panels.xml from 960f2d7c31/D817 since the described issue was fixed by f9b529f2fb/D1701. * Fix lobby playing menu sound in a running game after having closed the lobby dialog following introduction in 960f2d7c31/D817. * Fix GUI on nick change by updating g_Username. * Update profile panel only with data matching the player requested. Hack erasure: * Object semantics make it cheap to add state and cache values, storing literals in properties while removing globals, adding events while decoupling components and gaining moddability. * Erase comments and translation comments stating that this would be IRC!!, supersedes D1136. * Introduce Status chat message type to supersede "/special" chat command + "isSpecial" property from bffe917914 (formerly g_specialKey e6840f5fca) deluxe hack. * Introduce System chat message type to supersede system errors disguising as chat from a mock user called "system". Code cleanups: * Move code from XML to JS. * Move size values from JS to XML, especially following 960f2d7c31/D817 and 7752219cef/D1051. * Rename "user" to "player". * Fix lobby/ eslint warnings, refs D2261. * Remove message.nick emptiness check from 0940db3fc0/D835, since XEP-0045 dictates that it is non-empty. * Add translated string for deleted subjects. * Add TODOs for some evident COList issues, refs #5638. Differential Revision: https://code.wildfiregames.com/D2412 This was SVN commit r23172.
2019-11-21 14:44:41 +01:00
return std::wstring();
}
Rewrite lobby page to use class semantics, add more gamedetails labels, improve performance using batch processing and caching and gain possibility for game creation/player-join/leave events, refs #5387. Game selection details features: * Display victory conditions following their sending but missing display following bffe917914, refs 7b0f6f530c. * Display the host of the match and the game name in the selected game details following 61261d14fc, refs D1666. * Display mods if the mods differ (without having to attempt to join the game prior) following eca956a513. Performance features: * Implement batch message processing in the XmppClient to rebuild GUI objects only once when receiving backlog or returning from a match. * Implement Game class to cache gamelist, filter and sorting values, as they rarely change but are accessed often. * Cache sprintf objects. Security fixes: * Add escapeText in lobby/ to avoid players breaking the lobby for every participant, supersedes D720, comments by bb. * Do not hide broadcasted unrecognized chat commands that mods used as leaking private channels, fixes #5615. Defect fixes: * Fix XmppClient.cpp storing unused historic message types resulting in memory waste and unintentional replay of for instance disconnect/announcements messages following both e8dfde9ba6/D819 and 6bf74902a7/D2265, refs #3306. * Fix XmppClient.cpp victoryCondition -> victoryConditions gamesetup.js change from 6d54ab4c1f/D1240. * Fix leaderboard/profile page cancel hotkey closing the lobby dialog as well and removes cancel hotkey note from lobby_panels.xml from 960f2d7c31/D817 since the described issue was fixed by f9b529f2fb/D1701. * Fix lobby playing menu sound in a running game after having closed the lobby dialog following introduction in 960f2d7c31/D817. * Fix GUI on nick change by updating g_Username. * Update profile panel only with data matching the player requested. Hack erasure: * Object semantics make it cheap to add state and cache values, storing literals in properties while removing globals, adding events while decoupling components and gaining moddability. * Erase comments and translation comments stating that this would be IRC!!, supersedes D1136. * Introduce Status chat message type to supersede "/special" chat command + "isSpecial" property from bffe917914 (formerly g_specialKey e6840f5fca) deluxe hack. * Introduce System chat message type to supersede system errors disguising as chat from a mock user called "system". Code cleanups: * Move code from XML to JS. * Move size values from JS to XML, especially following 960f2d7c31/D817 and 7752219cef/D1051. * Rename "user" to "player". * Fix lobby/ eslint warnings, refs D2261. * Remove message.nick emptiness check from 0940db3fc0/D835, since XEP-0045 dictates that it is non-empty. * Add translated string for deleted subjects. * Add TODOs for some evident COList issues, refs #5638. Differential Revision: https://code.wildfiregames.com/D2412 This was SVN commit r23172.
2019-11-21 14:44:41 +01:00
return g_XmppClient->GetRating(utf8_from_wstring(nickname));
}
// Non-public secure PBKDF2 hash function with salting and 1,337 iterations
//
// TODO: We should use libsodium's crypto_pwhash instead of this. The first reason is that
// libsodium doesn't propose a bare PBKDF2 hash in its API and it's too bad to rely on custom
// code when we have a fully-fledged library available; the second reason is that Argon2 (the
// default algorithm for crypto_pwhash) is better than what we use (and it's the default one
// in the lib for a reason).
// However changing the hashing method should be planned carefully, by trying to login with a
// password hashed the old way, and, if successful, updating the password in the database using
// the new hashing method. Dropping the old hashing code can only be done either by giving users
// a way to reset their password, or by keeping track of successful password updates and dropping
// old unused accounts after some time.
std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::string& username)
{
ENSURE(sodium_init() >= 0);
const int DIGESTSIZE = crypto_hash_sha256_BYTES;
const int ITERATIONS = 1337;
cassert(DIGESTSIZE == 32);
static const unsigned char salt_base[DIGESTSIZE] = {
244, 243, 249, 244, 32, 33, 34, 35, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 32, 33, 244, 224, 127, 129, 130, 140, 153, 133, 123, 234, 123 };
// initialize the salt buffer
unsigned char salt_buffer[DIGESTSIZE] = {0};
crypto_hash_sha256_state state;
crypto_hash_sha256_init(&state);
crypto_hash_sha256_update(&state, salt_base, sizeof(salt_base));
crypto_hash_sha256_update(&state, (unsigned char*)username.c_str(), username.length());
crypto_hash_sha256_final(&state, salt_buffer);
// PBKDF2 to create the buffer
unsigned char encrypted[DIGESTSIZE];
pbkdf2(encrypted, (unsigned char*)password.c_str(), password.length(), salt_buffer, DIGESTSIZE, ITERATIONS);
return CStr(Hexify(encrypted, DIGESTSIZE)).UpperCase();
}
std::wstring JSI_Lobby::EncryptPassword(ScriptInterface::CmptPrivate* UNUSED(pCmptPrivate), const std::wstring& pass, const std::wstring& user)
{
return wstring_from_utf8(JSI_Lobby::EncryptPassword(utf8_from_wstring(pass), utf8_from_wstring(user)));
}
std::wstring JSI_Lobby::LobbyGetRoomSubject(ScriptInterface::CmptPrivate* pCmptPrivate)
{
if (!g_XmppClient)
{
ScriptRequest rq(pCmptPrivate->pScriptInterface);
ScriptException::Raise(rq, "Cannot call LobbyGetRoomSubject without an initialized XmppClient!");
return std::wstring();
}
Fix missing wstring_from_utf8 for multi-user-chat messages and translated strings following 9023f4bebb / D2264. The commit introduced support for arbitrary lobby CreateGUIMessage JS::Value arguments but didn't transfer wstring_from_utf8 appropriately. Instead of enlengthening the code by reintroducing utf8_from_wstring everyhwere, shorten the code and specialize ToJSVal for glooxwrapper::string and gloox enums. Avoid string copies for XmppClient getters, refs D1668: Change GetPresence() and GetRole() to return the pointer to the string literal instead of copy constructing a std::string each call. Don't reintroduce the unneeded utf8_from_wstring conversions for the untranslatable ASCII identifiers returned by GetPresence() and GetRole(). Change GetSubject() to return a const ref to the member instead of copy assigning the std::string to an output value. Change m_Subject to std::wstring to avoid constructing a copy using wstring_from_utf8 each GetSubject() call. Change gloox enum to translatable string functions to be static, so as to use them in the new ToJSVal functions (enabled by not calling CertificateErrorToString from ConnectionErrorToString anyymore in 92fc34c87c/D2274). Avoid per-player string copies in m_PlayerMap: Change m_PlayerMap value type from std::vector<std::string> to a new PlayerMap struct with named members for readability. Use gloox enums as PlayerMap values to avoid constructing (performance) and storing (memory footprint) std::strings. The JS String is created from the pointer to the ASCII string literal without intermediaries. Use glooxwrapper::string for nickname and m_Rating since it's the data source type received in relevant places, but that might be improved for performance with std::wstring. Construct map values in place where possible and post error instead of silently inserting if an existing value is to be modified. Avoid repeated std::map lookups on string keys by caching the PlayerMap::iterator where available. Remove some glooxwrapper::string to_string() calls redundant with its operator<< and improve DbgXMPP gloox enum output. Transfer rating too upon nickchange. Differential Revision: https://code.wildfiregames.com/D2271 Tested on: clang 8.0.1, Jenkins This was SVN commit r22891.
2019-09-12 19:23:33 +02:00
return g_XmppClient->GetSubject();
}
#endif