forked from 0ad/0ad
XmppClient cleanup.
Allow XmppClient to use arbitrary property names in GUIMessages. Remove duplication by calling CreateGUIMessage when receiving chat messages. Inline PushGUINotification. Use std::string in the GUIMessage because every data source is of that type. Apply the wstring_from_utf8 conversion to ensure correct display of less common UTF characters instead in the GuiPollMessage method. Add room subject change chat message. Differential Revision: https://code.wildfiregames.com/D835 Refs #4482 Comments by fpre, Vladislav and leper This was SVN commit r20064.
This commit is contained in:
parent
6861588371
commit
0940db3fc0
@ -135,7 +135,7 @@ var g_NetMessageTypes = {
|
||||
addChatMessage({
|
||||
"from": "system",
|
||||
"time": msg.time,
|
||||
"text": translate("Disconnected.") + " " + msg.text
|
||||
"text": translate("Disconnected.") + " " + msg.reason
|
||||
});
|
||||
return true;
|
||||
},
|
||||
@ -150,13 +150,23 @@ var g_NetMessageTypes = {
|
||||
},
|
||||
"chat": {
|
||||
"subject": msg => {
|
||||
updateSubject(msg.text);
|
||||
updateSubject(msg.subject);
|
||||
|
||||
if (msg.nick)
|
||||
addChatMessage({
|
||||
"text": "/special " + sprintf(translate("%(nick)s changed the lobby subject to %(subject)s"), {
|
||||
"nick": msg.nick,
|
||||
"subject": msg.subject
|
||||
}),
|
||||
"time": msg.time,
|
||||
"isSpecial": true
|
||||
});
|
||||
return false;
|
||||
},
|
||||
"join": msg => {
|
||||
addChatMessage({
|
||||
"text": "/special " + sprintf(translate("%(nick)s has joined."), {
|
||||
"nick": msg.text
|
||||
"nick": msg.nick
|
||||
}),
|
||||
"time": msg.time,
|
||||
"isSpecial": true
|
||||
@ -166,13 +176,13 @@ var g_NetMessageTypes = {
|
||||
"leave": msg => {
|
||||
addChatMessage({
|
||||
"text": "/special " + sprintf(translate("%(nick)s has left."), {
|
||||
"nick": msg.text
|
||||
"nick": msg.nick
|
||||
}),
|
||||
"time": msg.time,
|
||||
"isSpecial": true
|
||||
});
|
||||
|
||||
if (msg.text == g_Username)
|
||||
if (msg.nick == g_Username)
|
||||
Engine.DisconnectXmppClient();
|
||||
|
||||
return true;
|
||||
@ -181,18 +191,18 @@ var g_NetMessageTypes = {
|
||||
"role": msg => {
|
||||
Engine.GetGUIObjectByName("chatInput").hidden = Engine.LobbyGetPlayerRole(g_Username) == "visitor";
|
||||
|
||||
let me = g_Username == msg.text;
|
||||
let role = Engine.LobbyGetPlayerRole(msg.text);
|
||||
let me = g_Username == msg.nick;
|
||||
let newrole = Engine.LobbyGetPlayerRole(msg.nick);
|
||||
let txt =
|
||||
role == "visitor" ?
|
||||
newrole == "visitor" ?
|
||||
me ?
|
||||
translate("You have been muted.") :
|
||||
translate("%(nick)s has been muted.") :
|
||||
role == "moderator" ?
|
||||
newrole == "moderator" ?
|
||||
me ?
|
||||
translate("You are now a moderator.") :
|
||||
translate("%(nick)s is now a moderator.") :
|
||||
msg.data == "visitor" ?
|
||||
msg.oldrole == "visitor" ?
|
||||
me ?
|
||||
translate("You have been unmuted.") :
|
||||
translate("%(nick)s has been unmuted.") :
|
||||
@ -201,12 +211,12 @@ var g_NetMessageTypes = {
|
||||
translate("%(nick)s is not a moderator anymore.");
|
||||
|
||||
addChatMessage({
|
||||
"text": "/special " + sprintf(txt, { "nick": msg.text }),
|
||||
"text": "/special " + sprintf(txt, { "nick": msg.nick }),
|
||||
"time": msg.time,
|
||||
"isSpecial": true
|
||||
});
|
||||
|
||||
if (g_SelectedPlayer == msg.text)
|
||||
if (g_SelectedPlayer == msg.nick)
|
||||
updateUserRoleText(g_SelectedPlayer);
|
||||
|
||||
return false;
|
||||
@ -214,8 +224,8 @@ var g_NetMessageTypes = {
|
||||
"nick": msg => {
|
||||
addChatMessage({
|
||||
"text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), {
|
||||
"oldnick": msg.text,
|
||||
"newnick": msg.data
|
||||
"oldnick": msg.oldnick,
|
||||
"newnick": msg.newnick
|
||||
}),
|
||||
"time": msg.time,
|
||||
"isSpecial": true
|
||||
@ -223,11 +233,11 @@ var g_NetMessageTypes = {
|
||||
return true;
|
||||
},
|
||||
"kicked": msg => {
|
||||
handleKick(false, msg.text, msg.data || "", msg.time);
|
||||
handleKick(false, msg.nick, msg.reason, msg.time);
|
||||
return true;
|
||||
},
|
||||
"banned": msg => {
|
||||
handleKick(true, msg.text, msg.data || "", msg.time);
|
||||
handleKick(true, msg.nick, msg.reason, msg.time);
|
||||
return true;
|
||||
},
|
||||
"room-message": msg => {
|
||||
@ -550,8 +560,6 @@ function handleKick(banned, nick, reason, time)
|
||||
|
||||
/**
|
||||
* Update the subject GUI object.
|
||||
*
|
||||
* @param {string} newSubject
|
||||
*/
|
||||
function updateSubject(newSubject)
|
||||
{
|
||||
|
@ -162,11 +162,18 @@ function onTick()
|
||||
|
||||
g_LobbyIsConnecting = false;
|
||||
|
||||
switch(message.level) {
|
||||
switch (message.level)
|
||||
{
|
||||
case "error":
|
||||
{
|
||||
Engine.GetGUIObjectByName("feedback").caption = message.text;
|
||||
g_DisplayingSystemMessage = true;
|
||||
Engine.StopXmppClient();
|
||||
break;
|
||||
}
|
||||
case "disconnected":
|
||||
{
|
||||
Engine.GetGUIObjectByName("feedback").caption = message.text ||
|
||||
Engine.GetGUIObjectByName("feedback").caption = message.reason ||
|
||||
translate("Unknown error. This usually occurs because the same IP address is not allowed to register more than one account within one hour.");
|
||||
g_DisplayingSystemMessage = true;
|
||||
Engine.StopXmppClient();
|
||||
|
@ -140,7 +140,6 @@ XmppClient::XmppClient(const std::string& sUsername, const std::string& sPasswor
|
||||
m_sessionManager = new glooxwrapper::SessionManager(m_client, this);
|
||||
// Register plugins to allow gloox parse them in incoming sessions
|
||||
m_sessionManager->registerPlugins();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +230,7 @@ void XmppClient::onDisconnect(gloox::ConnectionError error)
|
||||
m_PlayerMap.clear();
|
||||
m_Profile.clear();
|
||||
|
||||
CreateGUIMessage("system", "disconnected", ConnectionErrorToString(error));
|
||||
CreateGUIMessage("system", "disconnected", "reason", ConnectionErrorToString(error));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,7 +256,7 @@ bool XmppClient::onTLSConnect(const glooxwrapper::CertInfo& info)
|
||||
*/
|
||||
void XmppClient::handleMUCError(glooxwrapper::MUCRoom*, gloox::StanzaError err)
|
||||
{
|
||||
CreateGUIMessage("system", "error", StanzaErrorToString(err));
|
||||
CreateGUIMessage("system", "error", "text", StanzaErrorToString(err));
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
@ -425,7 +424,8 @@ void XmppClient::handleRegistrationResult(const glooxwrapper::JID&, gloox::Regis
|
||||
if (result == gloox::RegistrationSuccess)
|
||||
CreateGUIMessage("system", "registered");
|
||||
else
|
||||
CreateGUIMessage("system", "error", RegistrationResultToString(result));
|
||||
CreateGUIMessage("system", "error", "text", RegistrationResultToString(result));
|
||||
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@ -549,9 +549,26 @@ void XmppClient::GUIGetProfile(const ScriptInterface& scriptInterface, JS::Mutab
|
||||
* Message interfaces *
|
||||
*****************************************************/
|
||||
|
||||
/**
|
||||
* Send GUI message queue when queried.
|
||||
*/
|
||||
void XmppClient::CreateGUIMessage(
|
||||
const std::string& type,
|
||||
const std::string& level,
|
||||
const std::string& property1_name,
|
||||
const std::string& property1_value,
|
||||
const std::string& property2_name,
|
||||
const std::string& property2_value,
|
||||
const std::time_t time)
|
||||
{
|
||||
GUIMessage message;
|
||||
message.type = type;
|
||||
message.level = level;
|
||||
message.property1_name = property1_name;
|
||||
message.property1_value = property1_value;
|
||||
message.property2_name = property2_name;
|
||||
message.property2_value = property2_value;
|
||||
message.time = time;
|
||||
m_GuiMessageQueue.push_back(std::move(message));
|
||||
}
|
||||
|
||||
void XmppClient::GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret)
|
||||
{
|
||||
if (m_GuiMessageQueue.empty())
|
||||
@ -565,18 +582,14 @@ void XmppClient::GuiPollMessage(const ScriptInterface& scriptInterface, JS::Muta
|
||||
JSAutoRequest rq(cx);
|
||||
|
||||
scriptInterface.Eval("({})", ret);
|
||||
scriptInterface.SetProperty(ret, "type", message.type);
|
||||
if (!message.from.empty())
|
||||
scriptInterface.SetProperty(ret, "from", message.from);
|
||||
if (!message.text.empty())
|
||||
scriptInterface.SetProperty(ret, "text", message.text);
|
||||
scriptInterface.SetProperty(ret, "type", wstring_from_utf8(message.type));
|
||||
if (!message.level.empty())
|
||||
scriptInterface.SetProperty(ret, "level", message.level);
|
||||
if (!message.data.empty())
|
||||
scriptInterface.SetProperty(ret, "data", message.data);
|
||||
|
||||
scriptInterface.SetProperty(ret, "level", wstring_from_utf8(message.level));
|
||||
if (!message.property1_name.empty())
|
||||
scriptInterface.SetProperty(ret, message.property1_name.c_str(), wstring_from_utf8(message.property1_value));
|
||||
if (!message.property2_name.empty())
|
||||
scriptInterface.SetProperty(ret, message.property2_name.c_str(), wstring_from_utf8(message.property2_value));
|
||||
scriptInterface.SetProperty(ret, "time", (double)message.time);
|
||||
|
||||
m_GuiMessageQueue.pop_front();
|
||||
}
|
||||
|
||||
@ -588,16 +601,6 @@ void XmppClient::SendMUCMessage(const std::string& message)
|
||||
m_mucRoom->send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a message onto the GUI queue.
|
||||
*
|
||||
* @param message Message to add to the queue
|
||||
*/
|
||||
void XmppClient::PushGuiMessage(XmppClient::GUIMessage message)
|
||||
{
|
||||
m_GuiMessageQueue.push_back(std::move(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all presence updates from the message queue.
|
||||
* Used when rejoining the lobby, since we don't need to handle past presence changes.
|
||||
@ -608,7 +611,7 @@ void XmppClient::ClearPresenceUpdates()
|
||||
std::remove_if(m_GuiMessageQueue.begin(), m_GuiMessageQueue.end(),
|
||||
[](XmppClient::GUIMessage& message)
|
||||
{
|
||||
return message.type == L"chat" && message.level == L"presence";
|
||||
return message.type == "chat" && message.level == "presence";
|
||||
}
|
||||
), m_GuiMessageQueue.end());
|
||||
}
|
||||
@ -620,30 +623,28 @@ void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Me
|
||||
{
|
||||
DbgXMPP(msg.from().resource() << " said " << msg.body());
|
||||
|
||||
GUIMessage message;
|
||||
message.type = L"chat";
|
||||
message.level = priv ? L"private-message" : L"room-message";
|
||||
message.from = wstring_from_utf8(msg.from().resource().to_string());
|
||||
message.text = wstring_from_utf8(msg.body().to_string());
|
||||
message.time = ComputeTimestamp(msg);
|
||||
PushGuiMessage(message);
|
||||
CreateGUIMessage(
|
||||
"chat",
|
||||
priv ? "private-message" : "room-message",
|
||||
"from", msg.from().resource().to_string(),
|
||||
"text", msg.body().to_string(),
|
||||
ComputeTimestamp(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a private message.
|
||||
*/
|
||||
void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::MessageSession *)
|
||||
void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::MessageSession*)
|
||||
{
|
||||
DbgXMPP("type " << msg.subtype() << ", subject " << msg.subject()
|
||||
<< ", message " << msg.body() << ", thread id " << msg.thread());
|
||||
|
||||
GUIMessage message;
|
||||
message.type = L"chat";
|
||||
message.level = L"private-message";
|
||||
message.from = wstring_from_utf8(msg.from().username().to_string());
|
||||
message.text = wstring_from_utf8(msg.body().to_string());
|
||||
message.time = ComputeTimestamp(msg);
|
||||
PushGuiMessage(message);
|
||||
CreateGUIMessage(
|
||||
"chat",
|
||||
"private-message",
|
||||
"from", msg.from().resource().to_string(),
|
||||
"text", msg.body().to_string(),
|
||||
ComputeTimestamp(msg));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -707,38 +708,15 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
|
||||
}
|
||||
}
|
||||
else if (iq.subtype() == gloox::IQ::Error)
|
||||
{
|
||||
gloox::StanzaError err = iq.error_error();
|
||||
CreateGUIMessage("system", "error", StanzaErrorToString(err));
|
||||
}
|
||||
CreateGUIMessage("system", "error", "text", StanzaErrorToString(iq.error_error()));
|
||||
else
|
||||
{
|
||||
CreateGUIMessage("system", "error", g_L10n.Translate("unknown subtype (see logs)"));
|
||||
std::string tag = tag_name(iq);
|
||||
LOGMESSAGE("unknown subtype '%s'", tag.c_str());
|
||||
CreateGUIMessage("system", "error", "text", g_L10n.Translate("unknown subtype (see logs)"));
|
||||
LOGMESSAGE("unknown subtype '%s'", tag_name(iq).c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new detail message for the GUI.
|
||||
*
|
||||
* @param type General message type
|
||||
* @param level Detailed message type
|
||||
* @param text Body of the message
|
||||
* @param data Optional field, used for auxiliary data
|
||||
*/
|
||||
void XmppClient::CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text, const std::string& 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);
|
||||
message.time = std::time(nullptr);
|
||||
PushGuiMessage(message);
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
* Presence, nickname, and subject *
|
||||
*****************************************************/
|
||||
@ -763,25 +741,25 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
|
||||
m_PlayerMap[newNick].resize(3);
|
||||
m_PlayerMap[newNick][0] = presenceString;
|
||||
m_PlayerMap[newNick][2] = roleString;
|
||||
CreateGUIMessage("chat", "nick", nick, participant.newNick.to_string());
|
||||
|
||||
DbgXMPP(nick << " is now known as " << participant.newNick.to_string());
|
||||
CreateGUIMessage("chat", "nick", "oldnick", nick, "newnick", participant.newNick.to_string());
|
||||
}
|
||||
else if (participant.flags & gloox::UserKicked)
|
||||
{
|
||||
DbgXMPP(nick << " was kicked. Reason: " << participant.reason.to_string());
|
||||
CreateGUIMessage("chat", "kicked", nick, participant.reason.to_string());
|
||||
CreateGUIMessage("chat", "kicked", "nick", nick, "reason", participant.reason.to_string());
|
||||
}
|
||||
else if (participant.flags & gloox::UserBanned)
|
||||
{
|
||||
DbgXMPP(nick << " was banned. Reason: " << participant.reason.to_string());
|
||||
CreateGUIMessage("chat", "banned", nick, participant.reason.to_string());
|
||||
CreateGUIMessage("chat", "banned", "nick", nick, "reason", participant.reason.to_string());
|
||||
}
|
||||
else
|
||||
{
|
||||
DbgXMPP(nick << " left the room (flags " << participant.flags << ")");
|
||||
CreateGUIMessage("chat", "leave", nick);
|
||||
CreateGUIMessage("chat", "leave", "nick", nick);
|
||||
}
|
||||
|
||||
m_PlayerMap.erase(nick);
|
||||
}
|
||||
else
|
||||
@ -796,11 +774,11 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
|
||||
m_initialLoadComplete = true;
|
||||
}
|
||||
else if (m_PlayerMap.find(nick) == m_PlayerMap.end())
|
||||
CreateGUIMessage("chat", "join", nick);
|
||||
CreateGUIMessage("chat", "join", "nick", nick);
|
||||
else if (m_PlayerMap[nick][2] != roleString)
|
||||
CreateGUIMessage("chat", "role", nick, m_PlayerMap[nick][2]);
|
||||
CreateGUIMessage("chat", "role", "nick", nick, "oldrole", m_PlayerMap[nick][2]);
|
||||
else
|
||||
CreateGUIMessage("chat", "presence", nick);
|
||||
CreateGUIMessage("chat", "presence", "nick", nick);
|
||||
|
||||
DbgXMPP(nick << " is in the room, presence : " << (int)presenceType);
|
||||
m_PlayerMap[nick].resize(3);
|
||||
@ -812,10 +790,10 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
|
||||
/**
|
||||
* Update local cache when subject changes.
|
||||
*/
|
||||
void XmppClient::handleMUCSubject(glooxwrapper::MUCRoom*, const glooxwrapper::string& UNUSED(nick), const glooxwrapper::string& subject)
|
||||
void XmppClient::handleMUCSubject(glooxwrapper::MUCRoom*, const glooxwrapper::string& nick, const glooxwrapper::string& subject)
|
||||
{
|
||||
m_Subject = subject.c_str();
|
||||
CreateGUIMessage("chat", "subject", m_Subject);
|
||||
CreateGUIMessage("chat", "subject", "nick", nick.c_str(), "subject", m_Subject);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -135,20 +135,26 @@ public:
|
||||
/* Messages */
|
||||
struct GUIMessage
|
||||
{
|
||||
std::wstring type;
|
||||
std::wstring level;
|
||||
std::wstring text;
|
||||
std::wstring data;
|
||||
std::wstring from;
|
||||
std::wstring message;
|
||||
std::string type;
|
||||
std::string level;
|
||||
std::string property1_name;
|
||||
std::string property1_value;
|
||||
std::string property2_name;
|
||||
std::string property2_value;
|
||||
std::time_t time;
|
||||
};
|
||||
void GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
|
||||
void SendMUCMessage(const std::string& message);
|
||||
void ClearPresenceUpdates();
|
||||
protected:
|
||||
void PushGuiMessage(XmppClient::GUIMessage message);
|
||||
void CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text = "", const std::string& data = "");
|
||||
void CreateGUIMessage(
|
||||
const std::string& type,
|
||||
const std::string& level = "",
|
||||
const std::string& property1_name = "",
|
||||
const std::string& property1_value = "",
|
||||
const std::string& property2_name = "",
|
||||
const std::string& property2_value = "",
|
||||
const std::time_t time = std::time_t(nullptr));
|
||||
|
||||
private:
|
||||
/// Map of players
|
||||
|
Loading…
Reference in New Issue
Block a user