1
1
forked from 0ad/0ad

Add timestamps to the GUI/chat-notifications sent from XmppClient, even if it's not a historical message.

Correct spammonitor behavior for historical messages and when returning
to the lobby from a game.
Patch by Josh, fixes #3832.

This was SVN commit r17928.
This commit is contained in:
elexis 2016-03-21 13:48:22 +00:00
parent 86a309ad76
commit 1f34a004e5
3 changed files with 71 additions and 32 deletions

View File

@ -111,10 +111,20 @@ var g_NetMessageTypes = {
updateLeaderboard();
updatePlayerList();
Engine.GetGUIObjectByName("hostButton").enabled = false;
addChatMessage({ "from": "system", "text": translate("Disconnected.") + msg.text, "color": g_SystemColor });
addChatMessage({
"from": "system",
"text": translate("Disconnected.") + msg.text,
"color": g_SystemColor,
"time": msg.time
});
},
"error": msg => {
addChatMessage({ "from": "system", "text": msg.text, "color": g_SystemColor });
addChatMessage({
"from": "system",
"text": msg.text,
"color": g_SystemColor,
"time": msg.time
});
}
},
"chat": {
@ -124,14 +134,16 @@ var g_NetMessageTypes = {
"join": msg => {
addChatMessage({
"text": "/special " + sprintf(translate("%(nick)s has joined."), { "nick": msg.text }),
"isSpecial": true
"isSpecial": true,
"time": msg.time
});
Engine.SendGetRatingList();
},
"leave": msg => {
addChatMessage({
"text": "/special " + sprintf(translate("%(nick)s has left."), { "nick": msg.text }),
"isSpecial": true
"isSpecial": true,
"time": msg.time
});
},
"presence": msg => {
@ -142,14 +154,15 @@ var g_NetMessageTypes = {
"oldnick": msg.text,
"newnick": msg.data
}),
"isSpecial": true
"isSpecial": true,
"time": msg.time
});
},
"room-message": msg => {
addChatMessage({
"from": escapeText(msg.from),
"text": escapeText(msg.text),
"datetime": msg.datetime
"time": msg.time
});
},
"private-message": msg => {
@ -157,7 +170,7 @@ var g_NetMessageTypes = {
addChatMessage({
"from": "(Private) " + escapeText(msg.from), // TODO: placeholder
"text": escapeText(msg.text.trim()), // some XMPP clients send trailing whitespace
"datetime": msg.datetime
"time": msg.time
});
}
},
@ -658,7 +671,8 @@ function joinSelectedGame()
"text": sprintf(
translate("This game's address '%(ip)s' does not appear to be valid."),
{ "ip": game.ip }
)
),
"time": Date.now() / 1000
});
return;
}
@ -769,7 +783,8 @@ function handleSpecialCommand(text)
default:
addChatMessage({
"from": "system",
"text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { "cmd": cmd })
"text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { "cmd": cmd }),
"time": Date.now() / 1000
});
}
return true;
@ -791,13 +806,10 @@ function addChatMessage(msg)
if (g_Username != msg.from)
msg.text = msg.text.replace(g_Username, colorPlayerName(g_Username));
// Run spam test if it's not a historical message
if (!msg.datetime)
{
updateSpamMonitor(msg.from);
if (isSpam(msg.text, msg.from))
return;
}
updateSpamMonitor(msg);
if (isSpam(msg.text, msg.from))
return;
}
var formatted = ircFormat(msg);
@ -907,14 +919,18 @@ function ircFormat(msg)
/**
* Update the spam monitor.
*
* @param {string} from - User to update.
* @param {Object} msg - Message containing user to update.
*/
function updateSpamMonitor(from)
function updateSpamMonitor(msg)
{
if (g_SpamMonitor[from])
++g_SpamMonitor[from][0];
// Ignore historical messages
if (msg.time < Date.now() / 1000 - g_SpamBlockDuration)
return;
if (g_SpamMonitor[msg.from])
++g_SpamMonitor[msg.from][0];
else
g_SpamMonitor[from] = [1, Math.floor(Date.now() / 1000), 0];
g_SpamMonitor[msg.from] = [1, Math.floor(Date.now() / 1000), 0];
}
/**
@ -947,7 +963,11 @@ function isSpam(text, from)
{
g_SpamMonitor[from][2] = time;
if (from == g_Username)
addChatMessage({ "from": "system", "text": translate("Please do not spam. You have been blocked for thirty seconds.") });
addChatMessage({
"from": "system",
"text": translate("Please do not spam. You have been blocked for thirty seconds."),
"time": Date.now() / 1000
});
return true;
}

View File

@ -592,8 +592,7 @@ void XmppClient::GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHan
scriptInterface.SetProperty(ret, "level", message.level);
if (!message.data.empty())
scriptInterface.SetProperty(ret, "data", message.data);
if (!message.datetime.empty())
scriptInterface.SetProperty(ret, "datetime", message.datetime);
scriptInterface.SetProperty(ret, "time", message.time);
m_GuiMessageQueue.pop_front();
}
@ -655,9 +654,7 @@ void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Me
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())
// See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format
message.datetime = msg.when()->stamp().to_string();
message.time = ComputeTimestamp(msg);
PushGuiMessage(message);
}
@ -674,9 +671,7 @@ void XmppClient::handleMessage(const glooxwrapper::Message& msg, glooxwrapper::M
message.level = L"private-message";
message.from = wstring_from_utf8(msg.from().username().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();
message.time = ComputeTimestamp(msg);
PushGuiMessage(message);
}
@ -769,6 +764,7 @@ void XmppClient::CreateGUIMessage(const std::string& type, const std::string& le
message.level = wstring_from_utf8(level);
message.text = wstring_from_utf8(text);
message.data = wstring_from_utf8(data);
message.time = time(NULL);
PushGuiMessage(message);
}
@ -938,6 +934,28 @@ void XmppClient::GetRole(const std::string& nick, std::string& role)
* Utilities *
*****************************************************/
/**
* Compute the POSIX timestamp of a message. Uses message datetime when possible, current time otherwise.
*
* @param msg The message on which to base the computation
* @returns POSIX GMT/UTC seconds since Jan. 1st 1970
*/
time_t XmppClient::ComputeTimestamp(const glooxwrapper::Message& msg)
{
if (!msg.when())
return time(NULL);
glooxwrapper::string timestampStr = msg.when()->stamp();
struct tm timestamp = {0};
// See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format
void * res = strptime(timestampStr.c_str(), "%Y-%m-%dT%H:%M:%SZ", &timestamp);
if (res == NULL)
LOGERROR("Recived delayed message with corrupted timestamp %s", timestampStr.to_string());
return mktime(&timestamp) - timezone;
}
/**
* Convert a gloox presence type to string.
*

View File

@ -127,6 +127,7 @@ protected:
std::string StanzaErrorToString(gloox::StanzaError err) const;
std::string ConnectionErrorToString(gloox::ConnectionError err) const;
std::string RegistrationResultToString(gloox::RegistrationResult res) const;
time_t ComputeTimestamp(const glooxwrapper::Message& msg);
public:
/* Messages */
@ -138,13 +139,13 @@ public:
std::wstring data;
std::wstring from;
std::wstring message;
std::string datetime;
time_t time;
};
void GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
void SendMUCMessage(const std::string& message);
void ClearPresenceUpdates();
int GetMucMessageCount();
protected:
protected:
void PushGuiMessage(XmppClient::GUIMessage message);
void CreateGUIMessage(const std::string& type, const std::string& level, const std::string& text = "", const std::string& data = "");