1
0
forked from 0ad/0ad

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.
This commit is contained in:
elexis 2019-09-12 17:23:33 +00:00
parent 8f3277cb99
commit 4c454f3eee
7 changed files with 254 additions and 126 deletions

View File

@ -47,9 +47,9 @@ public:
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 void GetSubject(std::string& subject) = 0;
virtual const char* GetPresence(const std::string& nickname) = 0;
virtual const char* GetRole(const std::string& nickname) = 0;
virtual const std::wstring& GetSubject() = 0;
virtual void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
virtual void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;

View File

@ -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"
@ -284,8 +285,8 @@ void XmppClient::onDisconnect(gloox::ConnectionError error)
"system",
"disconnected",
std::time(nullptr),
"reason", ConnectionErrorToString(error),
"certificate_status", CertificateErrorToString(m_certStatus));
"reason", error,
"certificate_status", m_certStatus);
}
/**
@ -317,7 +318,7 @@ bool XmppClient::onTLSConnect(const glooxwrapper::CertInfo& info)
*/
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);
}
/*****************************************************
@ -504,7 +505,7 @@ void XmppClient::handleRegistrationResult(const glooxwrapper::JID&, gloox::Regis
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();
}
@ -541,16 +542,16 @@ void XmppClient::GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::Mu
scriptInterface.CreateArray(ret);
int j = 0;
for (const std::pair<std::string, std::vector<std::string> >& p : m_PlayerMap)
for (const std::pair<glooxwrapper::string, SPlayer>& 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);
}
@ -579,7 +580,7 @@ void XmppClient::GUIGetGameList(const ScriptInterface& scriptInterface, JS::Muta
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);
}
@ -606,7 +607,7 @@ void XmppClient::GUIGetBoardList(const ScriptInterface& scriptInterface, JS::Mut
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);
}
@ -633,7 +634,7 @@ void XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface, JS::Mutab
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);
}
@ -747,8 +748,8 @@ void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Me
"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());
}
/**
@ -763,8 +764,8 @@ void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::M
"chat",
"private-message",
ComputeTimestamp(msg),
"from", msg.from().resource().to_string(),
"text", msg.body().to_string());
"from", msg.from().resource(),
"text", msg.body());
}
/**
@ -807,10 +808,10 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
{
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())
const PlayerMap::iterator it = m_PlayerMap.find(t->findAttribute("name"));
if (it != m_PlayerMap.end())
{
m_PlayerMap[name][1] = t->findAttribute("rating").to_string();
it->second.m_Rating = t->findAttribute("rating");
m_PlayerMapUpdate = true;
}
}
@ -846,12 +847,13 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
}
}
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;
}
@ -860,57 +862,91 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
*/
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(), participant.role, std::move(m_PlayerMap.at(nick).m_Rating)));
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);
}
else
{
const PlayerMap::iterator it = m_PlayerMap.find(nick);
/* During the initialization process, we receive join messages for everyone
* currently in the room. We don't want to display these, so we filter them
* out. We will always be the last to join during initialization.
*/
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);
else if (it == m_PlayerMap.end())
{
CreateGUIMessage(
"chat",
"join",
std::time(nullptr),
"nick", nick);
}
else if (it->second.m_Role != participant.role)
{
CreateGUIMessage(
"chat",
"role",
std::time(nullptr),
"nick", nick,
"oldrole", it->second.m_Role,
"newrole", participant.role);
}
else
{
// Don't create a GUI message for regular presence changes, because
@ -918,10 +954,23 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
// the only way they are used is to determine whether to update the playerlist.
}
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));
if (it == m_PlayerMap.end())
{
m_PlayerMap.emplace(
std::piecewise_construct,
std::forward_as_tuple(nick),
std::forward_as_tuple(presence.presence(), participant.role, std::string()));
}
else
{
it->second.m_Presence = presence.presence();
it->second.m_Role = participant.role;
}
}
m_PlayerMapUpdate = true;
@ -932,18 +981,22 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
*/
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 = wstring_from_utf8(subject.to_string());
CreateGUIMessage(
"chat",
"subject",
std::time(nullptr),
"nick", nick,
"subject", m_Subject);
}
/**
* Get current subject.
*
* @param topic Variable to store subject in.
*/
void XmppClient::GetSubject(std::string& subject)
const std::wstring& XmppClient::GetSubject()
{
subject = m_Subject;
return m_Subject;
}
/**
@ -1008,30 +1061,28 @@ void XmppClient::SetPresence(const std::string& presence)
/**
* 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";
const 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 = "";
const PlayerMap::iterator it = m_PlayerMap.find(nick);
if (it == m_PlayerMap.end())
return "";
return GetRoleString(it->second.m_Role);
}
/*****************************************************
@ -1045,7 +1096,7 @@ void XmppClient::GetRole(const std::string& nick, std::string& role)
*
* @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())
@ -1063,16 +1114,13 @@ std::time_t XmppClient::ComputeTimestamp(const glooxwrapper::Message& msg) const
}
/**
* 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");
@ -1083,31 +1131,28 @@ void XmppClient::GetPresenceString(const gloox::Presence::PresenceType p, std::s
CASE(Error, "error");
CASE(Invalid, "invalid");
default:
LOGERROR("Unknown presence type '%d'", (int)p);
break;
LOGERROR("Unknown presence type '%d'", static_cast<int>(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<int>(role));
return "";
#undef CASE
}
}
@ -1116,7 +1161,7 @@ void XmppClient::GetRoleString(const gloox::MUCRoomRole r, std::string& role) co
* 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<gloox::CertStatus, std::string> certificateErrorStrings = {
{ gloox::CertInvalid, g_L10n.Translate("The certificate is not trusted.") },
@ -1144,7 +1189,7 @@ std::string XmppClient::CertificateErrorToString(gloox::CertStatus status) const
* @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 + ")"
@ -1188,7 +1233,7 @@ std::string XmppClient::StanzaErrorToString(gloox::StanzaError err) const
* @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 + ")"
@ -1227,7 +1272,7 @@ std::string XmppClient::ConnectionErrorToString(gloox::ConnectionError err) cons
* @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 + ")"
@ -1251,6 +1296,8 @@ std::string XmppClient::RegistrationResultToString(gloox::RegistrationResult res
void XmppClient::SendStunEndpointToHost(const StunClient::StunEndpoint& stunEndpoint, const std::string& hostJIDStr)
{
DbgXMPP("SendStunEndpointToHost " << hostJIDStr);
char ipStr[256] = "(error)";
ENetAddress addr;
addr.host = ntohl(stunEndpoint.ip);

View File

@ -88,9 +88,9 @@ public:
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);
void GetSubject(std::string& subject);
const char* GetPresence(const std::string& nickname);
const char* GetRole(const std::string& nickname);
const std::wstring& GetSubject();
void GUIGetPlayerList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
@ -99,6 +99,17 @@ public:
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 @@ protected:
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:
JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface);
JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface);
@ -162,8 +164,19 @@ protected:
Args const&... args);
private:
struct SPlayer {
SPlayer(const gloox::Presence::PresenceType presence, const gloox::MUCRoomRole role, const glooxwrapper::string& rating)
: m_Presence(presence), m_Role(role), m_Rating(rating)
{
}
gloox::Presence::PresenceType m_Presence;
gloox::MUCRoomRole m_Role;
glooxwrapper::string m_Rating;
};
using PlayerMap = std::map<glooxwrapper::string, SPlayer>;
/// Map of players
std::map<std::string, std::vector<std::string> > m_PlayerMap;
PlayerMap m_PlayerMap;
/// Whether or not the playermap has changed since the last time the GUI checked.
bool m_PlayerMapUpdate;
/// List of games
@ -179,7 +192,7 @@ private:
/// Cache of all GUI messages received since the login
std::vector<JS::Heap<JS::Value> > m_HistoricGuiMessages;
/// Current room subject/topic.
std::string m_Subject;
std::wstring m_Subject;
};
#endif // XMPPCLIENT_H

View File

@ -161,6 +161,9 @@ namespace glooxwrapper
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 @@ namespace glooxwrapper
{
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)

View File

@ -0,0 +1,61 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#include "precompiled.h"
#include "lib/config2.h"
#if CONFIG2_LOBBY
#include "lobby/XmppClient.h"
#include "scriptinterface/ScriptInterface.h"
template<> void ScriptInterface::ToJSVal<glooxwrapper::string>(JSContext* cx, JS::MutableHandleValue ret, const glooxwrapper::string& val)
{
ToJSVal(cx, ret, wstring_from_utf8(val.to_string()));
}
template<> void ScriptInterface::ToJSVal<gloox::Presence::PresenceType>(JSContext* cx, JS::MutableHandleValue ret, const gloox::Presence::PresenceType& val)
{
ToJSVal(cx, ret, XmppClient::GetPresenceString(val));
}
template<> void ScriptInterface::ToJSVal<gloox::MUCRoomRole>(JSContext* cx, JS::MutableHandleValue ret, const gloox::MUCRoomRole& val)
{
ToJSVal(cx, ret, XmppClient::GetRoleString(val));
}
template<> void ScriptInterface::ToJSVal<gloox::StanzaError>(JSContext* cx, JS::MutableHandleValue ret, const gloox::StanzaError& val)
{
ToJSVal(cx, ret, wstring_from_utf8(XmppClient::StanzaErrorToString(val)));
}
template<> void ScriptInterface::ToJSVal<gloox::ConnectionError>(JSContext* cx, JS::MutableHandleValue ret, const gloox::ConnectionError& val)
{
ToJSVal(cx, ret, wstring_from_utf8(XmppClient::ConnectionErrorToString(val)));
}
template<> void ScriptInterface::ToJSVal<gloox::RegistrationResult>(JSContext* cx, JS::MutableHandleValue ret, const gloox::RegistrationResult& val)
{
ToJSVal(cx, ret, wstring_from_utf8(XmppClient::RegistrationResultToString(val)));
}
template<> void ScriptInterface::ToJSVal<gloox::CertStatus>(JSContext* cx, JS::MutableHandleValue ret, const gloox::CertStatus& val)
{
ToJSVal(cx, ret, wstring_from_utf8(XmppClient::CertificateErrorToString(val)));
}
#endif // CONFIG2_LOBBY

View File

@ -65,8 +65,8 @@ void JSI_Lobby::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
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");
scriptInterface.RegisterFunction<std::wstring, std::wstring, &JSI_Lobby::LobbyGetPlayerPresence>("LobbyGetPlayerPresence");
scriptInterface.RegisterFunction<std::wstring, std::wstring, &JSI_Lobby::LobbyGetPlayerRole>("LobbyGetPlayerRole");
scriptInterface.RegisterFunction<const char*, std::wstring, &JSI_Lobby::LobbyGetPlayerPresence>("LobbyGetPlayerPresence");
scriptInterface.RegisterFunction<const char*, std::wstring, &JSI_Lobby::LobbyGetPlayerRole>("LobbyGetPlayerRole");
scriptInterface.RegisterFunction<std::wstring, std::wstring, std::wstring, &JSI_Lobby::EncryptPassword>("EncryptPassword");
scriptInterface.RegisterFunction<std::wstring, &JSI_Lobby::LobbyGetRoomSubject>("LobbyGetRoomSubject");
#endif // CONFIG2_LOBBY
@ -309,24 +309,20 @@ void JSI_Lobby::LobbyBan(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const s
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
@ -381,9 +377,7 @@ std::wstring JSI_Lobby::LobbyGetRoomSubject(ScriptInterface::CxPrivate* UNUSED(p
if (!g_XmppClient)
return L"";
std::string subject;
g_XmppClient->GetSubject(subject);
return wstring_from_utf8(subject);
return g_XmppClient->GetSubject();
}
#endif

View File

@ -57,8 +57,8 @@ namespace JSI_Lobby
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