Index: binaries/data/mods/public/gui/lobby/lobby.js =================================================================== --- binaries/data/mods/public/gui/lobby/lobby.js +++ binaries/data/mods/public/gui/lobby/lobby.js @@ -121,18 +121,11 @@ updateLeaderboard(); updatePlayerList(); Engine.GetGUIObjectByName("hostButton").enabled = false; - - addChatMessage({ - "from": "system", - "text": translate("Disconnected.") + msg.text, - "color": g_SystemColor - }); }, "error": msg => { addChatMessage({ "from": "system", "text": msg.text, - "color": g_SystemColor }); } }, @@ -156,6 +149,9 @@ }), "isSpecial": true }); + + if (msg.text == g_Username) + Engine.DisconnectXmppClient(); }, "presence": msg => { }, @@ -168,6 +164,12 @@ "isSpecial": true }); }, + "kicked": msg => { + handleKick(false, msg.text, msg.data); + }, + "banned": msg => { + handleKick(true, msg.text, msg.data); + }, "room-message": msg => { addChatMessage({ "from": escapeText(msg.from), @@ -194,6 +196,38 @@ } }; +function handleKick(banned, nick, reason) +{ + let kickString = nick == g_Username ? + banned ? + translate("You have been banned from the lobby!") : + translate("You have been kicked from the lobby!") : + banned ? + translate("%(nick)s has been banned from the lobby.") : + translate("%(nick)s has been kicked from the lobby.") + + if (reason) + reason = sprintf(translateWithContext("lobby kick", "Reason: %(reason)s"), { + "reason": reason + }); + + addChatMessage({ + "text": "/special " + sprintf(kickString, { "nick": nick }) + " " + reason, + "isSpecial": true + }); + + if (nick != g_Username) + return; + + Engine.DisconnectXmppClient(); + + messageBox( + 400, 250, + kickString + "\n" + reason, + banned ? translate("BANNED") : translate("KICKED") + ); +} + /** * Called after the XmppConnection succeeded and when returning from a game. * @@ -785,7 +819,8 @@ if (text[0] != '/') return false; - let [cmd, nick] = ircSplit(text); + let [cmd, args] = ircSplit(text); + let [nick, reason] = ircSplit("/" + args); switch (cmd) { @@ -796,11 +831,10 @@ Engine.LobbySetPlayerPresence("available"); break; case "kick": - // TODO: Split reason from nick and pass it too - Engine.LobbyKick(nick, ""); + Engine.LobbyKick(nick, reason); break; case "ban": - Engine.LobbyBan(nick, ""); + Engine.LobbyBan(nick, reason); break; case "quit": returnToMainMenu(); @@ -859,7 +893,6 @@ Engine.GetGUIObjectByName("chatText").caption = g_ChatMessages.join("\n"); } - /** * Splits given input into command and argument. */ @@ -882,11 +915,7 @@ function ircFormat(msg) { let formattedMessage = ""; - - let coloredFrom = !msg.from ? "" : - msg.color ? - '[color="' + msg.color + '"]' + msg.from + "[/color]" : - colorPlayerName(msg.from); + let coloredFrom = msg.from && colorPlayerName(msg.from); // Handle commands allowed past handleSpecialCommand. if (msg.text[0] == '/') @@ -1094,6 +1123,9 @@ */ function getPlayerColor(playername) { + if (playername == "system") + return g_SystemColor; + // Generate a probably-unique hash for the player name and use that to create a color. let hash = 0; for (let i in playername) Index: source/lobby/XmppClient.cpp =================================================================== --- source/lobby/XmppClient.cpp +++ source/lobby/XmppClient.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -797,11 +797,24 @@ m_PlayerMap[newNick][0] = presenceString; m_PlayerMap[newNick][2] = roleString; CreateGUIMessage("chat", "nick", nick, participant.newNick.to_string()); + DbgXMPP(nick << " is now known as " << participant.newNick.to_string()); + } + else if (participant.flags & gloox::UserKicked) + { + DbgXMPP(nick << " was kicked. Reason:" << participant.reason.to_string()); + CreateGUIMessage("chat", "kicked", nick, participant.reason.to_string()); + } + else if (participant.flags & gloox::UserBanned) + { + DbgXMPP(nick << " was banned. Reason:" << participant.reason.to_string()); + CreateGUIMessage("chat", "banned", nick, participant.reason.to_string()); } else + { + DbgXMPP(nick << " left the room (flags " << flags << participant.flags << ")"); CreateGUIMessage("chat", "leave", nick); + } - DbgXMPP(nick << " left the room"); m_PlayerMap.erase(nick); } else Index: source/lobby/glooxwrapper/glooxwrapper.cpp =================================================================== --- source/lobby/glooxwrapper/glooxwrapper.cpp +++ source/lobby/glooxwrapper/glooxwrapper.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -141,13 +141,6 @@ /* MUCRoom not supported */ m_Wrapped->handleMUCParticipantPresence(NULL, part, glooxwrapper::Presence(presence.presence())); - - /* gloox 1.0 leaks some JIDs (fixed in 1.0.1), so clean them up */ -#if GLOOXVERSION == 0x10000 - delete participant.jid; - delete participant.actor; - delete participant.alternate; -#endif } virtual void handleMUCMessage(gloox::MUCRoom* UNUSED(room), const gloox::Message& msg, bool priv) Index: source/lobby/scripting/JSInterface_Lobby.cpp =================================================================== --- source/lobby/scripting/JSInterface_Lobby.cpp +++ source/lobby/scripting/JSInterface_Lobby.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2017 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -69,7 +69,7 @@ bool JSI_Lobby::HasXmppClient(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) { - return (g_XmppClient ? true : false); + return (bool) g_XmppClient; } bool JSI_Lobby::IsRankedGame(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) @@ -180,9 +180,6 @@ JS::Value JSI_Lobby::GetPlayerList(ScriptInterface::CxPrivate* pCxPrivate) { - if (!g_XmppClient) - return JS::UndefinedValue(); - JSContext* cx = pCxPrivate->pScriptInterface->GetContext(); JSAutoRequest rq(cx);