diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp
index 03cccac34c..523d2b6628 100644
--- a/source/graphics/GameView.cpp
+++ b/source/graphics/GameView.cpp
@@ -36,7 +36,7 @@
#include "lib/external_libraries/libsdl.h"
#include "lib/input.h"
#include "lib/posix/posix_types.h"
-#include "lobby/IXmppClient.h"
+#include "lobby/XmppClient.h"
#include "maths/BoundingBoxAligned.h"
#include "maths/Frustum.h"
#include "maths/Vector3D.h"
diff --git a/source/lobby/Globals.cpp b/source/lobby/Globals.cpp
index 6b9a26985d..1ba96bba76 100644
--- a/source/lobby/Globals.cpp
+++ b/source/lobby/Globals.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2025 Wildfire Games.
+/* Copyright (C) 2026 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -17,7 +17,7 @@
#include "precompiled.h"
-#include "IXmppClient.h"
+#include "XmppClient.h"
-IXmppClient *g_XmppClient = nullptr;
+XmppClient *g_XmppClient = nullptr;
bool g_rankedGame = false;
diff --git a/source/lobby/IXmppClient.h b/source/lobby/IXmppClient.h
deleted file mode 100644
index 7f6eeaec0f..0000000000
--- a/source/lobby/IXmppClient.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* 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
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D. If not, see .
- */
-
-#ifndef IXMPPCLIENT_H
-#define IXMPPCLIENT_H
-
-#include "lib/types.h"
-
-#include
-
-class ScriptInterface;
-class ScriptRequest;
-
-class IXmppClient
-{
-public:
- static IXmppClient* create(const ScriptInterface* scriptInterface, const std::string& sUsername, const std::string& sPassword, const std::string& sRoom, const std::string& sNick, const int historyRequestSize = 0, bool regOpt = false);
- virtual ~IXmppClient() {}
-
- virtual void connect() = 0;
- virtual void disconnect() = 0;
- virtual bool isConnected() = 0;
- virtual void recv() = 0;
- virtual void SendIqGetBoardList() = 0;
- virtual void SendIqGetProfile(const std::string& player) = 0;
- virtual void SendIqGameReport(const ScriptRequest& rq, JS::HandleValue data) = 0;
- virtual void SendIqRegisterGame(const ScriptRequest& rq, JS::HandleValue data) = 0;
- virtual void SendIqGetConnectionData(const std::string& jid, const std::string& password, const std::string& clientSalt, bool localIP) = 0;
- virtual void SendIqUnregisterGame() = 0;
- virtual void SendIqChangeStateGame(const std::string& nbp, const std::string& players) = 0;
- virtual void SendIqLobbyAuth(const std::string& to, const std::string& token) = 0;
- virtual void SetNick(const std::string& nick) = 0;
- virtual std::string GetNick() const = 0;
- virtual std::string GetJID() = 0;
- virtual std::string GetUsername() const = 0;
- virtual void ChangePassword(const std::string& newPassword) = 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;
- virtual const char* GetPresence(const std::string& nickname) = 0;
- virtual const char* GetRole(const std::string& nickname) = 0;
- virtual std::wstring GetRating(const std::string& nickname) = 0;
- virtual const std::wstring& GetSubject() = 0;
- virtual JS::Value GUIGetPlayerList(const ScriptRequest& rq) = 0;
- virtual JS::Value GUIGetGameList(const ScriptRequest& rq) = 0;
- virtual JS::Value GUIGetBoardList(const ScriptRequest& rq) = 0;
- virtual JS::Value GUIGetProfile(const ScriptRequest& rq) = 0;
-
- virtual JS::Value GuiPollNewMessages(const ScriptInterface& guiInterface) = 0;
- virtual JS::Value GuiPollHistoricMessages(const ScriptInterface& guiInterface) = 0;
- virtual bool GuiPollHasPlayerListUpdate() = 0;
-
- virtual void SendMUCMessage(const std::string& message) = 0;
- virtual void SendStunEndpointToHost(const std::string& ip, u16 port, const std::string& hostJID) = 0;
-};
-
-extern IXmppClient *g_XmppClient;
-extern bool g_rankedGame;
-
-#endif // XMPPCLIENT_H
diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp
index b53cb5a597..e69ec30da4 100644
--- a/source/lobby/XmppClient.cpp
+++ b/source/lobby/XmppClient.cpp
@@ -21,10 +21,11 @@
#include "StanzaExtensions.h"
#include "i18n/L10n.h"
+#include "lib/code_annotation.h"
#include "lib/external_libraries/gloox.h"
+#include "lib/types.h"
#include "lib/utf8.h"
#include "lobby/GlooxConversion.h"
-#include "lobby/IXmppClient.h"
#include "network/NetClient.h"
#include "network/NetServer.h"
#include "network/StunClient.h"
@@ -39,14 +40,24 @@
#include "scriptinterface/ScriptRequest.h"
#include "scriptinterface/StructuredClone.h"
+#include
+#include
#include
+#include
#include
#include
-#include
+#include
+#include
+#include
+#include
+#include