Index: binaries/data/mods/public/gui/gamesetup/gamesetup.js =================================================================== --- binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -2694,7 +2694,6 @@ let stanza = { "name": g_ServerName, "port": g_ServerPort, - "hostUsername": Engine.LobbyGetNick(), "mapName": g_GameAttributes.map, "niceMapName": getMapDisplayName(g_GameAttributes.map), "mapSize": g_GameAttributes.mapType == "random" ? g_GameAttributes.settings.Size : "Default", Index: binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js =================================================================== --- binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js +++ binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js @@ -312,7 +312,7 @@ try { - Engine.StartNetworkHost(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), port, playername); + Engine.StartNetworkHost(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), port); } catch (e) { 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 @@ -1254,7 +1254,7 @@ "name": g_Username, "rating": getRejoinRating(game), "useSTUN": !!game.stunIP, - "hostJID": game.hostUsername + "@" + g_LobbyServer + "/0ad" + "hostJID": game.hostJID }); } Index: source/lobby/IXmppClient.h =================================================================== --- source/lobby/IXmppClient.h +++ source/lobby/IXmppClient.h @@ -44,6 +44,7 @@ virtual void SendIqLobbyAuth(const std::string& to, const std::string& token) = 0; virtual void SetNick(const std::string& nick) = 0; virtual void GetNick(std::string& nick) = 0; + virtual void GetRoomJID(std::string& jid) = 0; virtual void kick(const std::string& nick, const std::string& reason) = 0; virtual void ban(const std::string& nick, const std::string& reason) = 0; virtual void SetPresence(const std::string& presence) = 0; Index: source/lobby/XmppClient.h =================================================================== --- source/lobby/XmppClient.h +++ source/lobby/XmppClient.h @@ -74,9 +74,10 @@ void SendIqRegisterGame(const ScriptInterface& scriptInterface, JS::HandleValue data); void SendIqUnregisterGame(); void SendIqChangeStateGame(const std::string& nbp, const std::string& players); - void SendIqLobbyAuth(const std::string& to, const std::string& token); + void SendIqLobbyAuth(const std::string& hostJIDStr, const std::string& token); void SetNick(const std::string& nick); void GetNick(std::string& nick); + void GetRoomJID(std::string& jid); void kick(const std::string& nick, const std::string& reason); void ban(const std::string& nick, const std::string& reason); void SetPresence(const std::string& presence); Index: source/lobby/XmppClient.cpp =================================================================== --- source/lobby/XmppClient.cpp +++ source/lobby/XmppClient.cpp @@ -439,13 +439,13 @@ /** * Send lobby authentication token. */ -void XmppClient::SendIqLobbyAuth(const std::string& to, const std::string& token) +void XmppClient::SendIqLobbyAuth(const std::string& hostJIDStr, const std::string& token) { LobbyAuth* auth = new LobbyAuth(); auth->m_Token = token; - glooxwrapper::JID clientJid(to + "@" + m_server + "/0ad"); - glooxwrapper::IQ iq(gloox::IQ::Set, clientJid, m_client->getID()); + glooxwrapper::JID hostJID(hostJIDStr); + glooxwrapper::IQ iq(gloox::IQ::Set, hostJID, m_client->getID()); iq.addExtension(auth); DbgXMPP("SendIqLobbyAuth [" << tag_xml(iq) << "]"); m_client->send(iq); @@ -528,7 +528,7 @@ JSAutoRequest rq(cx); scriptInterface.Eval("([])", ret); - const char* stats[] = { "name", "ip", "port", "stunIP", "stunPort", "hostUsername", "state", + const char* stats[] = { "name", "ip", "port", "stunIP", "stunPort", "hostJID", "state", "nbp", "maxnbp", "players", "mapName", "niceMapName", "mapSize", "mapType", "victoryCondition", "startTime", "mods" }; for(const glooxwrapper::Tag* const& t : m_GameList) @@ -912,6 +912,12 @@ nick = m_mucRoom->nick().to_string(); } +void XmppClient::GetRoomJID(std::string& jid) +{ + // TODO: add new getter? + jid = m_client->getWrapped()->jid().full(); +} + /** * Kick a player from the current room. * Index: source/network/NetClient.h =================================================================== --- source/network/NetClient.h +++ source/network/NetClient.h @@ -91,10 +91,10 @@ void SetUserName(const CStrW& username); /** - * Set the name of the hosting player. + * Set the JID of the hosting player. * This is needed for the secure lobby authentication. */ - void SetHostingPlayerName(const CStr& hostingPlayerName); + void SetHostJID(const CStr& hostJID); /** * Returns the GUID of the local client. @@ -261,7 +261,7 @@ CGame *m_Game; CStrW m_UserName; - CStr m_HostingPlayerName; + CStr m_HostJID; /// Current network session (or NULL if not connected) CNetClientSession* m_Session; Index: source/network/NetClient.cpp =================================================================== --- source/network/NetClient.cpp +++ source/network/NetClient.cpp @@ -160,9 +160,9 @@ m_UserName = username; } -void CNetClient::SetHostingPlayerName(const CStr& hostingPlayerName) +void CNetClient::SetHostJID(const CStr& HostJID) { - m_HostingPlayerName = hostingPlayerName; + m_HostJID = HostJID; } bool CNetClient::SetupConnection(const CStr& server, const u16 port, ENetHost* enetClient) @@ -534,8 +534,8 @@ if (message->m_Flags & PS_NETWORK_FLAG_REQUIRE_LOBBYAUTH) { - if (g_XmppClient && !client->m_HostingPlayerName.empty()) - g_XmppClient->SendIqLobbyAuth(client->m_HostingPlayerName, client->m_GUID); + if (g_XmppClient && !client->m_HostJID.empty()) + g_XmppClient->SendIqLobbyAuth(client->m_HostJID, client->m_GUID); else { JSContext* cx = client->GetScriptInterface().GetContext(); Index: source/network/scripting/JSInterface_Network.h =================================================================== --- source/network/scripting/JSInterface_Network.h +++ source/network/scripting/JSInterface_Network.h @@ -29,7 +29,7 @@ bool HasNetClient(ScriptInterface::CxPrivate* pCxPrivate); void StartNetworkGame(ScriptInterface::CxPrivate* pCxPrivate); void SetNetworkGameAttributes(ScriptInterface::CxPrivate* pCxPrivate, JS::HandleValue attribs1); - void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName); + void StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort); void StartNetworkJoin(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const CStr& serverAddress, u16 serverPort, bool useSTUN, const CStr& hostJID); JS::Value FindStunEndpoint(ScriptInterface::CxPrivate* pCxPrivate, int port); void DisconnectNetworkGame(ScriptInterface::CxPrivate* pCxPrivate); Index: source/network/scripting/JSInterface_Network.cpp =================================================================== --- source/network/scripting/JSInterface_Network.cpp +++ source/network/scripting/JSInterface_Network.cpp @@ -51,7 +51,7 @@ return StunClient::FindStunEndpointHost(*(pCxPrivate->pScriptInterface), port); } -void JSI_Network::StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort, const CStr& hostLobbyName) +void JSI_Network::StartNetworkHost(ScriptInterface::CxPrivate* pCxPrivate, const CStrW& playerName, const u16 serverPort) { ENSURE(!g_NetClient); ENSURE(!g_NetServer); @@ -69,7 +69,13 @@ g_Game = new CGame(); g_NetClient = new CNetClient(g_Game, true); g_NetClient->SetUserName(playerName); - g_NetClient->SetHostingPlayerName(hostLobbyName); + + if (g_XmppClient) + { + std::string hostJID; + g_XmppClient->GetRoomJID(hostJID); + g_NetClient->SetHostJID(hostJID); + } if (!g_NetClient->SetupConnection("127.0.0.1", serverPort)) { @@ -120,7 +126,9 @@ g_Game = new CGame(); g_NetClient = new CNetClient(g_Game, false); g_NetClient->SetUserName(playerName); - g_NetClient->SetHostingPlayerName(hostJID.substr(0, hostJID.find("@"))); + + if (g_XmppClient) + g_NetClient->SetHostJID(hostJID); if (g_XmppClient && useSTUN) StunClient::SendHolePunchingMessages(enetClient, serverAddress.c_str(), serverPort); @@ -230,7 +238,7 @@ scriptInterface.RegisterFunction("HasNetServer"); scriptInterface.RegisterFunction("HasNetClient"); scriptInterface.RegisterFunction("FindStunEndpoint"); - scriptInterface.RegisterFunction("StartNetworkHost"); + scriptInterface.RegisterFunction("StartNetworkHost"); scriptInterface.RegisterFunction("StartNetworkJoin"); scriptInterface.RegisterFunction("DisconnectNetworkGame"); scriptInterface.RegisterFunction("GetPlayerGUID"); Index: source/tools/lobbybots/README.md =================================================================== --- source/tools/lobbybots/README.md +++ source/tools/lobbybots/README.md @@ -93,8 +93,9 @@ ### 1.3 Install ejabberd ipstamp module -The ejabberd ipstamp module has the purpose of inserting the IP address of the hosting players into the gamelist packet. -That enables players to connect to each others games. +The ejabberd ipstamp module has the purpose of inserting the IP address and JIDs of the hosting players into the gamelist packet. +The IP addresses enable players to connect to each others games. +The JID is used by clients for STUN connection negotiation and the authentication mechanism that ensures that playernames match the lobby usernames. * Adjust `/etc/ejabberd/ejabberdctl.cfg` and set `CONTRIB_MODULES_PATH` to the directory where you want to store `mod_ipstamp`: Index: source/tools/lobbybots/mod_ipstamp/README.txt =================================================================== --- source/tools/lobbybots/mod_ipstamp/README.txt +++ source/tools/lobbybots/mod_ipstamp/README.txt @@ -1,7 +1,7 @@ mod_ipstamp =========== -mod_ipstamp is an ejabberd module for 0ad which adds ip addresses of a -game host to game registration stanzas. +mod_ipstamp is an ejabberd module for 0ad which adds ip addresses and JIDs of +game hosts to the game registration stanzas. For it to work the 0ad XMPP bots need to have the ACL "ipbots". Index: source/tools/lobbybots/mod_ipstamp/src/mod_ipstamp.erl =================================================================== --- source/tools/lobbybots/mod_ipstamp/src/mod_ipstamp.erl +++ source/tools/lobbybots/mod_ipstamp/src/mod_ipstamp.erl @@ -42,7 +42,7 @@ reload(_Host, _NewOpts, _OldOpts) -> ok. -spec on_filter_packet(Input :: iq()) -> iq() | drop. -on_filter_packet(#iq{type = set, to = To, sub_els = [SubEl]} = Input) -> +on_filter_packet(#iq{type = set, from = From, to = To, sub_els = [SubEl]} = Input) -> % We only want to do something for the bots case acl:match_rule(global, ipbots, To) of allow -> @@ -55,9 +55,14 @@ SIp = inet_parse:ntoa(Ip), ?INFO_MSG(string:concat("Inserting IP into game registration " "stanza: ", SIp), []), + % Get the sender's JID + SJID = jid:encode(From), + ?INFO_MSG(string:concat("Inserting JID into game registration " + "stanza: ", SJID), []), Game = fxml:get_subtag(SubEl, <<"game">>), GameWithIp = fxml:replace_tag_attr(<<"ip">>, SIp, Game), - SubEl2 = fxml:replace_subtag(GameWithIp, SubEl), + GameWithIpAndUser = fxml:replace_tag_attr(<<"hostJID">>, SJID, GameWithIp), + SubEl2 = fxml:replace_subtag(GameWithIpAndUser, SubEl), xmpp:set_els(Input, [SubEl2]); true -> Input