Display previously received lobby chat messages when returning from the gamesetup.

Differential Revision: https://code.wildfiregames.com/D819
Fixes #3306
Patch By: fpre / ffffffff
This was SVN commit r20070.
This commit is contained in:
elexis 2017-08-29 16:04:45 +00:00
parent 0ceeaf921b
commit e8dfde9ba6
7 changed files with 71 additions and 30 deletions

View file

@ -233,18 +233,19 @@ var g_NetMessageTypes = {
return true;
},
"kicked": msg => {
handleKick(false, msg.nick, msg.reason, msg.time);
handleKick(false, msg.nick, msg.reason, msg.time, msg.historic);
return true;
},
"banned": msg => {
handleKick(true, msg.nick, msg.reason, msg.time);
handleKick(true, msg.nick, msg.reason, msg.time, msg.historic);
return true;
},
"room-message": msg => {
addChatMessage({
"from": escapeText(msg.from),
"text": escapeText(msg.text),
"time": msg.time
"time": msg.time,
"historic": msg.historic
});
return false;
},
@ -264,7 +265,8 @@ var g_NetMessageTypes = {
"from": escapeText(msg.from || "system"),
"text": escapeText(msg.text.trim()),
"time": msg.time,
"private" : true
"historic": msg.historic,
"private": true
});
return false;
}
@ -395,6 +397,10 @@ function init(attribs)
updateToggleBuddy();
Engine.GetGUIObjectByName("chatInput").tooltip = colorizeAutocompleteHotkey();
// Get all messages since the login
for (let msg of Engine.LobbyGuiPollHistoricMessages())
g_NetMessageTypes[msg.type][msg.level](msg);
}
function updateLobbyColumns()
@ -516,7 +522,7 @@ function filterGame(game)
return false;
}
function handleKick(banned, nick, reason, time)
function handleKick(banned, nick, reason, time, historic)
{
let kickString = nick == g_Username ?
banned ?
@ -536,6 +542,7 @@ function handleKick(banned, nick, reason, time)
addChatMessage({
"text": "/special " + sprintf(kickString, { "nick": nick }) + " " + reason,
"time": time,
"historic": historic,
"isSpecial": true
});
return;
@ -1171,7 +1178,7 @@ function onTick()
while (true)
{
let msg = Engine.LobbyGuiPollMessage();
let msg = Engine.LobbyGuiPollNewMessage();
if (!msg)
break;
@ -1270,7 +1277,9 @@ function addChatMessage(msg)
if (g_Username != msg.from)
{
msg.text = msg.text.replace(g_Username, colorPlayerName(g_Username));
notifyUser(g_Username, msg.text);
if (!msg.historic)
notifyUser(g_Username, msg.text);
}
}

View file

@ -154,7 +154,7 @@ function onTick()
// Handle queued messages from the XMPP client (if running and if any)
let message;
while ((message = Engine.LobbyGuiPollMessage()) != undefined)
while ((message = Engine.LobbyGuiPollNewMessage()) != undefined)
{
// TODO: Properly deal with unrecognized messages
if (message.type != "system" || !message.level)

View file

@ -53,10 +53,9 @@ public:
virtual void GUIGetGameList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
virtual void GUIGetBoardList(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
virtual void GUIGetProfile(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
virtual void GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret) = 0;
virtual JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface) = 0;
virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface) = 0;
virtual void SendMUCMessage(const std::string& message) = 0;
virtual void SendStunEndpointToHost(StunClient::StunEndpoint* stunEndpoint, const std::string& hostJID) = 0;
};

View file

@ -229,6 +229,7 @@ void XmppClient::onDisconnect(gloox::ConnectionError error)
m_GameList.clear();
m_PlayerMap.clear();
m_Profile.clear();
m_HistoricGuiMessages.clear();
CreateGUIMessage("system", "disconnected", "reason", ConnectionErrorToString(error));
}
@ -569,19 +570,12 @@ void XmppClient::CreateGUIMessage(
m_GuiMessageQueue.push_back(std::move(message));
}
void XmppClient::GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret)
JS::Value XmppClient::GuiMessageToJSVal(const ScriptInterface& scriptInterface, const GUIMessage& message, const bool historic)
{
if (m_GuiMessageQueue.empty())
{
ret.setUndefined();
return;
}
GUIMessage message = m_GuiMessageQueue.front();
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
scriptInterface.Eval("({})", ret);
JS::RootedValue ret(cx);
scriptInterface.Eval("({})", &ret);
scriptInterface.SetProperty(ret, "type", wstring_from_utf8(message.type));
if (!message.level.empty())
scriptInterface.SetProperty(ret, "level", wstring_from_utf8(message.level));
@ -590,7 +584,38 @@ void XmppClient::GuiPollMessage(const ScriptInterface& scriptInterface, JS::Muta
if (!message.property2_name.empty())
scriptInterface.SetProperty(ret, message.property2_name.c_str(), wstring_from_utf8(message.property2_value));
scriptInterface.SetProperty(ret, "time", (double)message.time);
scriptInterface.SetProperty(ret, "historic", historic);
return ret;
}
JS::Value XmppClient::GuiPollNewMessage(const ScriptInterface& scriptInterface)
{
if (m_GuiMessageQueue.empty())
return JS::UndefinedValue();
GUIMessage message = m_GuiMessageQueue.front();
m_GuiMessageQueue.pop_front();
// Since there can be hundreds of presence changes while playing a game, ignore these for performance
if (message.type == "chat" && message.level != "presence")
m_HistoricGuiMessages.push_back(message);
return GuiMessageToJSVal(scriptInterface, message, false);
}
JS::Value XmppClient::GuiPollHistoricMessages(const ScriptInterface& scriptInterface)
{
JSContext* cx = scriptInterface.GetContext();
JSAutoRequest rq(cx);
JS::RootedObject ret(cx, JS_NewArrayObject(cx, 0));
uint32_t i = 0;
for (const GUIMessage& message : m_HistoricGuiMessages)
{
JS::RootedValue msg(cx, GuiMessageToJSVal(scriptInterface, message, true));
JS_SetElement(cx, ret, i++, msg);
}
return JS::ObjectValue(*ret);
}
/**

View file

@ -143,7 +143,9 @@ public:
std::string property2_value;
std::time_t time;
};
void GuiPollMessage(const ScriptInterface& scriptInterface, JS::MutableHandleValue ret);
JS::Value GuiMessageToJSVal(const ScriptInterface& scriptInterface, const GUIMessage& message, const bool historic);
JS::Value GuiPollNewMessage(const ScriptInterface& scriptInterface);
JS::Value GuiPollHistoricMessages(const ScriptInterface& scriptInterface);
void SendMUCMessage(const std::string& message);
void ClearPresenceUpdates();
protected:
@ -167,6 +169,8 @@ private:
std::vector<const glooxwrapper::Tag*> m_Profile;
/// Queue of messages for the GUI
std::deque<GUIMessage> m_GuiMessageQueue;
/// Cache of all GUI messages received since the login
std::vector<GUIMessage> m_HistoricGuiMessages;
/// Current room subject/topic.
std::string m_Subject;
};

View file

@ -50,7 +50,8 @@ void JSI_Lobby::RegisterScriptFunctions(const ScriptInterface& scriptInterface)
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetGameList>("GetGameList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetBoardList>("GetBoardList");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::GetProfile>("GetProfile");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollMessage>("LobbyGuiPollMessage");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollNewMessage>("LobbyGuiPollNewMessage");
scriptInterface.RegisterFunction<JS::Value, &JSI_Lobby::LobbyGuiPollHistoricMessages>("LobbyGuiPollHistoricMessages");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySendMessage>("LobbySendMessage");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySetPlayerPresence>("LobbySetPlayerPresence");
scriptInterface.RegisterFunction<void, std::wstring, &JSI_Lobby::LobbySetNick>("LobbySetNick");
@ -225,18 +226,20 @@ JS::Value JSI_Lobby::GetProfile(ScriptInterface::CxPrivate* pCxPrivate)
return profileFetch;
}
JS::Value JSI_Lobby::LobbyGuiPollMessage(ScriptInterface::CxPrivate* pCxPrivate)
JS::Value JSI_Lobby::LobbyGuiPollNewMessage(ScriptInterface::CxPrivate* pCxPrivate)
{
if (!g_XmppClient)
return JS::UndefinedValue();
JSContext* cx = pCxPrivate->pScriptInterface->GetContext();
JSAutoRequest rq(cx);
return g_XmppClient->GuiPollNewMessage(*(pCxPrivate->pScriptInterface));
}
JS::RootedValue poll(cx);
g_XmppClient->GuiPollMessage(*(pCxPrivate->pScriptInterface), &poll);
JS::Value JSI_Lobby::LobbyGuiPollHistoricMessages(ScriptInterface::CxPrivate* pCxPrivate)
{
if (!g_XmppClient)
return JS::UndefinedValue();
return poll;
return g_XmppClient->GuiPollHistoricMessages(*(pCxPrivate->pScriptInterface));
}
void JSI_Lobby::LobbySendMessage(ScriptInterface::CxPrivate* UNUSED(pCxPrivate), const std::wstring& message)

View file

@ -47,7 +47,8 @@ namespace JSI_Lobby
JS::Value GetGameList(ScriptInterface::CxPrivate* pCxPrivate);
JS::Value GetBoardList(ScriptInterface::CxPrivate* pCxPrivate);
JS::Value GetProfile(ScriptInterface::CxPrivate* pCxPrivate);
JS::Value LobbyGuiPollMessage(ScriptInterface::CxPrivate* pCxPrivate);
JS::Value LobbyGuiPollNewMessage(ScriptInterface::CxPrivate* pCxPrivate);
JS::Value LobbyGuiPollHistoricMessages(ScriptInterface::CxPrivate* pCxPrivate);
void LobbySendMessage(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& message);
void LobbySetPlayerPresence(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& presence);
void LobbySetNick(ScriptInterface::CxPrivate* pCxPrivate, const std::wstring& nick);