Ticket #3386: t3386_fix_lobby_rejoin_v3.1.patch

File t3386_fix_lobby_rejoin_v3.1.patch, 13.0 KB (added by elexis, 9 years ago)

Removed wrong comment.

  • binaries/data/mods/public/gui/lobby/lobby.js

     
    4646    mapTypeFilter.list_data = [""].concat(g_mapTypes);
    4747
    4848    Engine.LobbySetPlayerPresence("available");
    4949    Engine.SendGetGameList();
    5050    Engine.SendGetBoardList();
     51
     52    // When rejoining the lobby after a game, we don't need to process presence changes
     53    Engine.LobbyClearPresenceUpdates();
    5154    updatePlayerList();
     55
    5256    updateSubject(Engine.LobbyGetRoomSubject());
    5357
    5458    resetFilters();
    5559}
    5660
     
    231235    playersBox.list_status = presenceList;
    232236    playersBox.list_rating = ratingList;
    233237    playersBox.list = nickList;
    234238    if (playersBox.selected >= playersBox.list.length)
    235239        playersBox.selected = -1;
    236     return [playerList, presenceList, nickList, ratingList];
    237240}
    238241
    239242/**
    240243 * Display the profile of the selected player.
    241244 * Displays N/A for all stats until updateProfile is called when the stats
     
    687690            var from = escapeText(message.from);
    688691            addChatMessage({ "from": from, "text": text, "datetime": message.datetime});
    689692            break;
    690693        case "muc":
    691694            var nick = message.text;
    692             var presence = Engine.LobbyGetPlayerPresence(nick);
    693             var playersBox = Engine.GetGUIObjectByName("playersBox");
    694             var playerList = playersBox.list_name;
    695             var presenceList = playersBox.list_status;
    696             var nickList = playersBox.list;
    697             var ratingList = playersBox.list_rating;
    698             var nickIndex = nickList.indexOf(nick);
    699695            switch(message.level)
    700696            {
    701697            case "join":
    702                 var [name, status, rating] = formatPlayerListEntry(nick, presence, "-");
    703                 playerList.push(name);
    704                 presenceList.push(status);
    705                 nickList.push(nick);
    706                 ratingList.push(String(rating));
    707698                addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has joined."), { nick: nick }), "key": g_specialKey });
    708699                break;
    709700            case "leave":
    710                 if (nickIndex == -1) // Left, but not present (TODO: warn about this?)
    711                     break;
    712                 playerList.splice(nickIndex, 1);
    713                 presenceList.splice(nickIndex, 1);
    714                 nickList.splice(nickIndex, 1);
    715                 ratingList.splice(nickIndex, 1);
    716701                addChatMessage({ "text": "/special " + sprintf(translate("%(nick)s has left."), { nick: nick }), "key": g_specialKey });
    717702                break;
    718703            case "nick":
    719                 if (nickIndex == -1) // Changed nick, but not present (shouldn't ever happen)
    720                     break;
    721                 if (!isValidNick(message.data))
    722                 {
    723                     addChatMessage({ "from": "system", "text": sprintf(translate("Invalid nickname: %(nick)s"), { nick: message.data })});
    724                     break;
    725                 }
    726                 var [name, status, rating] = formatPlayerListEntry(message.data, presence, stripColorCodes(ratingList[nickIndex])); // TODO: actually we don't want to change the presence here, so use what was used before
    727                 playerList[nickIndex] = name;
    728                 // presence stays the same
    729                 nickList[nickIndex] = message.data;
    730704                addChatMessage({ "text": "/special " + sprintf(translate("%(oldnick)s is now known as %(newnick)s."), { oldnick: nick, newnick: message.data }), "key": g_specialKey });
    731705                break;
    732706            case "presence":
    733                 if (nickIndex == -1) // Changed presence, but not online (shouldn't ever happen)
    734                     break;
    735                 var [name, status, rating] = formatPlayerListEntry(nick, presence, stripColorCodes(ratingList[nickIndex]));
    736                 presenceList[nickIndex] = status;
    737                 playerList[nickIndex] = name;
    738                 ratingList[nickIndex] = rating;
    739707                break;
    740708            case "subject":
    741709                updateSubject(message.text);
    742710                break;
    743711            default:
    744712                warn(sprintf("Unknown message.level '%(msglvl)s'", { msglvl: message.level }));
    745713                break;
    746714            }
    747             // Push new data to GUI
    748             playersBox.list_name = playerList;
    749             playersBox.list_status = presenceList;
    750             playersBox.list_rating = ratingList;
    751             playersBox.list = nickList;     
    752             if (playersBox.selected >= playersBox.list.length)
    753                 playersBox.selected = -1;
     715            // We might receive many join/leaves when returning to the lobby from a long game.
     716            // To improve performance, only update the playerlist GUI when the last update in the current stack is processed
     717            if (Engine.LobbyGetMucMessageCount() == 0)
     718                updatePlayerList();
    754719            break;
    755720        case "system":
    756721            switch (message.level)
    757722            {
    758723            case "standard":
  • source/lobby/IXmppClient.h

     
    1 /* Copyright (C) 2014 Wildfire Games.
     1/* Copyright (C) 2015 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    55 * it under the terms of the GNU General Public License as published by
    66 * the Free Software Foundation, either version 2 of the License, or
     
    4545    virtual void ban(const std::string& nick, const std::string& reason) = 0;
    4646    virtual void SetPresence(const std::string& presence) = 0;
    4747    virtual void GetPresence(const std::string& nickname, std::string& presence) = 0;
    4848    virtual void GetRole(const std::string& nickname, std::string& role) = 0;
    4949    virtual void GetSubject(std::string& subject) = 0;
    50 
    5150    virtual void GUIGetPlayerList(ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
     51    virtual void ClearPresenceUpdates() = 0;
     52    virtual int GetMucMessageCount() = 0;
    5253    virtual void GUIGetGameList(ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5354    virtual void GUIGetBoardList(ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5455    virtual void GUIGetProfile(ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
    5556
    5657    virtual void GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
  • source/lobby/XmppClient.cpp

     
    640640{
    641641    m_GuiMessageQueue.push_back(std::move(message));
    642642}
    643643
    644644/**
     645 * Clears all presence updates from the message queue.
     646 * Used when rejoining the lobby, since we don't need to handle past presence changes.
     647 */
     648void XmppClient::ClearPresenceUpdates()
     649{
     650    m_GuiMessageQueue.erase(
     651        std::remove_if(m_GuiMessageQueue.begin(), m_GuiMessageQueue.end(),
     652            [](XmppClient::GUIMessage& message)
     653            {
     654                return message.type == L"muc" && message.level == L"presence";
     655            }
     656    ), m_GuiMessageQueue.end());
     657}
     658
     659/**
     660 * Used in order to update the GUI only once when multiple updates are queued.
     661 */
     662int XmppClient::GetMucMessageCount()
     663{
     664    return std::count_if(m_GuiMessageQueue.begin(), m_GuiMessageQueue.end(),
     665        [](XmppClient::GUIMessage& message)
     666        {
     667            return message.type == L"muc";
     668        });
     669}
     670
     671/**
    645672 * Handle a standard MUC textual message.
    646673 */
    647674void XmppClient::handleMUCMessage(glooxwrapper::MUCRoom*, const glooxwrapper::Message& msg, bool)
    648675{
    649676    DbgXMPP(msg.from().resource() << " said " << msg.body());
  • source/lobby/XmppClient.h

     
    1 /* Copyright (C) 2014 Wildfire Games.
     1/* Copyright (C) 2015 Wildfire Games.
    22 * This file is part of 0 A.D.
    33 *
    44 * 0 A.D. is free software: you can redistribute it and/or modify
    55 * it under the terms of the GNU General Public License as published by
    66 * the Free Software Foundation, either version 2 of the License, or
     
    1818#ifndef XXXMPPCLIENT_H
    1919#define XXXMPPCLIENT_H
    2020
    2121#include "IXmppClient.h"
    2222
    23 #include "glooxwrapper/glooxwrapper.h"
    24 
    25 //game - script
    2623#include <deque>
     24
     25#include "glooxwrapper/glooxwrapper.h"
    2726#include "scriptinterface/ScriptVal.h"
    2827
    29 //Game - script
    3028class ScriptInterface;
    3129
    3230namespace glooxwrapper
    3331{
    3432    class Client;
     
    3634}
    3735
    3836class XmppClient : public IXmppClient, public glooxwrapper::ConnectionListener, public glooxwrapper::MUCRoomHandler, public glooxwrapper::IqHandler, public glooxwrapper::RegistrationHandler, public glooxwrapper::MessageHandler
    3937{
    4038    NONCOPYABLE(XmppClient);
     39
    4140private:
    4241    //Components
    4342    glooxwrapper::Client* m_client;
    4443    glooxwrapper::MUCRoom* m_mucRoom;
    4544    glooxwrapper::Registration* m_registration;
     45
    4646    //Account infos
    4747    std::string m_username;
    4848    std::string m_password;
    4949    std::string m_nick;
    5050    std::string m_xpartamuppId;
     51
    5152    // State
    5253    bool m_initialLoadComplete = false;
     54
    5355public:
    5456    //Basic
    5557    XmppClient(const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, const int historyRequestSize = 0, const bool regOpt = false);
    5658    virtual ~XmppClient();
    5759
     
    7880
    7981    void GUIGetPlayerList(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
    8082    void GUIGetGameList(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
    8183    void GUIGetBoardList(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
    8284    void GUIGetProfile(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
     85
    8386    //Script
    8487    ScriptInterface& GetScriptInterface();
    8588
    8689protected:
    8790    /* Xmpp handlers */
     
    120123
    121124    // Helpers
    122125    void GetPresenceString(const gloox::Presence::PresenceType p, std::string& presence) const;
    123126    void GetRoleString(const gloox::MUCRoomRole r, std::string& role) const;
    124127    std::string StanzaErrorToString(gloox::StanzaError err);
     128
    125129public:
    126130    /* Messages */
    127131    struct GUIMessage
    128132    {
    129133        std::wstring type;
     
    134138        std::wstring message;
    135139        std::string datetime;
    136140    };
    137141    void GuiPollMessage(ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
    138142    void SendMUCMessage(const std::string& message);
     143    void ClearPresenceUpdates();
     144    int GetMucMessageCount();
    139145    protected:
    140146    void PushGuiMessage(XmppClient::GUIMessage message);
    141147    void CreateSimpleMessage(const std::string& type, const std::string& text, const std::string& level = "standard", const std::string& data = "");
    142148
    143149private:
  • source/lobby/scripting/JSInterface_Lobby.cpp

     
    4545    scriptInterface.RegisterFunction<void, JS::HandleValue, &JSI_Lobby::SendRegisterGame>("SendRegisterGame");
    4646    scriptInterface.RegisterFunction<void, JS::HandleValue, &JSI_Lobby::SendGameReport>("SendGameReport");
    4747    scriptInterface.RegisterFunction<void, &JSI_Lobby::SendUnregisterGame>("SendUnregisterGame");
    4848    scriptInterface.RegisterFunction<void, std::wstring, std::wstring, &JSI_Lobby::SendChangeStateGame>("SendChangeStateGame");
    4949    scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetPlayerList>("GetPlayerList");
     50    scriptInterface.RegisterFunction<void, &JSI_Lobby::LobbyClearPresenceUpdates>("LobbyClearPresenceUpdates");
     51    scriptInterface.RegisterFunction<int, &JSI_Lobby::LobbyGetMucMessageCount>("LobbyGetMucMessageCount");
    5052    scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetGameList>("GetGameList");
    5153    scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetBoardList>("GetBoardList");
    5254    scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetProfile>("GetProfile");
    5355    scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollMessage>("LobbyGuiPollMessage");
    5456    scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySendMessage>("LobbySendMessage");
     
    187189    g_XmppClient->GUIGetPlayerList(*(pCxPrivate->pScriptInterface), &playerList);
    188190
    189191    return playerList;
    190192}
    191193
     194void JSI_Lobby::LobbyClearPresenceUpdates(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
     195{
     196    if (!g_XmppClient)
     197        return;
     198
     199    g_XmppClient->ClearPresenceUpdates();
     200}
     201
     202int JSI_Lobby::LobbyGetMucMessageCount(ScriptInterface::CxPrivate* UNUSED(pCxPrivate))
     203{
     204    return g_XmppClient ? g_XmppClient->GetMucMessageCount() : 0;
     205}
     206
    192207JS::Value JSI_Lobby::GetGameList(ScriptInterface::CxPrivate* pCxPrivate)
    193208{
    194209    if (!g_XmppClient)
    195210        return JS::UndefinedValue();
    196211
  • source/lobby/scripting/JSInterface_Lobby.h

     
    4343    void SendGameReport(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue data);
    4444    void SendRegisterGame(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue data);
    4545    void SendUnregisterGame(ScriptInterface::CxPrivate* pCxPrivate);
    4646    void SendChangeStateGame(ScriptInterface::CxPrivate* pCxPrivate, std::wstring nbp, std::wstring players);
    4747    JS::Value GetPlayerList(ScriptInterface::CxPrivate* pCxPrivate);
     48    void LobbyClearPresenceUpdates(ScriptInterface::CxPrivate* pCxPrivate);
     49    int LobbyGetMucMessageCount(ScriptInterface::CxPrivate* pCxPrivate);
    4850    JS::Value GetGameList(ScriptInterface::CxPrivate* pCxPrivate);
    4951    JS::Value GetBoardList(ScriptInterface::CxPrivate* pCxPrivate);
    5052    JS::Value GetProfile(ScriptInterface::CxPrivate* pCxPrivate);
    5153    JS::Value LobbyGuiPollMessage(ScriptInterface::CxPrivate* pCxPrivate);
    5254    void LobbySendMessage(ScriptInterface::CxPrivate* pCxPrivate, std::wstring message);