Index: source/lobby/IXmppClient.h =================================================================== --- source/lobby/IXmppClient.h +++ source/lobby/IXmppClient.h @@ -47,8 +47,8 @@ virtual void kick(const std::string& nick, const std::string& reason) = 0; virtual void ban(const std::string& nick, const std::string& reason) = 0; virtual void SetPresence(const std::string& presence) = 0; - virtual void GetPresence(const std::string& nickname, std::string& presence) = 0; - virtual void GetRole(const std::string& nickname, std::string& role) = 0; + virtual const char* GetPresence(const std::string& nickname) = 0; + virtual const char* GetRole(const std::string& nickname) = 0; virtual void GetSubject(std::string& subject) = 0; virtual void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0; Index: source/lobby/XmppClient.h =================================================================== --- source/lobby/XmppClient.h +++ source/lobby/XmppClient.h @@ -88,8 +88,8 @@ void kick(const std::string& nick, const std::string& reason); void ban(const std::string& nick, const std::string& reason); void SetPresence(const std::string& presence); - void GetPresence(const std::string& nickname, std::string& presence); - void GetRole(const std::string& nickname, std::string& role); + const char* GetPresence(const std::string& nickname); + const char* GetRole(const std::string& nickname); void GetSubject(std::string& subject); void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret); @@ -99,6 +99,17 @@ void SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJID); + /** + * Convert gloox values to string or time. + */ + static const char* GetPresenceString(const gloox::Presence::PresenceType presenceType); + static const char* GetRoleString(const gloox::MUCRoomRole role); + static std::string StanzaErrorToString(gloox::StanzaError err); + static std::string RegistrationResultToString(gloox::RegistrationResult res); + static std::string ConnectionErrorToString(gloox::ConnectionError err); + static std::string CertificateErrorToString(gloox::CertStatus status); + static std::time_t ComputeTimestamp(const glooxwrapper::Message& msg); + protected: /* Xmpp handlers */ /* MUC handlers */ @@ -138,15 +149,6 @@ virtual void handleSessionAction(gloox::Jingle::Action action, glooxwrapper::Jingle::Session& session, const glooxwrapper::Jingle::Session::Jingle& jingle); virtual void handleSessionInitiation(glooxwrapper::Jingle::Session& session, const glooxwrapper::Jingle::Session::Jingle& jingle); - // Helpers - void GetPresenceString(const gloox::Presence::PresenceType p, std::string& presence) const; - void GetRoleString(const gloox::MUCRoomRole r, std::string& role) const; - std::string StanzaErrorToString(gloox::StanzaError err) const; - std::string ConnectionErrorToString(gloox::ConnectionError err) const; - std::string CertificateErrorToString(gloox::CertStatus status) const; - std::string RegistrationResultToString(gloox::RegistrationResult res) const; - std::time_t ComputeTimestamp(const glooxwrapper::Message& msg) const; - public: bool GuiPollPresenceStatusUpdate(); JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface); @@ -162,8 +164,24 @@ Args const&... args); private: + struct SPlayer { + SPlayer() + : m_Presence(gloox::Presence::PresenceType::Invalid), m_Rating(), m_Role(gloox::MUCRoomRole::RoleInvalid) + { + } + + SPlayer(const gloox::Presence::PresenceType presence, const glooxwrapper::string& rating, const gloox::MUCRoomRole& role) + : m_Presence(presence), m_Rating(rating), m_Role(role) + { + } + + gloox::Presence::PresenceType m_Presence; + glooxwrapper::string m_Rating; + gloox::MUCRoomRole m_Role; + }; /// Map of players - std::map > m_PlayerMap; + using PlayerMap = std::map; + PlayerMap m_PlayerMap; /// List of games std::vector m_GameList; /// List of rankings Index: source/lobby/XmppClient.cpp =================================================================== --- source/lobby/XmppClient.cpp +++ source/lobby/XmppClient.cpp @@ -25,6 +25,7 @@ #endif #include "i18n/L10n.h" +#include "lobby/scripting/GlooxScriptConversions.cpp" #include "lib/external_libraries/enet.h" #include "lib/utf8.h" #include "network/NetServer.h" @@ -37,7 +38,7 @@ #include //debug -#if 1 +#if 0 #define DbgXMPP(x) #else #define DbgXMPP(x) std::cout << x << std::endl; @@ -283,8 +284,8 @@ "system", "disconnected", std::time(nullptr), - "reason", ConnectionErrorToString(error), - "certificate_status", CertificateErrorToString(m_certStatus)); + "reason", error, + "certificate_status", m_certStatus); } /** @@ -316,7 +317,7 @@ */ void XmppClient::handleMUCError(glooxwrapper::MUCRoom*, gloox::StanzaError err) { - CreateGUIMessage("system", "error", std::time(nullptr), "text", StanzaErrorToString(err)); + CreateGUIMessage("system", "error", std::time(nullptr), "text", err); } /***************************************************** @@ -503,7 +504,7 @@ if (result == gloox::RegistrationSuccess) CreateGUIMessage("system", "registered", std::time(nullptr)); else - CreateGUIMessage("system", "error", std::time(nullptr), "text", RegistrationResultToString(result)); + CreateGUIMessage("system", "error", std::time(nullptr), "text", result); disconnect(); } @@ -540,16 +541,16 @@ scriptInterface.CreateArray(ret); int j = 0; - for (const std::pair >& p : m_PlayerMap) + for (const std::pair& p : m_PlayerMap) { JS::RootedValue player(cx); scriptInterface.CreateObject( &player, - "name", wstring_from_utf8(p.first), - "presence", wstring_from_utf8(p.second[0]), - "rating", wstring_from_utf8(p.second[1]), - "role", wstring_from_utf8(p.second[2])); + "name", p.first, + "presence", p.second.m_Presence, + "rating", p.second.m_Rating, + "role", p.second.m_Role); scriptInterface.SetPropertyInt(ret, j++, player); } @@ -578,7 +579,7 @@ scriptInterface.CreateObject(&game); for (size_t i = 0; i < ARRAY_SIZE(stats); ++i) - scriptInterface.SetProperty(game, stats[i], wstring_from_utf8(t->findAttribute(stats[i]).to_string())); + scriptInterface.SetProperty(game, stats[i], t->findAttribute(stats[i])); scriptInterface.SetPropertyInt(ret, j++, game); } @@ -605,7 +606,7 @@ scriptInterface.CreateObject(&board); for (size_t i = 0; i < ARRAY_SIZE(attributes); ++i) - scriptInterface.SetProperty(board, attributes[i], wstring_from_utf8(t->findAttribute(attributes[i]).to_string())); + scriptInterface.SetProperty(board, attributes[i], t->findAttribute(attributes[i])); scriptInterface.SetPropertyInt(ret, j++, board); } @@ -632,7 +633,7 @@ scriptInterface.CreateObject(&profile); for (size_t i = 0; i < ARRAY_SIZE(stats); ++i) - scriptInterface.SetProperty(profile, stats[i], wstring_from_utf8(t->findAttribute(stats[i]).to_string())); + scriptInterface.SetProperty(profile, stats[i], t->findAttribute(stats[i])); scriptInterface.SetPropertyInt(ret, j++, profile); } @@ -671,6 +672,7 @@ m_ScriptInterface->CreateObject(&message, "type", type, "level", level, "time", static_cast(time)); JS::RootedObject messageObj(cx, message.toObjectOrNull()); SetGUIMessageProperty(cx, messageObj, args...); + m_ScriptInterface->SetProperty(message, "historic", false); m_ScriptInterface->FreezeObject(message, true); m_GuiMessageQueue.push_back(JS::Heap(message)); } @@ -697,6 +699,7 @@ if (JS_StructuredClone(cx, message, &messageCopy, nullptr, nullptr)) { scriptInterface.SetProperty(messageCopy, "historic", true); + m_ScriptInterface->FreezeObject(messageCopy, true); m_HistoricGuiMessages.push_back(JS::Heap(messageCopy)); } else @@ -739,8 +742,8 @@ "chat", priv ? "private-message" : "room-message", ComputeTimestamp(msg), - "from", msg.from().resource().to_string(), - "text", msg.body().to_string()); + "from", msg.from().resource(), + "text", msg.body()); } /** @@ -755,8 +758,8 @@ "chat", "private-message", ComputeTimestamp(msg), - "from", msg.from().resource().to_string(), - "text", msg.body().to_string()); + "from", msg.from().resource(), + "text", msg.body()); } /** @@ -799,11 +802,11 @@ { for (const glooxwrapper::Tag* const& t : bq->m_StanzaBoardList) { - std::string name = t->findAttribute("name").to_string(); - if (m_PlayerMap.find(name) != m_PlayerMap.end()) - m_PlayerMap[name][1] = t->findAttribute("rating").to_string(); + PlayerMap::iterator it = m_PlayerMap.find(t->findAttribute("name")); + if (it != m_PlayerMap.end()) + it->second.m_Rating = t->findAttribute("rating"); } - + m_PresenceUpdate = true; CreateGUIMessage("game", "ratinglist", std::time(nullptr)); } } @@ -836,12 +839,13 @@ } } else if (iq.subtype() == gloox::IQ::Error) - CreateGUIMessage("system", "error", std::time(nullptr), "text", StanzaErrorToString(iq.error_error())); + CreateGUIMessage("system", "error", std::time(nullptr), "text", iq.error_error()); else { - CreateGUIMessage("system", "error", std::time(nullptr), "text", g_L10n.Translate("unknown subtype (see logs)")); + CreateGUIMessage("system", "error", std::time(nullptr), "text", wstring_from_utf8(g_L10n.Translate("unknown subtype (see logs)"))); LOGMESSAGE("unknown subtype '%s'", tag_name(iq).c_str()); } + return true; } @@ -850,39 +854,57 @@ */ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const glooxwrapper::MUCRoomParticipant participant, const glooxwrapper::Presence& presence) { - std::string nick = participant.nick->resource().to_string(); - gloox::Presence::PresenceType presenceType = presence.presence(); - std::string presenceString, roleString; - GetPresenceString(presenceType, presenceString); - GetRoleString(participant.role, roleString); + const glooxwrapper::string& nick = participant.nick->resource(); - if (presenceType == gloox::Presence::Unavailable) + if (presence.presence() == gloox::Presence::Unavailable) { if (!participant.newNick.empty() && (participant.flags & (gloox::UserNickChanged | gloox::UserSelf))) { // we have a nick change - std::string newNick = participant.newNick.to_string(); - m_PlayerMap[newNick].resize(3); - m_PlayerMap[newNick][0] = presenceString; - m_PlayerMap[newNick][2] = roleString; + if (m_PlayerMap.find(participant.newNick) == m_PlayerMap.end()) + m_PlayerMap.emplace( + std::piecewise_construct, + std::forward_as_tuple(participant.newNick), + std::forward_as_tuple(presence.presence(), m_PlayerMap.at(nick).m_Rating, participant.role)); + else + LOGERROR("Nickname changed to an existing nick!"); - DbgXMPP(nick << " is now known as " << participant.newNick.to_string()); - CreateGUIMessage("chat", "nick", std::time(nullptr), "oldnick", nick, "newnick", participant.newNick.to_string()); + DbgXMPP(nick << " is now known as " << participant.newNick); + CreateGUIMessage( + "chat", + "nick", + std::time(nullptr), + "oldnick", nick, + "newnick", participant.newNick); } else if (participant.flags & gloox::UserKicked) { - DbgXMPP(nick << " was kicked. Reason: " << participant.reason.to_string()); - CreateGUIMessage("chat", "kicked", std::time(nullptr), "nick", nick, "reason", participant.reason.to_string()); + DbgXMPP(nick << " was kicked. Reason: " << participant.reason); + CreateGUIMessage( + "chat", + "kicked", + std::time(nullptr), + "nick", nick, + "reason", participant.reason); } else if (participant.flags & gloox::UserBanned) { - DbgXMPP(nick << " was banned. Reason: " << participant.reason.to_string()); - CreateGUIMessage("chat", "banned", std::time(nullptr), "nick", nick, "reason", participant.reason.to_string()); + DbgXMPP(nick << " was banned. Reason: " << participant.reason); + CreateGUIMessage( + "chat", + "banned", + std::time(nullptr), + "nick", nick, + "reason", participant.reason); } else { DbgXMPP(nick << " left the room (flags " << participant.flags << ")"); - CreateGUIMessage("chat", "leave", std::time(nullptr), "nick", nick); + CreateGUIMessage( + "chat", + "leave", + std::time(nullptr), + "nick", nick); } m_PlayerMap.erase(nick); } @@ -894,24 +916,46 @@ */ if (!m_initialLoadComplete) { - if (m_mucRoom->nick().to_string() == nick) + if (m_mucRoom->nick() == nick) m_initialLoadComplete = true; } else if (m_PlayerMap.find(nick) == m_PlayerMap.end()) - CreateGUIMessage("chat", "join", std::time(nullptr), "nick", nick); - else if (m_PlayerMap[nick][2] != roleString) - CreateGUIMessage("chat", "role", std::time(nullptr), "nick", nick, "oldrole", m_PlayerMap[nick][2], "newrole", roleString); + { + CreateGUIMessage( + "chat", + "join", + std::time(nullptr), + "nick", nick); + } + else if (m_PlayerMap.at(nick).m_Role != participant.role) + { + CreateGUIMessage( + "chat", + "role", + std::time(nullptr), + "nick", nick, + "oldrole", m_PlayerMap.at(nick).m_Role, + "newrole", participant.role); + } else + { // Don't create a GUI message for regular presence changes, because // several hundreds of them accumulate during a match, impacting performance terribly and // the only way they are used is to determine whether to update the playerlist. - m_PresenceUpdate = true; + } - DbgXMPP(nick << " is in the room, presence : " << (int)presenceType); - m_PlayerMap[nick].resize(3); - m_PlayerMap[nick][0] = presenceString; - m_PlayerMap[nick][2] = roleString; + DbgXMPP( + nick << " is in the room, " + "presence: " << GetPresenceString(presence.presence()) << ", " + "role: "<< GetRoleString(participant.role)); + + // Insert or update + SPlayer& player = m_PlayerMap[nick]; + player.m_Presence = presence.presence(); + player.m_Role = participant.role; } + + m_PresenceUpdate = true; } /** @@ -919,8 +963,14 @@ */ void XmppClient::handleMUCSubject(glooxwrapper::MUCRoom*, const glooxwrapper::string& nick, const glooxwrapper::string& subject) { - m_Subject = subject.c_str(); - CreateGUIMessage("chat", "subject", std::time(nullptr), "nick", nick.c_str(), "subject", m_Subject); + m_Subject = subject.to_string(); + + CreateGUIMessage( + "chat", + "subject", + std::time(nullptr), + "nick", nick, + "subject", m_Subject); } /** @@ -995,30 +1045,28 @@ /** * Get the current xmpp presence of the given nick. - * - * @param nick Nickname to look up presence for - * @param presence Variable to store the presence in */ -void XmppClient::GetPresence(const std::string& nick, std::string& presence) +const char* XmppClient::GetPresence(const std::string& nick) { - if (m_PlayerMap.find(nick) != m_PlayerMap.end()) - presence = m_PlayerMap[nick][0]; - else - presence = "offline"; + PlayerMap::iterator it = m_PlayerMap.find(nick); + + if (it == m_PlayerMap.end()) + return "offline"; + + return GetPresenceString(it->second.m_Presence); } /** * Get the current xmpp role of the given nick. - * - * @param nick Nickname to look up presence for - * @param role Variable to store the role in */ -void XmppClient::GetRole(const std::string& nick, std::string& role) +const char* XmppClient::GetRole(const std::string& nick) { - if (m_PlayerMap.find(nick) != m_PlayerMap.end()) - role = m_PlayerMap[nick][2]; - else - role = ""; + PlayerMap::iterator it = m_PlayerMap.find(nick); + + if (it == m_PlayerMap.end()) + return ""; + + return GetRoleString(it->second.m_Role); } /***************************************************** @@ -1032,7 +1080,7 @@ * * @returns Seconds since the epoch. */ -std::time_t XmppClient::ComputeTimestamp(const glooxwrapper::Message& msg) const +std::time_t XmppClient::ComputeTimestamp(const glooxwrapper::Message& msg) { // Only historic messages contain a timestamp! if (!msg.when()) @@ -1050,16 +1098,13 @@ } /** - * Convert a gloox presence type to string. - * - * @param p Presence to be converted - * @param presence Variable to store the converted presence string in + * Convert a gloox presence type to an untranslated string literal to be used as an identifier by the scripts. */ -void XmppClient::GetPresenceString(const gloox::Presence::PresenceType p, std::string& presence) const +const char* XmppClient::GetPresenceString(const gloox::Presence::PresenceType presenceType) { - switch(p) + switch (presenceType) { -#define CASE(x,y) case gloox::Presence::x: presence = y; break +#define CASE(X,Y) case gloox::Presence::X: return Y CASE(Available, "available"); CASE(Chat, "chat"); CASE(Away, "away"); @@ -1070,31 +1115,28 @@ CASE(Error, "error"); CASE(Invalid, "invalid"); default: - LOGERROR("Unknown presence type '%d'", (int)p); - break; + LOGERROR("Unknown presence type '%d'", static_cast(presenceType)); + return ""; #undef CASE } } /** - * Convert a gloox role type to string. - * - * @param p Role to be converted - * @param presence Variable to store the converted role string in + * Convert a gloox role type to an untranslated string literal to be used as an identifier by the scripts. */ -void XmppClient::GetRoleString(const gloox::MUCRoomRole r, std::string& role) const +const char* XmppClient::GetRoleString(const gloox::MUCRoomRole role) { - switch(r) + switch (role) { -#define CASE(X, Y) case gloox::X: role = Y; break +#define CASE(X, Y) case gloox::X: return Y CASE(RoleNone, "none"); CASE(RoleVisitor, "visitor"); CASE(RoleParticipant, "participant"); CASE(RoleModerator, "moderator"); CASE(RoleInvalid, "invalid"); default: - LOGERROR("Unknown role type '%d'", (int)r); - break; + LOGERROR("Unknown role type '%d'", static_cast(role)); + return ""; #undef CASE } } @@ -1103,7 +1145,7 @@ * Translates a gloox certificate error codes, i.e. gloox certificate statuses except CertOk. * Keep in sync with specifications. */ -std::string XmppClient::CertificateErrorToString(gloox::CertStatus status) const +std::string XmppClient::CertificateErrorToString(gloox::CertStatus status) { std::map certificateErrorStrings = { { gloox::CertInvalid, g_L10n.Translate("The certificate is not trusted.") }, @@ -1131,7 +1173,7 @@ * @param err Error to be converted * @return Converted error string */ -std::string XmppClient::StanzaErrorToString(gloox::StanzaError err) const +std::string XmppClient::StanzaErrorToString(gloox::StanzaError err) { #define CASE(X, Y) case gloox::X: return Y #define DEBUG_CASE(X, Y) case gloox::X: return g_L10n.Translate("Error") + " (" + Y + ")" @@ -1175,7 +1217,7 @@ * @param err Error to be converted * @return Converted error string */ -std::string XmppClient::ConnectionErrorToString(gloox::ConnectionError err) const +std::string XmppClient::ConnectionErrorToString(gloox::ConnectionError err) { #define CASE(X, Y) case gloox::X: return Y #define DEBUG_CASE(X, Y) case gloox::X: return g_L10n.Translate("Error") + " (" + Y + ")" @@ -1214,7 +1256,7 @@ * @param err Enum to be converted * @return Converted string */ -std::string XmppClient::RegistrationResultToString(gloox::RegistrationResult res) const +std::string XmppClient::RegistrationResultToString(gloox::RegistrationResult res) { #define CASE(X, Y) case gloox::X: return Y #define DEBUG_CASE(X, Y) case gloox::X: return g_L10n.Translate("Error") + " (" + Y + ")" Index: source/lobby/glooxwrapper/glooxwrapper.h =================================================================== --- source/lobby/glooxwrapper/glooxwrapper.h +++ source/lobby/glooxwrapper/glooxwrapper.h @@ -161,6 +161,9 @@ glooxwrapper_free(m_Data); } + /** + * Gloox strings are UTF encoded, so don't forget to decode it before passing it to the GUI! + */ std::string to_string() const { return std::string(m_Data, m_Size); @@ -185,6 +188,16 @@ { return strcmp(m_Data, str) != 0; } + + bool operator==(const string& str) const + { + return strcmp(m_Data, str.m_Data) == 0; + } + + bool operator<(const string& str) const + { + return strcmp(m_Data, str.m_Data) < 0; + } }; static inline std::ostream& operator<<(std::ostream& stream, const string& string) Index: source/lobby/scripting/GlooxScriptConversions.cpp =================================================================== --- /dev/null +++ source/lobby/scripting/GlooxScriptConversions.cpp @@ -0,0 +1,56 @@ +/* Copyright (C) 2019 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 "lobby/XmppClient.h" +#include "scriptinterface/ScriptInterface.h" + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const glooxwrapper::string& val) +{ + ToJSVal(cx, ret, wstring_from_utf8(val.to_string())); +} + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const gloox::Presence::PresenceType& val) +{ + ToJSVal(cx, ret, XmppClient::GetPresenceString(val)); +} + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const gloox::MUCRoomRole& val) +{ + ToJSVal(cx, ret, XmppClient::GetRoleString(val)); +} + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const gloox::StanzaError& val) +{ + ToJSVal(cx, ret, wstring_from_utf8(XmppClient::StanzaErrorToString(val))); +} + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const gloox::ConnectionError& val) +{ + ToJSVal(cx, ret, wstring_from_utf8(XmppClient::ConnectionErrorToString(val))); +} + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const gloox::RegistrationResult& val) +{ + ToJSVal(cx, ret, wstring_from_utf8(XmppClient::RegistrationResultToString(val))); +} + +template<> void ScriptInterface::ToJSVal(JSContext* cx, JS::MutableHandleValue ret, const gloox::CertStatus& val) +{ + ToJSVal(cx, ret, wstring_from_utf8(XmppClient::CertificateErrorToString(val))); +} Index: source/lobby/scripting/JSInterface_Lobby.h =================================================================== --- source/lobby/scripting/JSInterface_Lobby.h +++ source/lobby/scripting/JSInterface_Lobby.h @@ -57,8 +57,8 @@ std::wstring LobbyGetNick(ScriptInterface::CxPrivate* pCxPrivate); void LobbyKick(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nick, const std::wstring& reason); void LobbyBan(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nick, const std::wstring& reason); - std::wstring LobbyGetPlayerPresence(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nickname); - std::wstring LobbyGetPlayerRole(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nickname); + const char* LobbyGetPlayerPresence(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nickname); + const char* LobbyGetPlayerRole(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nickname); std::wstring LobbyGetRoomSubject(ScriptInterface::CxPrivate* pCxPrivate); // Non-public secure PBKDF2 hash function with salting and 1,337 iterations Index: source/lobby/scripting/JSInterface_Lobby.cpp =================================================================== --- source/lobby/scripting/JSInterface_Lobby.cpp +++ source/lobby/scripting/JSInterface_Lobby.cpp @@ -65,8 +65,8 @@ scriptInterface.RegisterFunction("LobbyGetNick"); scriptInterface.RegisterFunction("LobbyKick"); scriptInterface.RegisterFunction("LobbyBan"); - scriptInterface.RegisterFunction("LobbyGetPlayerPresence"); - scriptInterface.RegisterFunction("LobbyGetPlayerRole"); + scriptInterface.RegisterFunction("LobbyGetPlayerPresence"); + scriptInterface.RegisterFunction("LobbyGetPlayerRole"); scriptInterface.RegisterFunction("EncryptPassword"); scriptInterface.RegisterFunction("LobbyGetRoomSubject"); #endif // CONFIG2_LOBBY @@ -309,24 +309,20 @@ g_XmppClient->ban(utf8_from_wstring(nick), utf8_from_wstring(reason)); } -std::wstring JSI_Lobby::LobbyGetPlayerPresence(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& nickname) +const char* JSI_Lobby::LobbyGetPlayerPresence(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& nickname) { if (!g_XmppClient) - return L""; + return ""; - std::string presence; - g_XmppClient->GetPresence(utf8_from_wstring(nickname), presence); - return wstring_from_utf8(presence); + return g_XmppClient->GetPresence(utf8_from_wstring(nickname)); } -std::wstring JSI_Lobby::LobbyGetPlayerRole(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& nickname) +const char* JSI_Lobby::LobbyGetPlayerRole(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& nickname) { if (!g_XmppClient) - return L""; + return ""; - std::string role; - g_XmppClient->GetRole(utf8_from_wstring(nickname), role); - return wstring_from_utf8(role); + return g_XmppClient->GetRole(utf8_from_wstring(nickname)); } // Non-public secure PBKDF2 hash function with salting and 1,337 iterations