diff --git a/binaries/data/mods/public/gui/lobby/lobby.js b/binaries/data/mods/public/gui/lobby/lobby.js index d92d9ebdb8..735dcbf85d 100644 --- a/binaries/data/mods/public/gui/lobby/lobby.js +++ b/binaries/data/mods/public/gui/lobby/lobby.js @@ -116,20 +116,10 @@ var g_NetMessageTypes = { updateLeaderboard(); updatePlayerList(); Engine.GetGUIObjectByName("hostButton").enabled = false; - addChatMessage({ - "from": "system", - "text": translate("Disconnected.") + msg.text, - "color": g_SystemColor, - "time": msg.time - }); + addChatMessage({ "from": "system", "text": translate("Disconnected.") + msg.text, "color": g_SystemColor }); }, "error": msg => { - addChatMessage({ - "from": "system", - "text": msg.text, - "color": g_SystemColor, - "time": msg.time - }); + addChatMessage({ "from": "system", "text": msg.text, "color": g_SystemColor }); } }, "chat": { @@ -139,16 +129,14 @@ var g_NetMessageTypes = { "join": msg => { addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { "nick": msg.text }), - "isSpecial": true, - "time": msg.time + "isSpecial": true }); Engine.SendGetRatingList(); }, "leave": msg => { addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has left."), { "nick": msg.text }), - "isSpecial": true, - "time": msg.time + "isSpecial": true }); }, "presence": msg => { @@ -159,15 +147,14 @@ var g_NetMessageTypes = { "oldnick": msg.text, "newnick": msg.data }), - "isSpecial": true, - "time": msg.time + "isSpecial": true }); }, "room-message": msg => { addChatMessage({ "from": escapeText(msg.from), "text": escapeText(msg.text), - "time": msg.time + "datetime": msg.datetime }); }, "private-message": msg => { @@ -175,7 +162,7 @@ var g_NetMessageTypes = { addChatMessage({ "from": "(Private) " + escapeText(msg.from), // TODO: placeholder "text": escapeText(msg.text.trim()), // some XMPP clients send trailing whitespace - "time": msg.time + "datetime": msg.datetime }); } }, @@ -676,8 +663,7 @@ 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; } @@ -788,8 +774,7 @@ function handleSpecialCommand(text) default: addChatMessage({ "from": "system", - "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { "cmd": cmd }), - "time": Date.now() / 1000 + "text": sprintf(translate("We're sorry, the '%(cmd)s' command is not supported."), { "cmd": cmd }) }); } return true; @@ -811,10 +796,13 @@ function addChatMessage(msg) if (g_Username != msg.from) msg.text = msg.text.replace(g_Username, colorPlayerName(g_Username)); - updateSpamMonitor(msg); - - if (isSpam(msg.text, msg.from)) - return; + // Run spam test if it's not a historical message + if (!msg.datetime) + { + updateSpamMonitor(msg.from); + if (isSpam(msg.text, msg.from)) + return; + } } var formatted = ircFormat(msg); @@ -896,13 +884,23 @@ function ircFormat(msg) if (!g_ShowTimestamp) return formattedMessage; - // Convert from UTC to localtime - var time = msg.time - new Date().getTimezoneOffset() * 60; + var time; + if (msg.datetime) + { + let dTime = msg.datetime.split("T"); + let parserDate = dTime[0].split("-"); + let parserTime = dTime[1].split(":"); + // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format of datetime + // Date takes Year, Month, Day, Hour, Minute, Second + time = new Date(Date.UTC(parserDate[0], parserDate[1], parserDate[2], parserTime[0], parserTime[1], parserTime[2].split("Z")[0])); + } + else + time = new Date(Date.now()); // Translation: Time as shown in the multiplayer lobby (when you enable it in the options page). // For a list of symbols that you can use, see: // https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table - var timeString = Engine.FormatMillisecondsIntoDateString(time * 1000, translate("HH:mm")); + var timeString = Engine.FormatMillisecondsIntoDateString(time.getTime(), translate("HH:mm")); // Translation: Time prefix as shown in the multiplayer lobby (when you enable it in the options page). var timePrefixString = '[font="' + g_SenderFont + '"]' + sprintf(translate("\\[%(time)s]"), { "time": timeString }) + '[/font]'; @@ -914,18 +912,14 @@ function ircFormat(msg) /** * Update the spam monitor. * - * @param {Object} msg - Message containing user to update. + * @param {string} from - User to update. */ -function updateSpamMonitor(msg) +function updateSpamMonitor(from) { - // Ignore historical messages - if (msg.time < Date.now() / 1000 - g_SpamBlockDuration) - return; - - if (g_SpamMonitor[msg.from]) - ++g_SpamMonitor[msg.from].count; + if (g_SpamMonitor[from]) + ++g_SpamMonitor[from].count; else - g_SpamMonitor[msg.from] = { + g_SpamMonitor[from] = { "count": 1, "lastSend": Math.floor(Date.now() / 1000), "lastBlock": 0 @@ -967,11 +961,7 @@ function isSpam(text, from) g_SpamMonitor[from].lastBlock = time; if (from == g_Username) - addChatMessage({ - "from": "system", - "text": translate("Please do not spam. You have been blocked for thirty seconds."), - "time": Date.now() / 1000 - }); + addChatMessage({ "from": "system", "text": translate("Please do not spam. You have been blocked for thirty seconds.") }); return true; } diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index 31e8674f10..f030040342 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -592,7 +592,8 @@ void XmppClient::GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHan scriptInterface.SetProperty(ret, "level", message.level); if (!message.data.empty()) scriptInterface.SetProperty(ret, "data", message.data); - scriptInterface.SetProperty(ret, "time", message.time); + if (!message.datetime.empty()) + scriptInterface.SetProperty(ret, "datetime", message.datetime); m_GuiMessageQueue.pop_front(); } @@ -654,7 +655,9 @@ 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()); - message.time = ComputeTimestamp(msg); + if (msg.when()) + // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format + message.datetime = msg.when()->stamp().to_string(); PushGuiMessage(message); } @@ -671,7 +674,9 @@ 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()); - message.time = ComputeTimestamp(msg); + if (msg.when()) + //See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format + message.datetime = msg.when()->stamp().to_string(); PushGuiMessage(message); } @@ -764,7 +769,6 @@ 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); } @@ -934,28 +938,6 @@ 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", ×tamp); - if (res == NULL) - LOGERROR("Recived delayed message with corrupted timestamp %s", timestampStr.to_string()); - - return mktime(×tamp) - timezone; -} - /** * Convert a gloox presence type to string. * diff --git a/source/lobby/XmppClient.h b/source/lobby/XmppClient.h index 0094467498..7712a2cd57 100644 --- a/source/lobby/XmppClient.h +++ b/source/lobby/XmppClient.h @@ -127,7 +127,6 @@ 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 */ @@ -139,7 +138,7 @@ public: std::wstring data; std::wstring from; std::wstring message; - time_t time; + std::string datetime; }; void GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHandleValue ret); void SendMUCMessage(const std::string& message);