diff --git a/build/premake/premake4.lua b/build/premake/premake4.lua index 87513d0f6b..9471b4fb47 100644 --- a/build/premake/premake4.lua +++ b/build/premake/premake4.lua @@ -580,6 +580,7 @@ function setup_all_libs () if not _OPTIONS["without-lobby"] then source_dirs = { "lobby", + "lobby/scripting", } extern_libs = { diff --git a/source/gui/scripting/ScriptFunctions.cpp b/source/gui/scripting/ScriptFunctions.cpp index 9da40c8564..52444f35d9 100644 --- a/source/gui/scripting/ScriptFunctions.cpp +++ b/source/gui/scripting/ScriptFunctions.cpp @@ -27,8 +27,7 @@ #include "lib/timer.h" #include "lib/utf8.h" #include "lib/sysdep/sysdep.h" -#include "lobby/IXmppClient.h" -#include "lobby/sha.h" +#include "lobby/scripting/JSInterface_Lobby.h" #include "maths/FixedVector3D.h" #include "network/NetClient.h" #include "network/NetServer.h" @@ -613,255 +612,6 @@ void RewindTimeWarp(void* UNUSED(cbdata)) g_Game->GetTurnManager()->RewindTimeWarp(); } -/* Begin lobby related functions */ - -bool HasXmppClient(void* UNUSED(cbdata)) -{ - return (g_XmppClient ? true : false); -} - -#if CONFIG2_LOBBY -void StartXmppClient(void* cbdata, std::wstring username, std::wstring password, std::wstring room, std::wstring nick) -{ - CGUIManager* guiManager = static_cast (cbdata); - - ENSURE(!g_XmppClient); - - g_XmppClient = IXmppClient::create(guiManager->GetScriptInterface(), - utf8_from_wstring(username), utf8_from_wstring(password), - utf8_from_wstring(room), utf8_from_wstring(nick)); - g_rankedGame = true; -} - -void StartRegisterXmppClient(void* cbdata, std::wstring username, std::wstring password) -{ - CGUIManager* guiManager = static_cast (cbdata); - - ENSURE(!g_XmppClient); - - g_XmppClient = IXmppClient::create(guiManager->GetScriptInterface(), - utf8_from_wstring(username), utf8_from_wstring(password), - "", "", true); -} - -void StopXmppClient(void* UNUSED(cbdata)) -{ - ENSURE(g_XmppClient); - SAFE_DELETE(g_XmppClient); - g_rankedGame = false; -} - -void ConnectXmppClient(void* UNUSED(cbdata)) -{ - ENSURE(g_XmppClient); - g_XmppClient->connect(); -} - -void DisconnectXmppClient(void* UNUSED(cbdata)) -{ - ENSURE(g_XmppClient); - g_XmppClient->disconnect(); -} - -void RecvXmppClient(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return; - g_XmppClient->recv(); -} - -void SendGetGameList(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return; - g_XmppClient->SendIqGetGameList(); -} - -void SendGetBoardList(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return; - g_XmppClient->SendIqGetBoardList(); -} - -void SendGameReport(void* UNUSED(cbdata), CScriptVal data) -{ - if (!g_XmppClient) - return; - g_XmppClient->SendIqGameReport(data); -} - -void SendRegisterGame(void* UNUSED(cbdata), CScriptVal data) -{ - if (!g_XmppClient) - return; - g_XmppClient->SendIqRegisterGame(data); -} - -void SendUnregisterGame(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return; - g_XmppClient->SendIqUnregisterGame(); -} - -void SendChangeStateGame(void* UNUSED(cbdata), std::wstring nbp, std::wstring players) -{ - if (!g_XmppClient) - return; - g_XmppClient->SendIqChangeStateGame(utf8_from_wstring(nbp), utf8_from_wstring(players)); -} - -CScriptVal GetPlayerList(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return CScriptVal(); - - CScriptValRooted playerList = g_XmppClient->GUIGetPlayerList(); - - return playerList.get(); -} - -CScriptVal GetGameList(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return CScriptVal(); - - CScriptValRooted gameList = g_XmppClient->GUIGetGameList(); - - return gameList.get(); -} - -CScriptVal GetBoardList(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return CScriptVal(); - - CScriptValRooted boardList = g_XmppClient->GUIGetBoardList(); - - return boardList.get(); -} - -CScriptVal LobbyGuiPollMessage(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return CScriptVal(); - - CScriptValRooted poll = g_XmppClient->GuiPollMessage(); - - return poll.get(); -} - -void LobbySendMessage(void* UNUSED(cbdata), std::wstring message) -{ - if (!g_XmppClient) - return; - - g_XmppClient->SendMUCMessage(utf8_from_wstring(message)); -} - -void LobbySetPlayerPresence(void* UNUSED(cbdata), std::wstring presence) -{ - if (!g_XmppClient) - return; - - g_XmppClient->SetPresence(utf8_from_wstring(presence)); -} - -void LobbySetNick(void* UNUSED(cbdata), std::wstring nick) -{ - if (!g_XmppClient) - return; - - g_XmppClient->SetNick(utf8_from_wstring(nick)); -} - -std::wstring LobbyGetNick(void* UNUSED(cbdata)) -{ - if (!g_XmppClient) - return L""; - - std::string nick; - g_XmppClient->GetNick(nick); - return wstring_from_utf8(nick); -} - -void LobbyKick(void* UNUSED(cbdata), std::wstring nick, std::wstring reason) -{ - if (!g_XmppClient) - return; - - g_XmppClient->kick(utf8_from_wstring(nick), utf8_from_wstring(reason)); -} - -void LobbyBan(void* UNUSED(cbdata), std::wstring nick, std::wstring reason) -{ - if (!g_XmppClient) - return; - - g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason)); -} - -std::wstring LobbyGetPlayerPresence(void* UNUSED(cbdata), std::wstring nickname) -{ - if (!g_XmppClient) - return L""; - - std::string presence; - g_XmppClient->GetPresence(utf8_from_wstring(nickname), presence); - return wstring_from_utf8(presence); -} - -// Non-public secure PBKDF2 hash function with salting and 1,337 iterations -static std::string EncryptPassword(const std::string& password, const std::string& username) -{ - const int DIGESTSIZE = SHA_DIGEST_SIZE; - const int ITERATIONS = 1337; - - static const byte 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 - byte salt_buffer[DIGESTSIZE] = {0}; - SHA256 hash; - hash.update(salt_base, sizeof(salt_base)); - hash.update(username.c_str(), username.length()); - hash.finish(salt_buffer); - - // PBKDF2 to create the buffer - byte encrypted[DIGESTSIZE]; - pbkdf2(encrypted, (byte*)password.c_str(), password.length(), salt_buffer, DIGESTSIZE, ITERATIONS); - - static const char base16[] = "0123456789ABCDEF"; - char hex[2 * DIGESTSIZE]; - for (int i = 0; i < DIGESTSIZE; ++i) - { - hex[i*2] = base16[encrypted[i] >> 4]; // 4 high bits - hex[i*2 + 1] = base16[encrypted[i] & 0x0F];// 4 low bits - } - return std::string(hex, sizeof(hex)); -} - -// Public hash interface. -std::wstring EncryptPassword(void* UNUSED(cbdata), std::wstring pass, std::wstring user) -{ - return wstring_from_utf8(EncryptPassword(utf8_from_wstring(pass), utf8_from_wstring(user))); -} - -bool IsRankedGame(void* UNUSED(cbdata)) -{ - return g_rankedGame; -} - -void SetRankedGame(void* UNUSED(cbdata), bool isRanked) -{ - g_rankedGame = isRanked; -} -#endif // CONFIG2_LOBBY - -/* End lobby related functions */ - void QuickSave(void* UNUSED(cbdata)) { g_Game->GetTurnManager()->QuickSave(); @@ -970,33 +720,33 @@ void GuiScriptingInit(ScriptInterface& scriptInterface) scriptInterface.RegisterFunction("SetBoundingBoxDebugOverlay"); // Lobby functions - scriptInterface.RegisterFunction("HasXmppClient"); + scriptInterface.RegisterFunction("HasXmppClient"); #if CONFIG2_LOBBY // Allow the lobby to be disabled - scriptInterface.RegisterFunction("StartXmppClient"); - scriptInterface.RegisterFunction("StartRegisterXmppClient"); - scriptInterface.RegisterFunction("StopXmppClient"); - scriptInterface.RegisterFunction("ConnectXmppClient"); - scriptInterface.RegisterFunction("DisconnectXmppClient"); - scriptInterface.RegisterFunction("RecvXmppClient"); - scriptInterface.RegisterFunction("SendGetGameList"); - scriptInterface.RegisterFunction("SendGetBoardList"); - scriptInterface.RegisterFunction("SendRegisterGame"); - scriptInterface.RegisterFunction("SendGameReport"); - scriptInterface.RegisterFunction("SendUnregisterGame"); - scriptInterface.RegisterFunction("SendChangeStateGame"); - scriptInterface.RegisterFunction("GetPlayerList"); - scriptInterface.RegisterFunction("GetGameList"); - scriptInterface.RegisterFunction("GetBoardList"); - scriptInterface.RegisterFunction("LobbyGuiPollMessage"); - scriptInterface.RegisterFunction("LobbySendMessage"); - scriptInterface.RegisterFunction("LobbySetPlayerPresence"); - scriptInterface.RegisterFunction("LobbySetNick"); - scriptInterface.RegisterFunction("LobbyGetNick"); - scriptInterface.RegisterFunction("LobbyKick"); - scriptInterface.RegisterFunction("LobbyBan"); - scriptInterface.RegisterFunction("LobbyGetPlayerPresence"); - scriptInterface.RegisterFunction("EncryptPassword"); - scriptInterface.RegisterFunction("IsRankedGame"); - scriptInterface.RegisterFunction("SetRankedGame"); + scriptInterface.RegisterFunction("StartXmppClient"); + scriptInterface.RegisterFunction("StartRegisterXmppClient"); + scriptInterface.RegisterFunction("StopXmppClient"); + scriptInterface.RegisterFunction("ConnectXmppClient"); + scriptInterface.RegisterFunction("DisconnectXmppClient"); + scriptInterface.RegisterFunction("RecvXmppClient"); + scriptInterface.RegisterFunction("SendGetGameList"); + scriptInterface.RegisterFunction("SendGetBoardList"); + scriptInterface.RegisterFunction("SendRegisterGame"); + scriptInterface.RegisterFunction("SendGameReport"); + scriptInterface.RegisterFunction("SendUnregisterGame"); + scriptInterface.RegisterFunction("SendChangeStateGame"); + scriptInterface.RegisterFunction("GetPlayerList"); + scriptInterface.RegisterFunction("GetGameList"); + scriptInterface.RegisterFunction("GetBoardList"); + scriptInterface.RegisterFunction("LobbyGuiPollMessage"); + scriptInterface.RegisterFunction("LobbySendMessage"); + scriptInterface.RegisterFunction("LobbySetPlayerPresence"); + scriptInterface.RegisterFunction("LobbySetNick"); + scriptInterface.RegisterFunction("LobbyGetNick"); + scriptInterface.RegisterFunction("LobbyKick"); + scriptInterface.RegisterFunction("LobbyBan"); + scriptInterface.RegisterFunction("LobbyGetPlayerPresence"); + scriptInterface.RegisterFunction("EncryptPassword"); + scriptInterface.RegisterFunction("IsRankedGame"); + scriptInterface.RegisterFunction("SetRankedGame"); #endif // CONFIG2_LOBBY } diff --git a/source/lobby/IXmppClient.h b/source/lobby/IXmppClient.h index fa96995c89..ce1f1b75af 100644 --- a/source/lobby/IXmppClient.h +++ b/source/lobby/IXmppClient.h @@ -25,7 +25,7 @@ class CScriptValRooted; class IXmppClient { public: - static IXmppClient* create(ScriptInterface& scriptInterface, const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt = false); + static IXmppClient* create(const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt = false); virtual ~IXmppClient() {} virtual void connect() = 0; @@ -33,8 +33,8 @@ public: virtual void recv() = 0; virtual void SendIqGetGameList() = 0; virtual void SendIqGetBoardList() = 0; - virtual void SendIqGameReport(CScriptVal data) = 0; - virtual void SendIqRegisterGame(CScriptVal data) = 0; + virtual void SendIqGameReport(ScriptInterface& scriptInterface, CScriptVal data) = 0; + virtual void SendIqRegisterGame(ScriptInterface& scriptInterface, CScriptVal data) = 0; virtual void SendIqUnregisterGame() = 0; virtual void SendIqChangeStateGame(const std::string& nbp, const std::string& players) = 0; virtual void SetNick(const std::string& nick) = 0; @@ -44,13 +44,11 @@ public: virtual void SetPresence(const std::string& presence) = 0; virtual void GetPresence(const std::string& nickname, std::string& presence) = 0; - virtual CScriptValRooted GUIGetPlayerList() = 0; - virtual CScriptValRooted GUIGetGameList() = 0; - virtual CScriptValRooted GUIGetBoardList() = 0; + virtual CScriptValRooted GUIGetPlayerList(ScriptInterface& scriptInterface) = 0; + virtual CScriptValRooted GUIGetGameList(ScriptInterface& scriptInterface) = 0; + virtual CScriptValRooted GUIGetBoardList(ScriptInterface& scriptInterface) = 0; - virtual ScriptInterface& GetScriptInterface() = 0; - - virtual CScriptValRooted GuiPollMessage() = 0; + virtual CScriptValRooted GuiPollMessage(ScriptInterface& scriptInterface) = 0; virtual void SendMUCMessage(const std::string& message) = 0; }; diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index 7ca4dc0af9..4bedb9e89b 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -60,16 +60,16 @@ static std::string tag_name(const glooxwrapper::IQ& iq) return ret; } -IXmppClient* IXmppClient::create(ScriptInterface& scriptInterface, const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt) +IXmppClient* IXmppClient::create(const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt) { - return new XmppClient(scriptInterface, sUsername, sPassword, sRoom, sNick, regOpt); + return new XmppClient(sUsername, sPassword, sRoom, sNick, regOpt); } /** * Construct the xmpp client */ -XmppClient::XmppClient(ScriptInterface& scriptInterface, const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt) - : m_ScriptInterface(scriptInterface), m_client(NULL), m_mucRoom(NULL), m_registration(NULL), m_username(sUsername), m_password(sPassword), m_nick(sNick) +XmppClient::XmppClient(const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt) + : m_client(NULL), m_mucRoom(NULL), m_registration(NULL), m_username(sUsername), m_password(sPassword), m_nick(sNick) { // Read lobby configuration from default.cfg std::string sServer; @@ -149,12 +149,6 @@ XmppClient::~XmppClient() glooxwrapper::Tag::free(*it); } -/// Game - script -ScriptInterface& XmppClient::GetScriptInterface() -{ - return m_ScriptInterface; -} - /// Network void XmppClient::connect() { @@ -289,7 +283,7 @@ void XmppClient::SendIqGetBoardList() * * @param data A JS array of game statistics */ -void XmppClient::SendIqGameReport(CScriptVal data) +void XmppClient::SendIqGameReport(ScriptInterface& scriptInterface, CScriptVal data) { glooxwrapper::JID xpartamuppJid(m_xpartamuppId); jsval dataval = data.get(); @@ -300,11 +294,11 @@ void XmppClient::SendIqGameReport(CScriptVal data) // Iterate through all the properties reported and add them to the stanza. std::vector properties; - m_ScriptInterface.EnumeratePropertyNamesWithPrefix(dataval, "", properties); + scriptInterface.EnumeratePropertyNamesWithPrefix(dataval, "", properties); for (std::vector::size_type i = 0; i != properties.size(); i++) { std::wstring value; - m_ScriptInterface.GetProperty(dataval, properties[i].c_str(), value); + scriptInterface.GetProperty(dataval, properties[i].c_str(), value); report->addAttribute(properties[i], utf8_from_wstring(value)); } @@ -323,7 +317,7 @@ void XmppClient::SendIqGameReport(CScriptVal data) * * @param data A JS array of game attributes */ -void XmppClient::SendIqRegisterGame(CScriptVal data) +void XmppClient::SendIqRegisterGame(ScriptInterface& scriptInterface, CScriptVal data) { glooxwrapper::JID xpartamuppJid(m_xpartamuppId); jsval dataval = data.get(); @@ -337,11 +331,11 @@ void XmppClient::SendIqRegisterGame(CScriptVal data) // Iterate through all the properties reported and add them to the stanza. std::vector properties; - m_ScriptInterface.EnumeratePropertyNamesWithPrefix(dataval, "", properties); + scriptInterface.EnumeratePropertyNamesWithPrefix(dataval, "", properties); for (std::vector::size_type i = 0; i != properties.size(); i++) { std::wstring value; - m_ScriptInterface.GetProperty(dataval, properties[i].c_str(), value); + scriptInterface.GetProperty(dataval, properties[i].c_str(), value); game->addAttribute(properties[i], utf8_from_wstring(value)); } @@ -462,20 +456,20 @@ void XmppClient::handleOOB(const glooxwrapper::JID&, const glooxwrapper::OOB&) * * @return A JS array containing all known players and their presences */ -CScriptValRooted XmppClient::GUIGetPlayerList() +CScriptValRooted XmppClient::GUIGetPlayerList(ScriptInterface& scriptInterface) { std::string presence; CScriptValRooted playerList; - m_ScriptInterface.Eval("({})", playerList); + scriptInterface.Eval("({})", playerList); for(std::map::const_iterator it = m_PlayerMap.begin(); it != m_PlayerMap.end(); ++it) { CScriptValRooted player; GetPresenceString(it->second, presence); - m_ScriptInterface.Eval("({})", player); - m_ScriptInterface.SetProperty(player.get(), "name", wstring_from_utf8(it->first)); - m_ScriptInterface.SetProperty(player.get(), "presence", wstring_from_utf8(presence)); + scriptInterface.Eval("({})", player); + scriptInterface.SetProperty(player.get(), "name", wstring_from_utf8(it->first)); + scriptInterface.SetProperty(player.get(), "presence", wstring_from_utf8(presence)); - m_ScriptInterface.SetProperty(playerList.get(), wstring_from_utf8(it->first).c_str(), player); + scriptInterface.SetProperty(playerList.get(), wstring_from_utf8(it->first).c_str(), player); } return playerList; @@ -486,21 +480,21 @@ CScriptValRooted XmppClient::GUIGetPlayerList() * * @return A JS array containing all known games */ -CScriptValRooted XmppClient::GUIGetGameList() +CScriptValRooted XmppClient::GUIGetGameList(ScriptInterface& scriptInterface) { CScriptValRooted gameList; - m_ScriptInterface.Eval("([])", gameList); + scriptInterface.Eval("([])", gameList); for(std::vector::const_iterator it = m_GameList.begin(); it != m_GameList.end(); ++it) { CScriptValRooted game; - m_ScriptInterface.Eval("({})", game); + scriptInterface.Eval("({})", game); const char* stats[] = { "name", "ip", "state", "nbp", "tnbp", "players", "mapName", "niceMapName", "mapSize", "mapType", "victoryCondition" }; short stats_length = 11; for (short i = 0; i < stats_length; i++) - m_ScriptInterface.SetProperty(game.get(), stats[i], wstring_from_utf8((*it)->findAttribute(stats[i]).to_string())); + scriptInterface.SetProperty(game.get(), stats[i], wstring_from_utf8((*it)->findAttribute(stats[i]).to_string())); - m_ScriptInterface.CallFunctionVoid(gameList.get(), "push", game); + scriptInterface.CallFunctionVoid(gameList.get(), "push", game); } return gameList; @@ -511,21 +505,21 @@ CScriptValRooted XmppClient::GUIGetGameList() * * @return A JS array containing all known leaderboard data */ -CScriptValRooted XmppClient::GUIGetBoardList() +CScriptValRooted XmppClient::GUIGetBoardList(ScriptInterface& scriptInterface) { CScriptValRooted boardList; - m_ScriptInterface.Eval("([])", boardList); + scriptInterface.Eval("([])", boardList); for(std::vector::const_iterator it = m_BoardList.begin(); it != m_BoardList.end(); ++it) { CScriptValRooted board; - m_ScriptInterface.Eval("({})", board); + scriptInterface.Eval("({})", board); const char* attributes[] = { "name", "rank", "rating" }; short attributes_length = 3; for (short i = 0; i < attributes_length; i++) - m_ScriptInterface.SetProperty(board.get(), attributes[i], wstring_from_utf8((*it)->findAttribute(attributes[i]).to_string())); + scriptInterface.SetProperty(board.get(), attributes[i], wstring_from_utf8((*it)->findAttribute(attributes[i]).to_string())); - m_ScriptInterface.CallFunctionVoid(boardList.get(), "push", board); + scriptInterface.CallFunctionVoid(boardList.get(), "push", board); } return boardList; @@ -538,14 +532,29 @@ CScriptValRooted XmppClient::GUIGetBoardList() /** * Send GUI message queue when queried. */ -CScriptValRooted XmppClient::GuiPollMessage() +CScriptValRooted XmppClient::GuiPollMessage(ScriptInterface& scriptInterface) { if (m_GuiMessageQueue.empty()) return CScriptValRooted(); - CScriptValRooted r = m_GuiMessageQueue.front(); + GUIMessage message = m_GuiMessageQueue.front(); + CScriptValRooted messageVal; + + scriptInterface.Eval("({})", messageVal); + scriptInterface.SetProperty(messageVal.get(), "type", message.type); + if (!message.from.empty()) + scriptInterface.SetProperty(messageVal.get(), "from", message.from); + if (!message.text.empty()) + scriptInterface.SetProperty(messageVal.get(), "text", message.text); + if (!message.level.empty()) + scriptInterface.SetProperty(messageVal.get(), "level", message.level); + if (!message.message.empty()) + scriptInterface.SetProperty(messageVal.get(), "message", message.message); + if (!message.data.empty()) + scriptInterface.SetProperty(messageVal.get(), "data", message.data); + m_GuiMessageQueue.pop_front(); - return r; + return messageVal; } /** @@ -561,9 +570,8 @@ void XmppClient::SendMUCMessage(const std::string& message) * * @param message Message to add to the queue */ -void XmppClient::PushGuiMessage(const CScriptValRooted& message) +void XmppClient::PushGuiMessage(XmppClient::GUIMessage message) { - ENSURE(!message.undefined()); m_GuiMessageQueue.push_back(message); } @@ -574,10 +582,10 @@ void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Me { DbgXMPP(msg.from().resource() << " said " << msg.body()); - CScriptValRooted message; - m_ScriptInterface.Eval("({ 'type':'mucmessage'})", message); - m_ScriptInterface.SetProperty(message.get(), "from", wstring_from_utf8(msg.from().resource().to_string())); - m_ScriptInterface.SetProperty(message.get(), "text", wstring_from_utf8(msg.body().to_string())); + GUIMessage message; + message.type = L"mucmessage"; + message.from = wstring_from_utf8(msg.from().resource().to_string()); + message.text = wstring_from_utf8(msg.body().to_string()); PushGuiMessage(message); } @@ -589,10 +597,9 @@ void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::M DbgXMPP("type " << msg.subtype() << ", subject " << msg.subject() << ", message " << msg.body() << ", thread id " << msg.thread()); - CScriptValRooted message; - m_ScriptInterface.Eval("({'type':'message'})", message); - m_ScriptInterface.SetProperty(message.get(), "from", wstring_from_utf8(msg.from().username().to_string())); - m_ScriptInterface.SetProperty(message.get(), "text", wstring_from_utf8(msg.body().to_string())); + GUIMessage message; + message.from = wstring_from_utf8(msg.from().username().to_string()); + message.message = wstring_from_utf8(msg.body().to_string()); PushGuiMessage(message); } @@ -654,12 +661,11 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq) */ void XmppClient::CreateSimpleMessage(const std::string& type, const std::string& text, const std::string& level, const std::string& data) { - CScriptValRooted message; - m_ScriptInterface.Eval("({})", message); - m_ScriptInterface.SetProperty(message.get(), "type", wstring_from_utf8(type)); - m_ScriptInterface.SetProperty(message.get(), "level", wstring_from_utf8(level)); - m_ScriptInterface.SetProperty(message.get(), "text", wstring_from_utf8(text)); - m_ScriptInterface.SetProperty(message.get(), "data", wstring_from_utf8(data)); + GUIMessage message; + message.type = wstring_from_utf8(type); + message.level = wstring_from_utf8(level); + message.text = wstring_from_utf8(text); + message.data = wstring_from_utf8(data); PushGuiMessage(message); } diff --git a/source/lobby/XmppClient.h b/source/lobby/XmppClient.h index dcfef2f447..6594dbb518 100644 --- a/source/lobby/XmppClient.h +++ b/source/lobby/XmppClient.h @@ -39,8 +39,6 @@ class XmppClient : public IXmppClient, public glooxwrapper::ConnectionListener, { NONCOPYABLE(XmppClient); private: - //Game - script - ScriptInterface& m_ScriptInterface; //Components glooxwrapper::Client* m_client; glooxwrapper::MUCRoom* m_mucRoom; @@ -53,7 +51,7 @@ private: public: //Basic - XmppClient(ScriptInterface& scriptInterface, const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt = false); + XmppClient(const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, bool regOpt = false); virtual ~XmppClient(); //Network @@ -62,8 +60,8 @@ public: void recv(); void SendIqGetGameList(); void SendIqGetBoardList(); - void SendIqGameReport(CScriptVal data); - void SendIqRegisterGame(CScriptVal data); + void SendIqGameReport(ScriptInterface& scriptInterface, CScriptVal data); + void SendIqRegisterGame(ScriptInterface& scriptInterface, CScriptVal data); void SendIqUnregisterGame(); void SendIqChangeStateGame(const std::string& nbp, const std::string& players); void SetNick(const std::string& nick); @@ -73,9 +71,9 @@ public: void SetPresence(const std::string& presence); void GetPresence(const std::string& nickname, std::string& presence); - CScriptValRooted GUIGetPlayerList(); - CScriptValRooted GUIGetGameList(); - CScriptValRooted GUIGetBoardList(); + CScriptValRooted GUIGetPlayerList(ScriptInterface& scriptInterface); + CScriptValRooted GUIGetGameList(ScriptInterface& scriptInterface); + CScriptValRooted GUIGetBoardList(ScriptInterface& scriptInterface); //Script ScriptInterface& GetScriptInterface(); @@ -120,10 +118,19 @@ protected: std::string StanzaErrorToString(gloox::StanzaError err); public: /* Messages */ - CScriptValRooted GuiPollMessage(); + struct GUIMessage + { + std::wstring type; + std::wstring level; + std::wstring text; + std::wstring data; + std::wstring from; + std::wstring message; + }; + CScriptValRooted GuiPollMessage(ScriptInterface& scriptInterface); void SendMUCMessage(const std::string& message); protected: - void PushGuiMessage(const CScriptValRooted& message); + void PushGuiMessage(XmppClient::GUIMessage message); void CreateSimpleMessage(const std::string& type, const std::string& text, const std::string& level = "standard", const std::string& data = ""); private: @@ -134,7 +141,7 @@ private: /// List of rankings std::vector m_BoardList; /// Queue of messages - std::deque m_GuiMessageQueue; + std::deque m_GuiMessageQueue; }; #endif // XMPPCLIENT_H diff --git a/source/lobby/scripting/JSInterface_Lobby.cpp b/source/lobby/scripting/JSInterface_Lobby.cpp new file mode 100644 index 0000000000..6a49ade974 --- /dev/null +++ b/source/lobby/scripting/JSInterface_Lobby.cpp @@ -0,0 +1,275 @@ +/* Copyright (C) 2013 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 . + */ + +#include "precompiled.h" + +#include "JSInterface_Lobby.h" + +#include "gui/GUIManager.h" +#include "lib/utf8.h" +#include "lobby/IXmppClient.h" +#include "lobby/sha.h" + +#include "scriptinterface/ScriptInterface.h" + +bool JSI_Lobby::HasXmppClient(void* UNUSED(cbdata)) +{ + return (g_XmppClient ? true : false); +} + +#if CONFIG2_LOBBY + +void JSI_Lobby::StartXmppClient(void* UNUSED(cbdata), std::wstring username, std::wstring password, std::wstring room, std::wstring nick) +{ + ENSURE(!g_XmppClient); + + g_XmppClient = IXmppClient::create(utf8_from_wstring(username), utf8_from_wstring(password), + utf8_from_wstring(room), utf8_from_wstring(nick)); + g_rankedGame = true; +} + +void JSI_Lobby::StartRegisterXmppClient(void* UNUSED(cbdata), std::wstring username, std::wstring password) +{ + ENSURE(!g_XmppClient); + + g_XmppClient = IXmppClient::create(utf8_from_wstring(username), utf8_from_wstring(password), + "", "", true); +} + +void JSI_Lobby::StopXmppClient(void* UNUSED(cbdata)) +{ + ENSURE(g_XmppClient); + SAFE_DELETE(g_XmppClient); + g_rankedGame = false; +} + +void JSI_Lobby::ConnectXmppClient(void* UNUSED(cbdata)) +{ + ENSURE(g_XmppClient); + g_XmppClient->connect(); +} + +void JSI_Lobby::DisconnectXmppClient(void* UNUSED(cbdata)) +{ + ENSURE(g_XmppClient); + g_XmppClient->disconnect(); +} + +void JSI_Lobby::RecvXmppClient(void* UNUSED(cbdata)) +{ + if (!g_XmppClient) + return; + g_XmppClient->recv(); +} + +void JSI_Lobby::SendGetGameList(void* UNUSED(cbdata)) +{ + if (!g_XmppClient) + return; + g_XmppClient->SendIqGetGameList(); +} + +void JSI_Lobby::SendGetBoardList(void* UNUSED(cbdata)) +{ + if (!g_XmppClient) + return; + g_XmppClient->SendIqGetBoardList(); +} + +void JSI_Lobby::SendGameReport(void* cbdata, CScriptVal data) +{ + if (!g_XmppClient) + return; + + CGUIManager* guiManager = static_cast (cbdata); + g_XmppClient->SendIqGameReport(guiManager->GetScriptInterface(), data); +} + +void JSI_Lobby::SendRegisterGame(void* cbdata, CScriptVal data) +{ + if (!g_XmppClient) + return; + + CGUIManager* guiManager = static_cast (cbdata); + g_XmppClient->SendIqRegisterGame(guiManager->GetScriptInterface(), data); +} + +void JSI_Lobby::SendUnregisterGame(void* UNUSED(cbdata)) +{ + if (!g_XmppClient) + return; + g_XmppClient->SendIqUnregisterGame(); +} + +void JSI_Lobby::SendChangeStateGame(void* UNUSED(cbdata), std::wstring nbp, std::wstring players) +{ + if (!g_XmppClient) + return; + g_XmppClient->SendIqChangeStateGame(utf8_from_wstring(nbp), utf8_from_wstring(players)); +} + +CScriptVal JSI_Lobby::GetPlayerList(void* cbdata) +{ + if (!g_XmppClient) + return CScriptVal(); + + CGUIManager* guiManager = static_cast (cbdata); + CScriptValRooted playerList = g_XmppClient->GUIGetPlayerList(guiManager->GetScriptInterface()); + + return playerList.get(); +} + +CScriptVal JSI_Lobby::GetGameList(void* cbdata) +{ + if (!g_XmppClient) + return CScriptVal(); + + CGUIManager* guiManager = static_cast (cbdata); + CScriptValRooted gameList = g_XmppClient->GUIGetGameList(guiManager->GetScriptInterface()); + + return gameList.get(); +} + +CScriptVal JSI_Lobby::GetBoardList(void* cbdata) +{ + if (!g_XmppClient) + return CScriptVal(); + + CGUIManager* guiManager = static_cast (cbdata); + CScriptValRooted boardList = g_XmppClient->GUIGetBoardList(guiManager->GetScriptInterface()); + + return boardList.get(); +} + +CScriptVal JSI_Lobby::LobbyGuiPollMessage(void* cbdata) +{ + if (!g_XmppClient) + return CScriptVal(); + + CGUIManager* guiManager = static_cast (cbdata); + CScriptValRooted poll = g_XmppClient->GuiPollMessage(guiManager->GetScriptInterface()); + + return poll.get(); +} + +void JSI_Lobby::LobbySendMessage(void* UNUSED(cbdata), std::wstring message) +{ + if (!g_XmppClient) + return; + + g_XmppClient->SendMUCMessage(utf8_from_wstring(message)); +} + +void JSI_Lobby::LobbySetPlayerPresence(void* UNUSED(cbdata), std::wstring presence) +{ + if (!g_XmppClient) + return; + + g_XmppClient->SetPresence(utf8_from_wstring(presence)); +} + +void JSI_Lobby::LobbySetNick(void* UNUSED(cbdata), std::wstring nick) +{ + if (!g_XmppClient) + return; + + g_XmppClient->SetNick(utf8_from_wstring(nick)); +} + +std::wstring JSI_Lobby::LobbyGetNick(void* UNUSED(cbdata)) +{ + if (!g_XmppClient) + return L""; + + std::string nick; + g_XmppClient->GetNick(nick); + return wstring_from_utf8(nick); +} + +void JSI_Lobby::LobbyKick(void* UNUSED(cbdata), std::wstring nick, std::wstring reason) +{ + if (!g_XmppClient) + return; + + g_XmppClient->kick(utf8_from_wstring(nick), utf8_from_wstring(reason)); +} + +void JSI_Lobby::LobbyBan(void* UNUSED(cbdata), std::wstring nick, std::wstring reason) +{ + if (!g_XmppClient) + return; + + g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason)); +} + +std::wstring JSI_Lobby::LobbyGetPlayerPresence(void* UNUSED(cbdata), std::wstring nickname) +{ + if (!g_XmppClient) + return L""; + + std::string presence; + g_XmppClient->GetPresence(utf8_from_wstring(nickname), presence); + return wstring_from_utf8(presence); +} + +// Non-public secure PBKDF2 hash function with salting and 1,337 iterations +std::string JSI_Lobby::EncryptPassword(const std::string& password, const std::string& username) +{ + const int DIGESTSIZE = SHA_DIGEST_SIZE; + const int ITERATIONS = 1337; + + static const byte 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 + byte salt_buffer[DIGESTSIZE] = {0}; + SHA256 hash; + hash.update(salt_base, sizeof(salt_base)); + hash.update(username.c_str(), username.length()); + hash.finish(salt_buffer); + + // PBKDF2 to create the buffer + byte encrypted[DIGESTSIZE]; + pbkdf2(encrypted, (byte*)password.c_str(), password.length(), salt_buffer, DIGESTSIZE, ITERATIONS); + + static const char base16[] = "0123456789ABCDEF"; + char hex[2 * DIGESTSIZE]; + for (int i = 0; i < DIGESTSIZE; ++i) + { + hex[i*2] = base16[encrypted[i] >> 4]; // 4 high bits + hex[i*2 + 1] = base16[encrypted[i] & 0x0F];// 4 low bits + } + return std::string(hex, sizeof(hex)); +} + +std::wstring JSI_Lobby::EncryptPassword(void* UNUSED(cbdata), std::wstring pass, std::wstring user) +{ + return wstring_from_utf8(JSI_Lobby::EncryptPassword(utf8_from_wstring(pass), utf8_from_wstring(user))); +} + +bool JSI_Lobby::IsRankedGame(void* UNUSED(cbdata)) +{ + return g_rankedGame; +} + +void JSI_Lobby::SetRankedGame(void* UNUSED(cbdata), bool isRanked) +{ + g_rankedGame = isRanked; +} + +#endif \ No newline at end of file diff --git a/source/lobby/scripting/JSInterface_Lobby.h b/source/lobby/scripting/JSInterface_Lobby.h new file mode 100644 index 0000000000..759ee53507 --- /dev/null +++ b/source/lobby/scripting/JSInterface_Lobby.h @@ -0,0 +1,66 @@ +/* Copyright (C) 2013 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 . + */ + +#ifndef INCLUDED_JSI_LOBBY +#define INCLUDED_JSI_LOBBY + +#include "scriptinterface/ScriptVal.h" +#include "lib/config2.h" // for CONFIG2_LOBBY + +class ScriptInterface; + +namespace JSI_Lobby +{ + bool HasXmppClient(void* cbdata); + +#if CONFIG2_LOBBY + void StartXmppClient(void* cbdata, std::wstring username, std::wstring password, std::wstring room, std::wstring nick); + void StartRegisterXmppClient(void* cbdata, std::wstring username, std::wstring password); + void StopXmppClient(void* cbdata); + void ConnectXmppClient(void* cbdata); + void DisconnectXmppClient(void* cbdata); + void RecvXmppClient(void* cbdata); + void SendGetGameList(void* cbdata); + void SendGetBoardList(void* cbdata); + void SendGameReport(void* cbdata, CScriptVal data); + void SendRegisterGame(void* cbdata, CScriptVal data); + void SendUnregisterGame(void* cbdata); + void SendChangeStateGame(void* cbdata, std::wstring nbp, std::wstring players); + CScriptVal GetPlayerList(void* cbdata); + CScriptVal GetGameList(void* cbdata); + CScriptVal GetBoardList(void* cbdata); + CScriptVal LobbyGuiPollMessage(void* cbdata); + void LobbySendMessage(void* cbdata, std::wstring message); + void LobbySetPlayerPresence(void* cbdata, std::wstring presence); + void LobbySetNick(void* cbdata, std::wstring nick); + std::wstring LobbyGetNick(void* cbdata); + void LobbyKick(void* cbdata, std::wstring nick, std::wstring reason); + void LobbyBan(void* cbdata, std::wstring nick, std::wstring reason); + std::wstring LobbyGetPlayerPresence(void* cbdata, std::wstring nickname); + + // Non-public secure PBKDF2 hash function with salting and 1,337 iterations + std::string EncryptPassword(const std::string& password, const std::string& username); + + // Public hash interface. + std::wstring EncryptPassword(void* cbdata, std::wstring pass, std::wstring user); + + bool IsRankedGame(void* cbdata); + void SetRankedGame(void* cbdata, bool isRanked); +#endif // CONFIG2_LOBBY +} + +#endif \ No newline at end of file