1
0
forked from 0ad/0ad

Major lobby cleanup.

Create an object holding the handling of all netmessage types.
Display private messages sent by moderators.

Details:
 Switch back the second and third argument of CreateSimpleMessage, so it
relates again to the switch/object.
 Reduce the dimension/nesting of the object/switch from three to two.
 Hence remove the useless "standard" and "internal" value send in the
text field.
 Rename CreateSimpleMessage to CreateGUIMessage
 Use the property "level" instead of "text" for "connect" and
"disconnect".
 Remove the handling of the "connect" event in lobby.js, since it is
never called.
 Translate the disconnect event.
 Add comments and explicit checks to handleMessage and handleMUCMessage
to make obvious where they differ.
 Remove the "message" property from those GUI messages, since it should
just use "text".
 Move the login-fail handling to JS.
 Remove useless sprintf calls from warning messages.
 Inline some variables.
 Add missing semicolons.

This was SVN commit r17581.
This commit is contained in:
elexis 2015-12-31 17:08:23 +00:00
parent 2bf194134b
commit ccb534259d
4 changed files with 167 additions and 153 deletions

View File

@ -35,7 +35,7 @@ const g_GameColors = {
"init": "0 219 0",
"waiting": "255 127 0",
"running": "219 0 0"
}
};
/**
* The playerlist will be assembled using these values.
@ -91,6 +91,81 @@ var g_SelectedPlayer = "";
*/
var g_SelectedGameIP = "";
/**
* Notifications sent by XmppClient.cpp
*/
var g_NetMessageTypes = {
"system": {
// Three cases are handled in prelobby.js
"registered": msg => {
},
"login-failed": msg => {
},
"connected": msg => {
},
"disconnected": msg => {
updateGameList();
updateLeaderboard();
updatePlayerList();
Engine.GetGUIObjectByName("hostButton").enabled = false;
addChatMessage({ "from": "system", "text": translate("Disconnected."), "color": g_SystemColor });
},
"error": msg => {
addChatMessage({ "from": "system", "text": escapeText(msg.text), "color": g_SystemColor });
}
},
"chat": {
"subject": msg => {
updateSubject(msg.text);
},
"join": msg => {
addChatMessage({
"text": "/special " + sprintf(translate("%(nick)s has joined."), { "nick": msg.text }),
"isSpecial": true
});
Engine.SendGetRatingList();
},
"leave": msg => {
addChatMessage({
"text": "/special " + sprintf(translate("%(nick)s has left."), { "nick": msg.text }),
"isSpecial": true
});
},
"presence": msg => {
},
"nick": msg => {
addChatMessage({
"text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), {
"oldnick": msg.text,
"newnick": msg.data
}),
"isSpecial": true
});
},
"room-message": msg => {
addChatMessage({
"from": escapeText(msg.from),
"text": escapeText(msg.text),
"datetime": msg.datetime
});
},
"private-message": msg => {
if (Engine.LobbyGetPlayerRole(msg.from) == "moderator")
addChatMessage({
"from": "(Private) " + escapeText(msg.from), // TODO: placeholder
"text": escapeText(msg.text.trim()), // some XMPP clients send trailing whitespace
"datetime": msg.datetime
});
}
},
"game": {
"gamelist": msg => updateGameList(),
"profile": msg => updateProfile(),
"leaderboard": msg => updateLeaderboard(),
"ratinglist": msg => updatePlayerList()
}
};
/**
* Called after the XmppConnection succeeded and when returning from a game.
*
@ -276,7 +351,7 @@ function updatePlayerList()
playersBox.list_status = presenceList;
playersBox.list_rating = ratingList;
playersBox.list = nickList;
playersBox.selected = playersBox.list.indexOf(g_SelectedPlayer)
playersBox.selected = playersBox.list.indexOf(g_SelectedPlayer);
}
/**
@ -566,80 +641,25 @@ function onTick()
while (true)
{
var message = Engine.LobbyGuiPollMessage();
if (!message)
let msg = Engine.LobbyGuiPollMessage();
if (!msg)
break;
switch (message.type)
if (!g_NetMessageTypes[msg.type])
{
case "mucmessage":
addChatMessage({ "from": escapeText(message.from), "text": escapeText(message.text), "datetime": message.datetime});
break;
case "muc":
switch(message.level)
{
case "join":
addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { "nick": message.text }), "isSpecial": true });
Engine.SendGetRatingList();
break;
case "leave":
addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has left."), { "nick": message.text }), "isSpecial": true });
break;
case "nick":
addChatMessage({ "text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), { "oldnick": message.text, "newnick": message.data }), "isSpecial": true });
break;
case "presence":
break;
case "subject":
updateSubject(message.text);
break;
default:
warn(sprintf("Unknown message.level '%(msglvl)s'", { "msglvl": message.level }));
break;
}
// To improve performance, only update the playerlist GUI when the last update in the current stack is processed
if (Engine.LobbyGetMucMessageCount() == 0)
updatePlayerList();
break;
case "system":
switch (message.level)
{
case "standard":
addChatMessage({ "from": "system", "text": escapeText(message.text), "color": g_SystemColor });
if (message.text == "disconnected")
{
updateGameList();
updateLeaderboard();
updatePlayerList();
Engine.GetGUIObjectByName("hostButton").enabled = false;
}
else if (message.text == "connected")
Engine.GetGUIObjectByName("hostButton").enabled = true;
break;
case "error":
addChatMessage({ "from": "system", "text": escapeText(message.text), "color": g_SystemColor });
break;
case "internal":
switch (message.text)
{
case "gamelist updated":
updateGameList();
break;
case "boardlist updated":
updateLeaderboard();
break;
case "ratinglist updated":
updatePlayerList();
break;
case "profile updated":
updateProfile();
break;
}
break;
}
break;
default:
error(sprintf("Unrecognised message type %(msgtype)s", { "msgtype": message.type }));
warn("Unrecognised message type: " + msg.type);
continue;
}
if (!g_NetMessageTypes[msg.type][msg.level])
{
warn("Unrecognised message level: " + msg.level);
continue;
}
g_NetMessageTypes[msg.type][msg.level](msg);
// To improve performance, only update the playerlist GUI when the last update in the current stack is processed
if (msg.type == "chat" && Engine.LobbyGetMucMessageCount() == 0)
updatePlayerList();
}
}
@ -888,7 +908,7 @@ function isSpam(text, from)
*/
function checkSpamMonitor()
{
var time = Math.floor(Date.now() / 1000)
var time = Math.floor(Date.now() / 1000);
for (let i in g_SpamMonitor)
{
let stats = g_SpamMonitor[i];

View File

@ -5,6 +5,39 @@ var g_TermsOfServiceRead = false;
var g_TermsOfUseRead = false;
var g_HasSystemMessage = false;
/**
* Notifications sent by XmppClient.cpp
* Other types are handled in lobby.js
*/
var g_SystemMessageTypes = {
"error": (message, username, password) => {
Engine.GetGUIObjectByName("feedback").caption = message.text;
Engine.StopXmppClient();
},
"login-failed": (message, username, password) => {
Engine.GetGUIObjectByName("feedback").caption = translate("Authentication failed");
Engine.StopXmppClient();
},
"registered": (message, username, password) => {
Engine.GetGUIObjectByName("feedback").caption = translate("Registered");
Engine.GetGUIObjectByName("connectUsername").caption = username;
Engine.GetGUIObjectByName("connectPassword").caption = password;
Engine.StopXmppClient();
switchPage("connect");
},
"connected": (message, username, password) => {
Engine.PopGuiPage();
Engine.SwitchGuiPage("page_lobby.xml");
Engine.ConfigDB_CreateValue("user", "playername", sanitizePlayerName(username, true, true));
Engine.ConfigDB_CreateValue("user", "lobby.login", username);
if (password != g_EncrytedPassword.substring(0, 10))
g_EncrytedPassword = Engine.EncryptPassword(password, username);
Engine.ConfigDB_CreateValue("user", "lobby.password", g_EncrytedPassword);
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
}
};
function init()
{
g_EncrytedPassword = Engine.ConfigDB_GetValue("user", "lobby.password");
@ -69,21 +102,13 @@ function lobbyStartRegister()
function onTick()
{
var pageRegisterHidden = Engine.GetGUIObjectByName("pageRegister").hidden;
if (pageRegisterHidden)
{
var username = Engine.GetGUIObjectByName("connectUsername").caption;
var password = Engine.GetGUIObjectByName("connectPassword").caption;
}
else
{
var username = Engine.GetGUIObjectByName("registerUsername").caption;
var password = Engine.GetGUIObjectByName("registerPassword").caption;
}
var username = Engine.GetGUIObjectByName(pageRegisterHidden ? "connectUsername" : "registerUsername").caption;
var password = Engine.GetGUIObjectByName(pageRegisterHidden ? "connectPassword" : "registerPassword").caption;
var passwordAgain = Engine.GetGUIObjectByName("registerPasswordAgain").caption;
var agreeTerms = Engine.GetGUIObjectByName("registerAgreeTerms");
var feedback = Engine.GetGUIObjectByName("feedback");
var continueButton = Engine.GetGUIObjectByName("continue");
var sanitizedName = sanitizePlayerName(username, true, true);
// Do not change feedback while connecting.
if (g_LobbyIsConnecting) {}
@ -99,7 +124,7 @@ function onTick()
feedback.caption = translate("Please enter your username");
}
// Check that they are using a valid username.
else if (username != sanitizedName)
else if (username != sanitizePlayerName(username, true, true))
{
continueButton.enabled = false;
feedback.caption = translate("Usernames can't contain \\[, ], unicode, whitespace, or commas");
@ -161,49 +186,20 @@ function onTick()
// The XmppClient has been created, we are waiting
// to be connected or to receive an error.
//Receive messages
while (true)
{
var message = Engine.LobbyGuiPollMessage();
let message = Engine.LobbyGuiPollMessage();
if (!message)
break;
if (message.type == "system" && message.text == "connected")
{
// We are connected, switch to the lobby page
Engine.PopGuiPage();
// Use username as nick.
var nick = sanitizePlayerName(username, true, true);
if (message.type != "system")
continue;
// Switch to lobby
Engine.SwitchGuiPage("page_lobby.xml");
// Store nick, login, and password
Engine.ConfigDB_CreateValue("user", "playername", nick);
Engine.ConfigDB_CreateValue("user", "lobby.login", username);
// We only store the encrypted password, so make sure to re-encrypt it if changed before saving.
if (password != g_EncrytedPassword.substring(0, 10))
g_EncrytedPassword = Engine.EncryptPassword(password, username);
Engine.ConfigDB_CreateValue("user", "lobby.password", g_EncrytedPassword);
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
}
else if (message.type == "system" && message.text == "registered")
{
// Great, we are registered. Switch to the connection window.
feedback.caption = translate("Registered");
Engine.StopXmppClient();
g_LobbyIsConnecting = false;
Engine.GetGUIObjectByName("connectUsername").caption = username;
Engine.GetGUIObjectByName("connectPassword").caption = password;
switchPage("connect");
}
else if(message.type == "system" && (message.level == "error" || message.text == "disconnected"))
{
g_HasSystemMessage = true;
feedback.caption = message.text == "disconnected" ? translate("Disconnected") : message.text;
Engine.StopXmppClient();
g_LobbyIsConnecting = false;
}
g_HasSystemMessage = true;
g_LobbyIsConnecting = false;
if (g_SystemMessageTypes[message.level])
g_SystemMessageTypes[message.level](message, username, password);
}
}

View File

@ -189,7 +189,7 @@ void XmppClient::onConnect()
{
if (m_mucRoom)
{
CreateSimpleMessage("system", "connected");
CreateGUIMessage("system", "connected");
m_mucRoom->join();
}
@ -220,9 +220,9 @@ void XmppClient::onDisconnect(gloox::ConnectionError error)
m_Profile.clear();
if (error == gloox::ConnAuthenticationFailed)
CreateSimpleMessage("system", g_L10n.Translate("Authentication failed"), "error");
CreateGUIMessage("system", "login-failed");
else
CreateSimpleMessage("system", "disconnected");
CreateGUIMessage("system", "disconnected");
}
/**
@ -249,7 +249,7 @@ bool XmppClient::onTLSConnect(const glooxwrapper::CertInfo& info)
void XmppClient::handleMUCError(glooxwrapper::MUCRoom*, gloox::StanzaError err)
{
std::string msg = StanzaErrorToString(err);
CreateSimpleMessage("system", msg, "error");
CreateGUIMessage("system", "error", msg);
}
/*****************************************************
@ -445,9 +445,7 @@ void XmppClient::handleRegistrationFields(const glooxwrapper::JID&, int fields,
void XmppClient::handleRegistrationResult(const glooxwrapper::JID&, gloox::RegistrationResult result)
{
if (result == gloox::RegistrationSuccess)
{
CreateSimpleMessage("system", "registered");
}
CreateGUIMessage("system", "registered");
else
{
std::string msg;
@ -465,7 +463,7 @@ void XmppClient::handleRegistrationResult(const glooxwrapper::JID&, gloox::Regis
default: msg = g_L10n.Translate("Registration unknown error");
}
#undef CASE
CreateSimpleMessage("system", msg, "error");
CreateGUIMessage("system", "error", msg);
}
disconnect();
}
@ -613,8 +611,6 @@ void XmppClient::GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHan
scriptInterface.SetProperty(ret, "text", message.text);
if (!message.level.empty())
scriptInterface.SetProperty(ret, "level", message.level);
if (!message.message.empty())
scriptInterface.SetProperty(ret, "message", message.message);
if (!message.data.empty())
scriptInterface.SetProperty(ret, "data", message.data);
if (!message.datetime.empty())
@ -651,7 +647,7 @@ void XmppClient::ClearPresenceUpdates()
std::remove_if(m_GuiMessageQueue.begin(), m_GuiMessageQueue.end(),
[](XmppClient::GUIMessage& message)
{
return message.type == L"muc" && message.level == L"presence";
return message.type == L"chat" && message.level == L"presence";
}
), m_GuiMessageQueue.end());
}
@ -664,19 +660,20 @@ int XmppClient::GetMucMessageCount()
return std::count_if(m_GuiMessageQueue.begin(), m_GuiMessageQueue.end(),
[](XmppClient::GUIMessage& message)
{
return message.type == L"muc";
return message.type == L"chat";
});
}
/**
* Handle a standard MUC textual message.
* Handle a room message.
*/
void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Message& msg, bool)
{
DbgXMPP(msg.from().resource() << " said " << msg.body());
GUIMessage message;
message.type = L"mucmessage";
message.type = L"chat";
message.level = L"room-message";
message.from = wstring_from_utf8(msg.from().resource().to_string());
message.text = wstring_from_utf8(msg.body().to_string());
if (msg.when())
@ -686,7 +683,7 @@ void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Me
}
/**
* Handle a standard textual message.
* Handle a private message.
*/
void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::MessageSession *)
{
@ -694,8 +691,10 @@ void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::M
<< ", 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.message = wstring_from_utf8(msg.body().to_string());
message.text = wstring_from_utf8(msg.body().to_string());
if (msg.when())
//See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format
message.datetime = msg.when()->stamp().to_string();
@ -723,7 +722,7 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
for (const glooxwrapper::Tag* const& t : gq->m_GameList)
m_GameList.emplace_back(t->clone());
CreateSimpleMessage("system", "gamelist updated", "internal");
CreateGUIMessage("game", "gamelist");
}
if (bq)
{
@ -736,7 +735,7 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
for (const glooxwrapper::Tag* const& t : bq->m_StanzaBoardList)
m_BoardList.emplace_back(t->clone());
CreateSimpleMessage("system", "boardlist updated", "internal");
CreateGUIMessage("game", "leaderboard");
}
else if (bq->m_Command == "ratinglist")
{
@ -747,7 +746,7 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
m_PlayerMap[name][1] = t->findAttribute("rating").to_string();
}
CreateSimpleMessage("system", "ratinglist updated", "internal");
CreateGUIMessage("game", "ratinglist");
}
}
if (pq)
@ -759,22 +758,21 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
for (const glooxwrapper::Tag* const& t : pq->m_StanzaProfile)
m_Profile.emplace_back(t->clone());
CreateSimpleMessage("system", "profile updated", "internal");
CreateGUIMessage("game", "profile");
}
}
else if (iq.subtype() == gloox::IQ::Error)
{
gloox::StanzaError err = iq.error_error();
std::string msg = StanzaErrorToString(err);
CreateSimpleMessage("system", msg, "error");
CreateGUIMessage("system", "error", msg);
}
else
{
CreateSimpleMessage("system", g_L10n.Translate("unknown subtype (see logs)"), "error");
CreateGUIMessage("system", "error", g_L10n.Translate("unknown subtype (see logs)"));
std::string tag = tag_name(iq);
LOGMESSAGE("unknown subtype '%s'", tag.c_str());
}
return true;
}
@ -786,7 +784,7 @@ bool XmppClient::handleIq(const glooxwrapper::IQ& iq)
* @param text Body of the message
* @param data Optional field, used for auxiliary data
*/
void XmppClient::CreateSimpleMessage(const std::string& type, const std::string& text, const std::string& level, const std::string& 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);
@ -820,10 +818,10 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
m_PlayerMap[newNick].resize(3);
m_PlayerMap[newNick][0] = presenceString;
m_PlayerMap[newNick][2] = roleString;
CreateSimpleMessage("muc", nick, "nick", participant.newNick.to_string());
CreateGUIMessage("chat", "nick", nick, participant.newNick.to_string());
}
else
CreateSimpleMessage("muc", nick, "leave");
CreateGUIMessage("chat", "leave", nick);
DbgXMPP(nick << " left the room");
m_PlayerMap.erase(nick);
@ -840,9 +838,9 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
m_initialLoadComplete = true;
}
else if (m_PlayerMap.find(nick) == m_PlayerMap.end())
CreateSimpleMessage("muc", nick, "join");
CreateGUIMessage("chat", "join", nick);
else
CreateSimpleMessage("muc", nick, "presence");
CreateGUIMessage("chat", "presence", nick);
DbgXMPP(nick << " is in the room, presence : " << (int)presenceType);
m_PlayerMap[nick].resize(3);
@ -857,7 +855,7 @@ void XmppClient::handleMUCParticipantPresence(glooxwrapper::MUCRoom*, const gloo
void XmppClient::handleMUCSubject(glooxwrapper::MUCRoom*, const glooxwrapper::string& UNUSED(nick), const glooxwrapper::string& subject)
{
m_Subject = subject.c_str();
CreateSimpleMessage("muc", m_Subject, "subject");
CreateGUIMessage("chat", "subject", m_Subject);
}
/**

View File

@ -144,7 +144,7 @@ public:
int GetMucMessageCount();
protected:
void PushGuiMessage(XmppClient::GUIMessage message);
void CreateSimpleMessage(const std::string& type, const std::string& text, const std::string& level = "standard", const std::string& data = "");
void CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text = "", const std::string& data = "");
private:
/// Map of players