/* 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 * 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 . */ #include "precompiled.h" #include "lib/config2.h" #if CONFIG2_LOBBY #include "GlooxConversion.h" #include "i18n/L10n.h" #include "ps/CLogger.h" const char* GetPresenceString(const gloox::Presence::PresenceType presenceType) { switch (presenceType) { #define CASE(X,Y) case gloox::Presence::X: return Y CASE(Available, "available"); CASE(Chat, "chat"); CASE(Away, "away"); CASE(DND, "playing"); CASE(XA, "away"); CASE(Unavailable, "offline"); CASE(Probe, "probe"); CASE(Error, "error"); CASE(Invalid, "invalid"); default: LOGERROR("Unknown presence type '%d'", static_cast(presenceType)); return ""; #undef CASE } } const char* GetRoleString(const gloox::MUCRoomRole role) { switch (role) { #define CASE(X, Y) case gloox::X: return Y CASE(RoleNone, "none"); CASE(RoleVisitor, "visitor"); CASE(RoleParticipant, "participant"); CASE(RoleModerator, "moderator"); CASE(RoleInvalid, "invalid"); default: LOGERROR("Unknown role type '%d'", static_cast(role)); return ""; #undef CASE } } std::string StanzaErrorToString(gloox::StanzaError err) { #define CASE(X, Y) case gloox::X: return Y #define DEBUG_CASE(X, Y) case gloox::X: return g_L10n.Translate("Error") + " (" + Y + ")" switch (err) { CASE(StanzaErrorUndefined, g_L10n.Translate("No error")); DEBUG_CASE(StanzaErrorBadRequest, "Server received malformed XML"); CASE(StanzaErrorConflict, g_L10n.Translate("Player already logged in")); DEBUG_CASE(StanzaErrorFeatureNotImplemented, "Server does not implement requested feature"); CASE(StanzaErrorForbidden, g_L10n.Translate("Forbidden")); DEBUG_CASE(StanzaErrorGone, "Unable to find message receipiant"); CASE(StanzaErrorInternalServerError, g_L10n.Translate("Internal server error")); DEBUG_CASE(StanzaErrorItemNotFound, "Message receipiant does not exist"); DEBUG_CASE(StanzaErrorJidMalformed, "JID (XMPP address) malformed"); DEBUG_CASE(StanzaErrorNotAcceptable, "Receipiant refused message. Possible policy issue"); CASE(StanzaErrorNotAllowed, g_L10n.Translate("Not allowed")); CASE(StanzaErrorNotAuthorized, g_L10n.Translate("Not authorized")); DEBUG_CASE(StanzaErrorNotModified, "Requested item has not changed since last request"); DEBUG_CASE(StanzaErrorPaymentRequired, "This server requires payment"); CASE(StanzaErrorRecipientUnavailable, g_L10n.Translate("Recipient temporarily unavailable")); DEBUG_CASE(StanzaErrorRedirect, "Request redirected"); CASE(StanzaErrorRegistrationRequired, g_L10n.Translate("Registration required")); DEBUG_CASE(StanzaErrorRemoteServerNotFound, "Remote server not found"); DEBUG_CASE(StanzaErrorRemoteServerTimeout, "Remote server timed out"); DEBUG_CASE(StanzaErrorResourceConstraint, "The recipient is unable to process the message due to resource constraints"); CASE(StanzaErrorServiceUnavailable, g_L10n.Translate("Service unavailable")); DEBUG_CASE(StanzaErrorSubscribtionRequired, "Service requires subscription"); DEBUG_CASE(StanzaErrorUnexpectedRequest, "Attempt to send from invalid stanza address"); DEBUG_CASE(StanzaErrorUnknownSender, "Invalid 'from' address"); default: return g_L10n.Translate("Unknown error"); } #undef DEBUG_CASE #undef CASE } std::string ConnectionErrorToString(gloox::ConnectionError err) { #define CASE(X, Y) case gloox::X: return Y #define DEBUG_CASE(X, Y) case gloox::X: return g_L10n.Translate("Error") + " (" + Y + ")" switch (err) { CASE(ConnNoError, g_L10n.Translate("No error")); CASE(ConnStreamError, g_L10n.Translate("Stream error")); CASE(ConnStreamVersionError, g_L10n.Translate("The incoming stream version is unsupported")); CASE(ConnStreamClosed, g_L10n.Translate("The stream has been closed by the server")); DEBUG_CASE(ConnProxyAuthRequired, "The HTTP/SOCKS5 proxy requires authentication"); DEBUG_CASE(ConnProxyAuthFailed, "HTTP/SOCKS5 proxy authentication failed"); DEBUG_CASE(ConnProxyNoSupportedAuth, "The HTTP/SOCKS5 proxy requires an unsupported authentication mechanism"); CASE(ConnIoError, g_L10n.Translate("An I/O error occurred")); DEBUG_CASE(ConnParseError, "An XML parse error occurred"); CASE(ConnConnectionRefused, g_L10n.Translate("The connection was refused by the server")); CASE(ConnDnsError, g_L10n.Translate("Resolving the server's hostname failed")); CASE(ConnOutOfMemory, g_L10n.Translate("This system is out of memory")); DEBUG_CASE(ConnNoSupportedAuth, "The authentication mechanisms the server offered are not supported " "or no authentication mechanisms were available"); CASE(ConnTlsFailed, g_L10n.Translate("The server's certificate could not be verified or the TLS " "handshake did not complete successfully")); CASE(ConnTlsNotAvailable, g_L10n.Translate("The server did not offer required TLS encryption")); DEBUG_CASE(ConnCompressionFailed, "Negotiation/initializing compression failed"); CASE(ConnAuthenticationFailed, g_L10n.Translate("Authentication failed. Incorrect password or account does not exist")); CASE(ConnUserDisconnected, g_L10n.Translate("The user or system requested a disconnect")); CASE(ConnNotConnected, g_L10n.Translate("There is no active connection")); default: return g_L10n.Translate("Unknown error"); } #undef DEBUG_CASE #undef CASE } std::string RegistrationResultToString(gloox::RegistrationResult res) { #define CASE(X, Y) case gloox::X: return Y #define DEBUG_CASE(X, Y) case gloox::X: return g_L10n.Translate("Error") + " (" + Y + ")" switch (res) { CASE(RegistrationSuccess, g_L10n.Translate("Your account has been successfully registered")); CASE(RegistrationNotAcceptable, g_L10n.Translate("Not all necessary information provided")); CASE(RegistrationConflict, g_L10n.Translate("Username already exists")); DEBUG_CASE(RegistrationNotAuthorized, "Account removal timeout or insufficiently secure channel for password change"); DEBUG_CASE(RegistrationBadRequest, "Server received an incomplete request"); DEBUG_CASE(RegistrationForbidden, "Registration forbidden"); DEBUG_CASE(RegistrationRequired, "Account cannot be removed as it does not exist"); DEBUG_CASE(RegistrationUnexpectedRequest, "This client is unregistered with the server"); DEBUG_CASE(RegistrationNotAllowed, "Server does not permit password changes"); default: return ""; } #undef DEBUG_CASE #undef CASE } std::string CertificateErrorToString(gloox::CertStatus status) { std::map certificateErrorStrings = { { gloox::CertInvalid, g_L10n.Translate("The certificate is not trusted.") }, { gloox::CertSignerUnknown, g_L10n.Translate("The certificate hasn't got a known issuer.") }, { gloox::CertRevoked, g_L10n.Translate("The certificate has been revoked.") }, { gloox::CertExpired, g_L10n.Translate("The certificate has expired.") }, { gloox::CertNotActive, g_L10n.Translate("The certificate is not yet active.") }, { gloox::CertWrongPeer, g_L10n.Translate("The certificate has not been issued for the peer connected to.") }, { gloox::CertSignerNotCa, g_L10n.Translate("The certificate signer is not a certificate authority.") } }; std::string result; for (std::map::iterator it = certificateErrorStrings.begin(); it != certificateErrorStrings.end(); ++it) { if (status & it->first) result += "\n" + it->second; } return result; } #endif // CONFIG2_LOBBY