diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg index cc06d577e8..324461202f 100644 --- a/binaries/data/config/default.cfg +++ b/binaries/data/config/default.cfg @@ -519,8 +519,6 @@ rememberpassword = true ; Whether to store the encrypted password in gamerating = false ; Show the average rating of the participating players in a column of the gamelist [lobby.stun] -enabled = true ; The STUN protocol allows hosting games without configuring the firewall and router. - ; If STUN is disabled, the game relies on direct connection, UPnP and port forwarding. server = "lobby.wildfiregames.com" ; Address of the STUN server. port = 3478 ; Port of the STUN server. delay = 10 ; Duration in milliseconds that is waited between checking for retrieved STUN responses. diff --git a/binaries/data/mods/public/autostart/autostart_host.js b/binaries/data/mods/public/autostart/autostart_host.js index 787cdbd205..ff38fd62de 100644 --- a/binaries/data/mods/public/autostart/autostart_host.js +++ b/binaries/data/mods/public/autostart/autostart_host.js @@ -13,8 +13,8 @@ class AutoStartHost const playerName = cmdLineArgs['autostart-playername'] || "anonymous"; const port = +(cmdLineArgs['autostart-port'] ?? 5073); - // Stun and password not implemented for autostart. - Engine.StartNetworkHost(playerName, port, false, "", !('autostart-disable-replay' in cmdLineArgs)); + // Password not implemented for autostart. + Engine.StartNetworkHost(playerName, port, "", !('autostart-disable-replay' in cmdLineArgs)); } catch (e) { diff --git a/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js b/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js index 2ae6a5eebf..347c37acc9 100644 --- a/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js +++ b/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.js @@ -50,15 +50,12 @@ function init(attribs) case "host": { let hasXmppClient = Engine.HasXmppClient(); - Engine.GetGUIObjectByName("hostSTUNWrapper").hidden = !hasXmppClient; Engine.GetGUIObjectByName("hostPasswordWrapper").hidden = !hasXmppClient; if (hasXmppClient) { Engine.GetGUIObjectByName("hostPlayerName").caption = attribs.name; Engine.GetGUIObjectByName("hostServerName").caption = sprintf(translate("%(name)s's game"), { "name": attribs.name }); - - Engine.GetGUIObjectByName("useSTUN").checked = Engine.ConfigDB_GetValue("user", "lobby.stun.enabled") == "true"; } switchSetupPage("pageHost"); @@ -387,12 +384,10 @@ function startHost(playername, servername, port, password, loadSavedGame) return false; } - let useSTUN = Engine.HasXmppClient() && Engine.GetGUIObjectByName("useSTUN").checked; - try { Engine.StartNetworkHost(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), port, - useSTUN, password, loadSavedGame, true); + password, loadSavedGame, true); } catch (e) { diff --git a/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.xml b/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.xml index c1d56f93ed..201491646d 100644 --- a/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.xml +++ b/binaries/data/mods/public/gui/gamesetup_mp/gamesetup_mp.xml @@ -115,15 +115,6 @@ - - - - Engine.ConfigDB_CreateAndSaveValue("user", "lobby.stun.enabled", String(this.checked)); - - - Use STUN to work around firewalls - - diff --git a/source/lobby/StanzaExtensions.cpp b/source/lobby/StanzaExtensions.cpp index bc70084373..7ca0da2fcf 100644 --- a/source/lobby/StanzaExtensions.cpp +++ b/source/lobby/StanzaExtensions.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -298,9 +298,6 @@ ConnectionData::ConnectionData(const gloox::Tag* tag) const gloox::Tag* pip = tag->findTag("connectiondata/isLocalIP"); if (pip) m_IsLocalIP = pip->cdata(); - const gloox::Tag* s = tag->findTag("connectiondata/useSTUN"); - if (s) - m_UseSTUN = s->cdata(); const gloox::Tag* pw = tag->findTag("connectiondata/password"); if (pw) m_Password = pw->cdata(); @@ -335,8 +332,6 @@ gloox::Tag* ConnectionData::tag() const t->addChild(new gloox::Tag("port", m_Port)); if (!m_IsLocalIP.empty()) t->addChild(new gloox::Tag("isLocalIP", m_IsLocalIP)); - if (!m_UseSTUN.empty()) - t->addChild(new gloox::Tag("useSTUN", m_UseSTUN)); if (!m_Password.empty()) t->addChild(new gloox::Tag("password", m_Password)); if (!m_ClientSalt.empty()) diff --git a/source/lobby/StanzaExtensions.h b/source/lobby/StanzaExtensions.h index d22ce0d437..2a26c2610e 100644 --- a/source/lobby/StanzaExtensions.h +++ b/source/lobby/StanzaExtensions.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2021 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -61,7 +61,6 @@ public: std::string m_Ip; std::string m_Port; std::string m_IsLocalIP; - std::string m_UseSTUN; std::string m_Password; std::string m_ClientSalt; std::string m_Error; diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index 3773cdd6ee..7ca5abc5db 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -855,8 +855,8 @@ bool XmppClient::handleIq(const gloox::IQ& iq) return true; } - g_NetClient->SetupServerData(cd->m_Ip, stoi(cd->m_Port), !cd->m_UseSTUN.empty()); - g_NetClient->TryToConnect(iq.from().full(), !cd->m_IsLocalIP.empty()); + g_NetClient->SetupServerData(cd->m_Ip, stoi(cd->m_Port)); + g_NetClient->TryToConnectWithSTUN(iq.from().full(), !cd->m_IsLocalIP.empty()); } if (gq) { @@ -866,23 +866,6 @@ bool XmppClient::handleIq(const gloox::IQ& iq) return true; } - if (gq->m_Command == "register" && g_NetServer && !g_NetServer->GetUseSTUN()) - { - if (gq->m_GameList.empty()) - { - LOGWARNING("XmppClient: Received empty game list in response to Game Register"); - return true; - } - std::string publicIP = gq->m_GameList.front()->findAttribute("ip"); - if (publicIP.empty()) - { - LOGWARNING("XmppClient: Received game with no IP in response to Game Register"); - return true; - } - g_NetServer->SetConnectionData(publicIP, g_NetServer->GetPublicPort()); - return true; - } - for (const gloox::Tag* const& t : m_GameList) delete t; m_GameList.clear(); @@ -1006,7 +989,6 @@ bool XmppClient::handleIq(const gloox::IQ& iq) { connectionData->m_Ip = g_NetServer->GetPublicIp(); connectionData->m_Port = std::to_string(g_NetServer->GetPublicPort()); - connectionData->m_UseSTUN = g_NetServer->GetUseSTUN() ? "true" : ""; connectionData->m_IsLocalIP = ""; } else @@ -1016,7 +998,6 @@ bool XmppClient::handleIq(const gloox::IQ& iq) { connectionData->m_Ip = ip; connectionData->m_Port = std::to_string(g_NetServer->GetLocalPort()); - connectionData->m_UseSTUN = ""; connectionData->m_IsLocalIP = "true"; } else diff --git a/source/network/NetClient.cpp b/source/network/NetClient.cpp index 307b71098b..484a7bb4d1 100644 --- a/source/network/NetClient.cpp +++ b/source/network/NetClient.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -182,13 +182,12 @@ void CNetClient::SetupConnectionViaLobby() g_XmppClient->SendIqGetConnectionData(m_HostJID, m_Password, m_UserName.ToUTF8(), false); } -void CNetClient::SetupServerData(CStr address, u16 port, bool stun) +void CNetClient::SetupServerData(CStr address, u16 port) { ENSURE(!m_Session); m_ServerAddress = address; m_ServerPort = port; - m_UseSTUN = stun; } void CNetClient::HandleGetServerDataFailed(const CStr& error) @@ -203,8 +202,10 @@ void CNetClient::HandleGetServerDataFailed(const CStr& error) ); } -bool CNetClient::TryToConnect(const CStr& hostJID, bool localNetwork) +bool CNetClient::TryToConnectWithSTUN(const CStr& hostJID, bool localNetwork) { + ENSURE(g_XmppClient); + if (m_Session) return false; @@ -231,7 +232,7 @@ bool CNetClient::TryToConnect(const CStr& hostJID, bool localNetwork) CStr ip; u16 port = 0; - if (g_XmppClient && m_UseSTUN) + if (!localNetwork) { if (!StunClient::FindPublicIP(*enetClient, ip, port)) { @@ -252,7 +253,7 @@ bool CNetClient::TryToConnect(const CStr& hostJID, bool localNetwork) return true; } } - else if (g_XmppClient && localNetwork) + else { // We may need to punch a hole through the local firewall, so fetch our local IP. // NB: we'll ignore failures here, and hope that the firewall will be open to connection diff --git a/source/network/NetClient.h b/source/network/NetClient.h index ac5f27e77d..2f56bf321b 100644 --- a/source/network/NetClient.h +++ b/source/network/NetClient.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -116,7 +116,7 @@ public: * Set connection data to the remote networked server. * @param address IP address or host name to connect to */ - void SetupServerData(CStr address, u16 port, bool stun); + void SetupServerData(CStr address, u16 port); /** * Set up a connection to the remote networked server. @@ -136,7 +136,7 @@ public: * @param localNetwork - if true, assume we are trying to connect on the local network. * @return true on success, false on connection failure */ - bool TryToConnect(const CStr& hostJID, bool localNetwork); + bool TryToConnectWithSTUN(const CStr& hostJID, bool localNetwork); /** * Destroy the connection to the server. @@ -325,7 +325,6 @@ private: CStr m_HostJID; CStr m_ServerAddress; u16 m_ServerPort; - bool m_UseSTUN; /** * Password to join the game. diff --git a/source/network/NetServer.cpp b/source/network/NetServer.cpp index f3753c2481..37fe2c96f3 100644 --- a/source/network/NetServer.cpp +++ b/source/network/NetServer.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -1676,7 +1676,7 @@ void CNetServerWorker::SendHolePunchingMessage(const CStr& ipStr, u16 port) CNetServer::CNetServer(const bool continueSavedGame, const bool useLobbyAuth) : m_Worker{new CNetServerWorker{continueSavedGame, useLobbyAuth}}, - m_LobbyAuth(useLobbyAuth), m_UseSTUN(false), m_PublicIp(""), m_PublicPort(20595), m_Password() + m_LobbyAuth(useLobbyAuth), m_PublicIp(""), m_PublicPort(20595), m_Password() { } @@ -1685,11 +1685,6 @@ CNetServer::~CNetServer() delete m_Worker; } -bool CNetServer::GetUseSTUN() const -{ - return m_UseSTUN; -} - bool CNetServer::UseLobbyAuth() const { return m_LobbyAuth; @@ -1718,16 +1713,8 @@ u16 CNetServer::GetLocalPort() const return m_Worker->m_Host->address.port; } -void CNetServer::SetConnectionData(const CStr& ip, const u16 port) +bool CNetServer::SetConnectionData() { - m_PublicIp = ip; - m_PublicPort = port; - m_UseSTUN = false; -} - -bool CNetServer::SetConnectionDataViaSTUN() -{ - m_UseSTUN = true; std::lock_guard lock(m_Worker->m_WorkerMutex); if (!m_Worker->m_Host) return false; diff --git a/source/network/NetServer.h b/source/network/NetServer.h index f1c2bf2ae9..060d12a328 100644 --- a/source/network/NetServer.h +++ b/source/network/NetServer.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -144,10 +144,7 @@ public: void SendHolePunchingMessage(const CStr& ip, u16 port); - void SetConnectionData(const CStr& ip, u16 port); - bool SetConnectionDataViaSTUN(); - - bool GetUseSTUN() const; + bool SetConnectionData(); /** * Return the externally accessible IP. @@ -186,7 +183,6 @@ public: private: CNetServerWorker* m_Worker; const bool m_LobbyAuth; - bool m_UseSTUN; u16 m_PublicPort; CStr m_PublicIp; CStr m_Password; diff --git a/source/network/scripting/JSInterface_Network.cpp b/source/network/scripting/JSInterface_Network.cpp index ba5162521d..4438dbda2f 100644 --- a/source/network/scripting/JSInterface_Network.cpp +++ b/source/network/scripting/JSInterface_Network.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -65,7 +65,7 @@ bool HasNetClient() return !!g_NetClient; } -void StartNetworkHost(const ScriptRequest& rq, const CStrW& playerName, const u16 serverPort, bool useSTUN, +void StartNetworkHost(const ScriptRequest& rq, const CStrW& playerName, const u16 serverPort, const CStr& password, const bool continueSavedGame, bool storeReplay) { ENSURE(!g_NetClient); @@ -84,20 +84,12 @@ void StartNetworkHost(const ScriptRequest& rq, const CStrW& playerName, const u1 } // In lobby, we send our public ip and port on request to the players who want to connect. - // Thus we need to know our public IP. Use STUN if that's available, - // otherwise, the lobby's reponse to the game registration stanza will tell us our public IP. - if (hasLobby) + // Thus we need to know our public IP and use STUN to get it. + if (hasLobby && !g_NetServer->SetConnectionData()) { - if (!useSTUN) - // Don't store IP - the lobby bot will send it later. - // (if a client tries to connect before it's setup, they'll be disconnected) - g_NetServer->SetConnectionData("", serverPort); - else if (!g_NetServer->SetConnectionDataViaSTUN()) - { - ScriptException::Raise(rq, "Failed to host via STUN."); - SAFE_DELETE(g_NetServer); - return; - } + ScriptException::Raise(rq, "Failed to resolve public IP-address."); + SAFE_DELETE(g_NetServer); + return; } // Generate a secret to identify the host client. @@ -134,7 +126,7 @@ void StartNetworkHost(const ScriptRequest& rq, const CStrW& playerName, const u1 g_NetClient->SetGamePassword(hashedPass); } - g_NetClient->SetupServerData("127.0.0.1", serverPort, false); + g_NetClient->SetupServerData("127.0.0.1", serverPort); g_NetClient->SetControllerSecret(secret); if (!g_NetClient->SetupConnection(nullptr)) @@ -154,7 +146,7 @@ void StartNetworkJoin(const ScriptRequest& rq, const CStrW& playerName, const CS g_Game = new CGame(storeReplay); g_NetClient = new CNetClient(g_Game); g_NetClient->SetUserName(playerName); - g_NetClient->SetupServerData(serverAddress, serverPort, false); + g_NetClient->SetupServerData(serverAddress, serverPort); if (!g_NetClient->SetupConnection(nullptr)) { diff --git a/source/network/tests/test_Net.h b/source/network/tests/test_Net.h index 027231b72a..56e27797ae 100644 --- a/source/network/tests/test_Net.h +++ b/source/network/tests/test_Net.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -73,7 +73,7 @@ public: TS_ASSERT(server.SetupConnection(PS_DEFAULT_PORT)); for (CNetClient* client: clients) { - client->SetupServerData("127.0.0.1", PS_DEFAULT_PORT, false); + client->SetupServerData("127.0.0.1", PS_DEFAULT_PORT); TS_ASSERT(client->SetupConnection(nullptr)); } @@ -307,7 +307,7 @@ public: client2B.SetUserName(L"bob"); clients.push_back(&client2B); - client2B.SetupServerData("127.0.0.1", PS_DEFAULT_PORT, false); + client2B.SetupServerData("127.0.0.1", PS_DEFAULT_PORT); TS_ASSERT(client2B.SetupConnection(nullptr)); for (size_t i = 0; ; ++i)