Ticket #3156: fixhistory-spam-timestamps-and-initialjoins.diff

File fixhistory-spam-timestamps-and-initialjoins.diff, 7.9 KB (added by Josh, 9 years ago)

Disable the spam monitor while parsing historical data, fix timestamps on historical messages, and fix superfluous initial join messages.

  • source/lobby/XmppClient.cpp

     
    615615        scriptInterface.SetProperty(ret, "message", message.message);
    616616    if (!message.data.empty())
    617617        scriptInterface.SetProperty(ret, "data", message.data);
    618    
     618    if (!message.datetime.empty())
     619        scriptInterface.SetProperty(ret, "datetime", message.datetime);
     620
    619621    m_GuiMessageQueue.pop_front();
    620622}
    621623
     
    648650    message.type = L"mucmessage";
    649651    message.from = wstring_from_utf8(msg.from().resource().to_string());
    650652    message.text = wstring_from_utf8(msg.body().to_string());
     653    if (msg.when())
     654        // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format
     655        message.datetime = msg.when()->stamp().to_string();
    651656    PushGuiMessage(message);
    652657}
    653658
     
    662667    GUIMessage message;
    663668    message.from = wstring_from_utf8(msg.from().username().to_string());
    664669    message.message = wstring_from_utf8(msg.body().to_string());
     670    if (msg.when())
     671        //See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format
     672        message.datetime = msg.when()->stamp().to_string();
    665673    PushGuiMessage(message);
    666674}
    667675
  • source/lobby/XmppClient.h

     
    131131        std::wstring data;
    132132        std::wstring from;
    133133        std::wstring message;
     134        std::string datetime;
    134135    };
    135136    void GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
    136137    void SendMUCMessage(const std::string& message);
  • source/lobby/glooxwrapper/glooxwrapper.cpp

     
    383383}
    384384
    385385
     386glooxwrapper::DelayedDelivery::DelayedDelivery(const gloox::DelayedDelivery* wrapped)
     387{
     388    m_Wrapped = wrapped;
     389}
     390
     391const glooxwrapper::string glooxwrapper::DelayedDelivery::stamp() const
     392{
     393    return m_Wrapped->stamp();
     394}
     395
     396
    386397glooxwrapper::Disco::Disco(gloox::Disco* wrapped)
    387398{
    388399    m_Wrapped = wrapped;
     
    513524    return m_Wrapped->thread();
    514525}
    515526
     527const glooxwrapper::DelayedDelivery* glooxwrapper::Message::when() const
     528{
     529    const gloox::DelayedDelivery* wrapped = m_Wrapped->when();
     530    if (wrapped == 0)
     531        return 0;
     532    return new glooxwrapper::DelayedDelivery(wrapped);
     533}
    516534
     535
    517536glooxwrapper::MUCRoom::MUCRoom(Client* parent, const JID& nick, MUCRoomHandler* mrh, MUCRoomConfigHandler* UNUSED(mrch))
    518537{
    519538    m_HandlerWrapper = new MUCRoomHandlerWrapper(mrh);
  • source/lobby/glooxwrapper/glooxwrapper.h

     
    8585{
    8686    class Client;
    8787    class DataForm;
     88    class DelayedDelivery;
    8889    class Disco;
    8990    class IQ;
    9091    class JID;
     
    406407        void disconnect();
    407408    };
    408409
     410    class GLOOXWRAPPER_API DelayedDelivery
     411    {
     412        NONCOPYABLE(DelayedDelivery);
     413    private:
     414        const gloox::DelayedDelivery* m_Wrapped;
     415    public:
     416        DelayedDelivery(const gloox::DelayedDelivery* wrapped);
     417        const string stamp() const;
     418    };
     419
    409420    class GLOOXWRAPPER_API Disco
    410421    {
    411422        NONCOPYABLE(Disco);
     
    480491        string body() const;
    481492        string subject(const string& lang = "default") const;
    482493        string thread() const;
     494        const glooxwrapper::DelayedDelivery* when() const;
    483495    };
    484496
    485497    class GLOOXWRAPPER_API MUCRoom
  • binaries/data/mods/public/gui/lobby/lobby.js

     
    1010const g_mapTypes = ["skirmish", "random", "scenario"];
    1111var g_userRating = ""; // Rating of user, defaults to Unrated
    1212var g_modPrefix = "@";
     13var g_joined = false;
    1314// Block spammers for 30 seconds.
    1415var SPAM_BLOCK_LENGTH = 30;
    1516
     
    613614        {
    614615        case "mucmessage": // For room messages
    615616            var from = escapeText(message.from);
    616             addChatMessage({ "from": from, "text": text });
     617            addChatMessage({ "from": from, "text": text, "datetime": message.datetime});
    617618            break;
    618619        case "message": // For private messages
    619620            var from = escapeText(message.from);
    620             addChatMessage({ "from": from, "text": text });
     621            addChatMessage({ "from": from, "text": text, "datetime": message.datetime});
    621622            break;
    622623        case "muc":
    623624            var nick = message.text;
     
    635636                {
    636637                    // We just joined, we need to get the full player list
    637638                    [playerList, presenceList, nickList, ratingList] = updatePlayerList();
     639                    // Don't display any joins until our join request bounces back
     640                    // Our join message should be the last one as we just got added to the stack
     641                    g_joined = true;
    638642                    break;
    639643                }
    640                 var [name, status, rating] = formatPlayerListEntry(nick, presence, "-");
    641                 playerList.push(name);
    642                 presenceList.push(status);
    643                 nickList.push(nick);
    644                 ratingList.push(String(rating));
    645                 Engine.SendGetRatingList();
    646                 addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { nick: nick }), "key": g_specialKey });
     644                else if (g_joined)
     645                {
     646                    var [name, status, rating] = formatPlayerListEntry(nick, presence, "-");
     647                    playerList.push(name);
     648                    presenceList.push(status);
     649                    nickList.push(nick);
     650                    ratingList.push(String(rating));
     651                    Engine.SendGetRatingList();
     652                    addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { nick: nick }), "key": g_specialKey });
     653                }
    647654                break;
    648655            case "leave":
    649656                if (nickIndex == -1) // Left, but not present (TODO: warn about this?)
     
    819826    if (!msg.color)
    820827        msg.color = null;
    821828    if (!msg.key)
    822         msg.key = null;
     829        msg.key = null;
     830    if (!msg.datetime)
     831        msg.datetime = null;
    823832
    824833    // Highlight local user's nick
    825834    if (msg.text.indexOf(g_Name) != -1 && g_Name != msg.from)
    826835        msg.text = msg.text.replace(new RegExp('\\b' + '\\' + g_Name + '\\b', "g"), colorPlayerName(g_Name));
    827836
    828     // Run spam test
    829     updateSpamMonitor(msg.from);
     837    // Run spam test if it's not a historical message
     838    if (!msg.datetime)
     839        updateSpamMonitor(msg.from);
    830840    if (isSpam(msg.text, msg.from))
    831841        return;
    832842
    833843    // Format Text
    834     var formatted = ircFormat(msg.text, msg.from, msg.color, msg.key);
     844    var formatted = ircFormat(msg.text, msg.from, msg.color, msg.key, msg.datetime);
    835845
    836846    // If there is text, add it to the chat box.
    837847    if (formatted)
     
    856866 * @param from Sender of the message.
    857867 * @param color Optional color of sender.
    858868 * @param key Key to verify join/leave messages with. TODO: Remove this, it only provides synthetic security.
     869 * @param datetime Current date and time of message, only used for historical messages
    859870 * @return Formatted text.
    860871 */
    861 function ircFormat(text, from, color, key)
     872function ircFormat(text, from, color, key, datetime)
    862873{
    863874    // Generate and apply color to uncolored names,
    864875    if (!color && from)
     
    912923    // Build time header if enabled
    913924    if (g_timestamp)
    914925    {
    915         // Time for optional time header
    916         var time = new Date(Date.now());
    917926
     927        var time;
     928        if (datetime)
     929        {
     930            var parserDate = datetime.split("T")[0].split("-");
     931            var parserTime = datetime.split("T")[1].split(":");
     932            // See http://xmpp.org/extensions/xep-0082.html#sect-idp285136 for format of datetime
     933            // Date takes Year, Month, Day, Hour, Minute, Second
     934            time = new Date(Date.UTC(parserDate[0], parserDate[1], parserDate[2], parserTime[0], parserTime[1], parserTime[2].split("Z")[0]));
     935        }
     936        else
     937            time = new Date(Date.now());
     938
    918939        // Translation: Time as shown in the multiplayer lobby (when you enable it in the options page).
    919940        // For a list of symbols that you can use, see:
    920941        // https://sites.google.com/site/icuprojectuserguide/formatparse/datetime?pli=1#TOC-Date-Field-Symbol-Table