mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-11-08 10:29:00 +00:00
Use XMPP Roster for BuddyList
This allows the same user to keep the buddy list across clients and config resets. At the same time this allows for per lobby buddy lists which is needed as the same nickname may refer to different people. Use lower case comparison for buddy names. This is in line with the idea of local part of jid should be seen as normalized nick and is used server-side to compare user names. The migration is kept simple. I.e. only attempted if the roster is empty and the config indicates no migration was done before. Fixes: #6824 Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
This commit is contained in:
16 files changed
+313
-65
No files matched your search
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2025 Wildfire Games.
|
||||
/* Copyright (C) 2026 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@@ -62,6 +62,8 @@
|
||||
#include <gloox/presence.h> // IWYU pragma: export
|
||||
#include <gloox/registration.h> // IWYU pragma: export
|
||||
#include <gloox/registrationhandler.h> // IWYU pragma: export
|
||||
#include <gloox/rosterlistener.h> // IWYU pragma: export
|
||||
#include <gloox/rostermanager.h> // IWYU pragma: export
|
||||
#include <gloox/stanzaextension.h> // IWYU pragma: export
|
||||
#include <gloox/tag.h> // IWYU pragma: export
|
||||
#include <gloox/util.h> // IWYU pragma: export
|
||||
|
||||
+186
-5
@@ -39,6 +39,7 @@
|
||||
#include "scriptinterface/Request.h"
|
||||
#include "scriptinterface/StructuredClone.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <ctime>
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
@@ -51,6 +52,7 @@
|
||||
#include <js/Vector.h>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <unicode/locid.h>
|
||||
@@ -60,6 +62,8 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr const char* ROSTER_GROUP_NAME_BUDDIES{"buddies"};
|
||||
|
||||
//debug
|
||||
#if 1
|
||||
#define DbgXMPP(x)
|
||||
@@ -129,7 +133,7 @@ std::optional<gloox::MUCRoom> CreateMucRoom(gloox::MUCRoomHandler* handler, cons
|
||||
|
||||
class XmppClient::Impl : public gloox::ConnectionListener, public gloox::MUCRoomHandler,
|
||||
public gloox::IqHandler, public gloox::RegistrationHandler, public gloox::MessageHandler,
|
||||
public gloox::Jingle::SessionHandler, public gloox::LogHandler
|
||||
public gloox::Jingle::SessionHandler, public gloox::LogHandler, public gloox::RosterListener
|
||||
{
|
||||
public:
|
||||
// Basic
|
||||
@@ -161,6 +165,7 @@ public:
|
||||
gloox::CertStatus m_certStatus;
|
||||
bool m_initialLoadComplete;
|
||||
bool m_regOpt;
|
||||
std::set<std::string> m_Buddies;
|
||||
|
||||
private:
|
||||
/* Xmpp handlers */
|
||||
@@ -216,6 +221,37 @@ private:
|
||||
void handleSessionInitiation(gloox::Jingle::Session* session,
|
||||
const gloox::Jingle::Session::Jingle* jingle);
|
||||
|
||||
/**
|
||||
* Rebuild m_Buddies from the roster.
|
||||
*/
|
||||
void UpdateBuddies();
|
||||
|
||||
/**
|
||||
* Move a pre-roster buddy list from the config into the roster, then drop
|
||||
* it from the config. Does nothing once that migration has happened.
|
||||
*
|
||||
* Must only be called once the roster has been received, since an empty
|
||||
* roster cannot be distinguished from one without buddies.
|
||||
*/
|
||||
void MigrateBuddyList();
|
||||
|
||||
/* Roster */
|
||||
void handleItemAdded(const gloox::JID& jid) override;
|
||||
void handleItemSubscribed(const gloox::JID& /*jid*/) override {}
|
||||
void handleItemRemoved(const gloox::JID& jid) override;
|
||||
void handleItemUpdated(const gloox::JID& jid) override;
|
||||
void handleItemUnsubscribed(const gloox::JID& /*jid*/) override {}
|
||||
void handleRoster(const gloox::Roster& /*roster*/) override;
|
||||
void handleRosterPresence(const gloox::RosterItem& /*item*/, const std::string& /*resource*/, gloox::Presence::PresenceType /*presence*/, const std::string& /*msg*/) override {}
|
||||
void handleSelfPresence(const gloox::RosterItem& /*item*/, const std::string& /*resource*/, gloox::Presence::PresenceType /*presence*/, const std::string& /*msg*/) override {}
|
||||
bool handleSubscriptionRequest(const gloox::JID& /*jid*/, const std::string& /*msg*/) override { return false; }
|
||||
bool handleUnsubscriptionRequest(const gloox::JID& /*jid*/, const std::string& /*msg*/) override { return false; }
|
||||
void handleNonrosterPresence(const gloox::Presence& /*presence*/) override {}
|
||||
void handleRosterError(const gloox::IQ& iq) override;
|
||||
#if GLOOXVERSION >= 0x010100
|
||||
void handleRosterItemExchange(const gloox::JID& /*from*/, const gloox::RosterX* /*items*/) override {}
|
||||
#endif
|
||||
|
||||
template<typename... Args>
|
||||
void CreateGUIMessage(
|
||||
const std::string& type,
|
||||
@@ -223,14 +259,16 @@ private:
|
||||
const std::time_t time,
|
||||
Args const&... args);
|
||||
|
||||
public:
|
||||
struct SPlayer {
|
||||
SPlayer(const gloox::Presence::PresenceType presence, const gloox::MUCRoomRole role,
|
||||
const std::string& rating)
|
||||
: m_Presence(presence), m_Role(role), m_Rating(rating)
|
||||
const std::string& bareJid, const std::string& rating)
|
||||
: m_Presence(presence), m_Role(role), m_BareJid(bareJid), m_Rating(rating)
|
||||
{
|
||||
}
|
||||
gloox::Presence::PresenceType m_Presence;
|
||||
gloox::MUCRoomRole m_Role;
|
||||
std::string m_BareJid;
|
||||
std::string m_Rating;
|
||||
};
|
||||
using PlayerMap = std::map<std::string, SPlayer>;
|
||||
@@ -335,6 +373,8 @@ XmppClient::Impl::Impl(const Script::Interface* scriptInterface, const std::stri
|
||||
|
||||
m_client.registerMessageHandler(this);
|
||||
|
||||
m_client.rosterManager()->registerRosterListener(this, false);
|
||||
|
||||
m_registration.registerRegistrationHandler(this);
|
||||
|
||||
// Uncomment to see the raw stanzas
|
||||
@@ -428,6 +468,7 @@ void XmppClient::Impl::onDisconnect(gloox::ConnectionError error)
|
||||
m_PlayerMap.clear();
|
||||
m_PlayerMapUpdate = true;
|
||||
m_HistoricGuiMessages.clear();
|
||||
m_Buddies.clear();
|
||||
m_initialLoadComplete = false;
|
||||
|
||||
CreateGUIMessage(
|
||||
@@ -1190,7 +1231,7 @@ void XmppClient::Impl::handleMUCParticipantPresence(gloox::MUCRoom*, const gloox
|
||||
m_PlayerMap.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(participant.newNick),
|
||||
std::forward_as_tuple(presence.presence(), participant.role, std::move(m_PlayerMap.at(nick).m_Rating)));
|
||||
std::forward_as_tuple(presence.presence(), participant.role, participant.jid ? participant.jid->bare() : "", std::move(m_PlayerMap.at(nick).m_Rating)));
|
||||
else
|
||||
LOGERROR("Nickname changed to an existing nick!");
|
||||
|
||||
@@ -1282,12 +1323,16 @@ void XmppClient::Impl::handleMUCParticipantPresence(gloox::MUCRoom*, const gloox
|
||||
m_PlayerMap.emplace(
|
||||
std::piecewise_construct,
|
||||
std::forward_as_tuple(nick),
|
||||
std::forward_as_tuple(presence.presence(), participant.role, std::string()));
|
||||
std::forward_as_tuple(presence.presence(), participant.role,
|
||||
participant.jid ? participant.jid->bare() : "",
|
||||
std::string()));
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.m_Presence = presence.presence();
|
||||
it->second.m_Role = participant.role;
|
||||
if (participant.jid)
|
||||
it->second.m_BareJid = participant.jid->bare();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1511,3 +1556,139 @@ void XmppClient::Impl::handleSessionInitiation(gloox::Jingle::Session*,
|
||||
|
||||
g_NetServer->SendHolePunchingMessage(candidate.ip, candidate.port);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// Roster
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
// TODO: Helper only needed till split view is supported by all compilers.
|
||||
std::vector<std::string> splitBuddyList(std::string buddyList)
|
||||
{
|
||||
std::vector<std::string> buddies{};
|
||||
size_t posStart{0};
|
||||
size_t posEnd{0};
|
||||
while ((posEnd = buddyList.find(",", posStart)) != std::string::npos)
|
||||
{
|
||||
buddies.push_back(buddyList.substr(posStart, posEnd - posStart));
|
||||
posStart = posEnd + 1;
|
||||
}
|
||||
buddies.push_back(buddyList.substr(posStart));
|
||||
return buddies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given roster item is one of the buddies tracked in the buddy list.
|
||||
*/
|
||||
bool IsBuddyRosterItem(const gloox::RosterItem& item)
|
||||
{
|
||||
const gloox::StringList groups = item.groups();
|
||||
return !item.name().empty() &&
|
||||
std::find(groups.begin(), groups.end(), ROSTER_GROUP_NAME_BUDDIES) != groups.end();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void XmppClient::AddBuddy(const std::string& nick)
|
||||
{
|
||||
DbgXMPP("Add buddy: " + nick);
|
||||
const auto it = m_Impl->m_PlayerMap.find(nick);
|
||||
|
||||
if (it == m_Impl->m_PlayerMap.end())
|
||||
LOGWARNING("XmppClient: Can't add unknown player to roster: {}", nick);
|
||||
else if (it->second.m_BareJid.empty())
|
||||
LOGWARNING("XmppClient: Anonymous player can't be added to roster: {}", nick);
|
||||
else
|
||||
m_Impl->m_client.rosterManager()->add(it->second.m_BareJid, nick, gloox::StringList{ROSTER_GROUP_NAME_BUDDIES});
|
||||
}
|
||||
|
||||
void XmppClient::RemoveBuddy(const std::string& nick)
|
||||
{
|
||||
DbgXMPP("Remove buddy: " + nick);
|
||||
const auto it = m_Impl->m_PlayerMap.find(nick);
|
||||
|
||||
if (it == m_Impl->m_PlayerMap.end())
|
||||
LOGWARNING("XmppClient: Can't remove unknown player from roster: {}", nick);
|
||||
else if (it->second.m_BareJid.empty())
|
||||
LOGWARNING("XmppClient: Anonymous player can't be removed from roster: {}", nick);
|
||||
else
|
||||
m_Impl->m_client.rosterManager()->remove(it->second.m_BareJid);
|
||||
}
|
||||
|
||||
bool XmppClient::IsBuddy(const std::string& nick) const
|
||||
{
|
||||
return m_Impl->m_Buddies.find(CStr(nick).LowerCase()) != m_Impl->m_Buddies.end();
|
||||
}
|
||||
|
||||
std::set<std::string> XmppClient::GetBuddies() const
|
||||
{
|
||||
return m_Impl->m_Buddies;
|
||||
}
|
||||
|
||||
void XmppClient::Impl::UpdateBuddies()
|
||||
{
|
||||
m_Buddies.clear();
|
||||
for (const auto& [jid, item] : *m_client.rosterManager()->roster())
|
||||
{
|
||||
if (IsBuddyRosterItem(*item))
|
||||
m_Buddies.insert(CStr(item->name()).LowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
void XmppClient::Impl::MigrateBuddyList()
|
||||
{
|
||||
if (g_ConfigDB.Get("lobby.buddies.migrated", false))
|
||||
return;
|
||||
|
||||
if (m_client.rosterManager()->roster()->empty())
|
||||
{
|
||||
const std::string buddyList{g_ConfigDB.Get("lobby.buddies", std::string{})};
|
||||
for (const std::string& nick : splitBuddyList(buddyList))
|
||||
{
|
||||
if (nick.empty())
|
||||
continue;
|
||||
|
||||
m_client.rosterManager()->add(nick + "@" + m_server, nick, gloox::StringList{ROSTER_GROUP_NAME_BUDDIES});
|
||||
}
|
||||
}
|
||||
|
||||
g_ConfigDB.RemoveValue(CFG_USER, "lobby.buddies");
|
||||
g_ConfigDB.SetValueString(CFG_USER, "lobby.buddies.migrated", "true");
|
||||
g_ConfigDB.WriteFile(CFG_USER);
|
||||
}
|
||||
|
||||
void XmppClient::Impl::handleRoster(const gloox::Roster& /*roster*/)
|
||||
{
|
||||
MigrateBuddyList();
|
||||
UpdateBuddies();
|
||||
CreateGUIMessage("roster", "change", std::time(nullptr));
|
||||
}
|
||||
|
||||
void XmppClient::Impl::handleItemAdded(const gloox::JID& /*jid*/)
|
||||
{
|
||||
UpdateBuddies();
|
||||
CreateGUIMessage("roster", "change", std::time(nullptr));
|
||||
}
|
||||
|
||||
void XmppClient::Impl::handleItemRemoved(const gloox::JID& jid)
|
||||
{
|
||||
// gloox (1.0.28) calles this before before updating the roster which means
|
||||
// calling UpdateBuddies here would still leave the removed buddy in
|
||||
// m_Buddies; drop just that entry instead.
|
||||
if (const gloox::RosterItem* item = m_client.rosterManager()->getRosterItem(jid); item && IsBuddyRosterItem(*item))
|
||||
m_Buddies.erase(CStr(item->name()).LowerCase());
|
||||
|
||||
CreateGUIMessage("roster", "change", std::time(nullptr));
|
||||
}
|
||||
|
||||
void XmppClient::Impl::handleItemUpdated(const gloox::JID& /*jid*/)
|
||||
{
|
||||
UpdateBuddies();
|
||||
CreateGUIMessage("roster", "change", std::time(nullptr));
|
||||
}
|
||||
|
||||
void XmppClient::Impl::handleRosterError(const gloox::IQ& iq)
|
||||
{
|
||||
LOGERROR("{}", iq.tag()->xml());
|
||||
}
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include <js/Value.h>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace Script { class Interface; }
|
||||
namespace Script { class Request; }
|
||||
@@ -69,6 +71,40 @@ public:
|
||||
void SendMUCMessage(const std::string& message);
|
||||
void SendStunEndpointToHost(const std::string& ip, std::uint16_t port, const std::string& hostJID);
|
||||
|
||||
/* Roster */
|
||||
|
||||
/**
|
||||
* Add the given nickname to the buddies of the current user.
|
||||
*
|
||||
* @param nick The nickname of a player in the lobby.
|
||||
*/
|
||||
void AddBuddy(const std::string& nick);
|
||||
|
||||
/**
|
||||
* Remove the given nickname from the buddies of the current user.
|
||||
*
|
||||
* @param nick The nickname of a player in the lobby.
|
||||
*/
|
||||
void RemoveBuddy(const std::string& nick);
|
||||
|
||||
/**
|
||||
* Whether the given nickname is a buddy of the current user.
|
||||
*
|
||||
* The buddies are stored in the XMPP roster of the connected lobby. Since
|
||||
* a nickname only identifies a user within one lobby, this is meaningless
|
||||
* without a connection and always returns false in that case.
|
||||
*
|
||||
* @param nick The nickname to look up, compared case-insensitively
|
||||
*/
|
||||
bool IsBuddy(const std::string& nick) const;
|
||||
|
||||
/**
|
||||
* Get the nicknames of all buddies of the current user.
|
||||
*
|
||||
* @returns The (lowercase) nicknames of the buddies in the lobby's roster
|
||||
*/
|
||||
std::set<std::string> GetBuddies() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
const std::unique_ptr<Impl> m_Impl;
|
||||
|
||||
@@ -51,6 +51,21 @@ bool HasXmppClient()
|
||||
return g_XmppClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the given nickname is a buddy of the current user.
|
||||
*
|
||||
* @param nick The nickname to look up, compared case-insensitively
|
||||
*/
|
||||
static bool IsLobbyBuddy([[maybe_unused]] const std::string& nick)
|
||||
{
|
||||
#if CONFIG2_LOBBY
|
||||
return g_XmppClient && g_XmppClient->IsBuddy(nick);
|
||||
#else
|
||||
// Without the lobby there is no roster to look the nickname up in.
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetRankedGame(bool isRanked)
|
||||
{
|
||||
g_rankedGame = isRanked;
|
||||
@@ -190,6 +205,7 @@ void RegisterScriptFunctions(const Script::Request& rq)
|
||||
{
|
||||
// Lobby functions
|
||||
Script::Function::Register<&HasXmppClient>(rq, "HasXmppClient");
|
||||
Script::Function::Register<&IsLobbyBuddy>(rq, "IsLobbyBuddy");
|
||||
Script::Function::Register<&SetRankedGame>(rq, "SetRankedGame");
|
||||
#if CONFIG2_LOBBY // Allow the lobby to be disabled
|
||||
Script::Function::Register<&StartXmppClient>(rq, "StartXmppClient");
|
||||
@@ -229,6 +245,10 @@ void RegisterScriptFunctions(const Script::Request& rq)
|
||||
REGISTER_XMPP(GetRole, "LobbyGetPlayerRole");
|
||||
REGISTER_XMPP(GetRating, "LobbyGetPlayerRating");
|
||||
REGISTER_XMPP(GetSubject, "LobbyGetRoomSubject");
|
||||
|
||||
// Roster
|
||||
REGISTER_XMPP(AddBuddy, "LobbyAddBuddy");
|
||||
REGISTER_XMPP(RemoveBuddy, "LobbyRemoveBuddy");
|
||||
#undef REGISTER_XMPP
|
||||
|
||||
Script::Function::Register<&EncryptPassword>(rq, "EncryptPassword");
|
||||
|
||||
@@ -118,9 +118,10 @@ static CStr DebugName(CNetServerSession* session)
|
||||
|
||||
CNetServerWorker::CNetServerWorker(const bool continueSavedGame, std::uint16_t port,
|
||||
const bool useLobbyAuth, std::string password, std::string controllerSecret,
|
||||
std::string initAttributes) :
|
||||
std::string initAttributes, std::set<std::string> buddies) :
|
||||
m_ContinuesSavedGame{continueSavedGame},
|
||||
m_LobbyAuth{useLobbyAuth},
|
||||
m_Buddies{std::move(buddies)},
|
||||
m_ControllerSecret{std::move(controllerSecret)},
|
||||
m_Password{std::move(password)}
|
||||
{
|
||||
@@ -1078,17 +1079,9 @@ bool CNetServerWorker::OnAuthenticate(CNetServerSession* session, CFsmEvent<CNet
|
||||
}
|
||||
else if (observerLateJoin == "buddies")
|
||||
{
|
||||
std::wstringstream buddiesStream(wstring_from_utf8(
|
||||
g_ConfigDB.Get("lobby.buddies", std::string{})));
|
||||
CStrW buddy;
|
||||
while (std::getline(buddiesStream, buddy, L','))
|
||||
{
|
||||
if (buddy == usernameWithoutRating)
|
||||
{
|
||||
isRejoining = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const std::string name{usernameWithoutRating.ToUTF8().LowerCase()};
|
||||
if (server.m_Buddies.count(name) > 0)
|
||||
isRejoining = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1695,9 +1688,10 @@ void CNetServerWorker::SendHolePunchingMessage(const CStr& ipStr, std::uint16_t
|
||||
|
||||
|
||||
CNetServer::CNetServer(const bool continueSavedGame, std::uint16_t port, const bool useLobbyAuth,
|
||||
std::string password, std::string controllerSecret, std::string initAttributes) :
|
||||
std::string password, std::string controllerSecret, std::string initAttributes,
|
||||
std::set<std::string> buddies) :
|
||||
m_Worker{continueSavedGame, port, useLobbyAuth, password, std::move(controllerSecret),
|
||||
std::move(initAttributes)},
|
||||
std::move(initAttributes), std::move(buddies)},
|
||||
m_LobbyAuth{useLobbyAuth},
|
||||
m_Password{std::move(password)}
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <js/Value.h>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
@@ -135,7 +136,8 @@ private:
|
||||
friend class CNetServer;
|
||||
|
||||
CNetServerWorker(const bool continuesSavedGame, std::uint16_t port, const bool useLobbyAuth,
|
||||
std::string password, std::string controllerSecret, std::string initAttributes);
|
||||
std::string password, std::string controllerSecret, std::string initAttributes,
|
||||
std::set<std::string> buddies);
|
||||
~CNetServerWorker();
|
||||
|
||||
bool CheckPassword(const std::string& password, const std::string& salt) const;
|
||||
@@ -262,6 +264,13 @@ private:
|
||||
*/
|
||||
const bool m_LobbyAuth;
|
||||
|
||||
/**
|
||||
* The nicknames (lowercase) of the host's buddies at the time the game was
|
||||
* hosted, used to decide who may join after the game has started
|
||||
* (lateobserver authentication).
|
||||
*/
|
||||
const std::set<std::string> m_Buddies;
|
||||
|
||||
std::unique_ptr<ENetHost, DestroyHost> m_Host;
|
||||
std::vector<std::unique_ptr<CNetServerSession>> m_Sessions;
|
||||
|
||||
@@ -356,7 +365,8 @@ class CNetServer
|
||||
NONCOPYABLE(CNetServer);
|
||||
public:
|
||||
CNetServer(const bool isSavedGame, std::uint16_t port, const bool useLobbyAuth = false,
|
||||
std::string password = {}, std::string controllerSecret = {}, std::string initAttributes = {});
|
||||
std::string password = {}, std::string controllerSecret = {}, std::string initAttributes = {},
|
||||
std::set<std::string> buddies = {});
|
||||
|
||||
/**
|
||||
* Call from the GUI to asynchronously notify all clients that they should start loading the game.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "JSInterface_Network.h"
|
||||
|
||||
#include "lib/code_generation.h"
|
||||
#include "lib/config2.h"
|
||||
#include "lib/debug.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "lobby/XmppClient.h"
|
||||
@@ -45,6 +46,7 @@
|
||||
#include <js/TypeDecls.h>
|
||||
#include <js/Value.h>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
@@ -109,7 +111,18 @@ void StartNetworkHost(const CStrW& playerName, const std::uint16_t serverPort, c
|
||||
HashCryptographically(password, hostJID + password + PS_SERIALIZATION_VERSION) : "";
|
||||
|
||||
const std::string secret = ps_generate_guid();
|
||||
g_NetServer = new CNetServer(continueSavedGame, serverPort, hasLobby, hashedPassword, secret);
|
||||
|
||||
// Snapshot the host's buddies from the roster of the lobby they are
|
||||
// connected to. Hosting without a lobby means there is no roster, so
|
||||
// nobody is a buddy.
|
||||
std::set<std::string> buddies;
|
||||
#if CONFIG2_LOBBY
|
||||
if (hasLobby)
|
||||
buddies = g_XmppClient->GetBuddies();
|
||||
#endif
|
||||
|
||||
g_NetServer = new CNetServer(continueSavedGame, serverPort, hasLobby, hashedPassword, secret,
|
||||
{}, buddies);
|
||||
|
||||
// Generate a secret to identify the host client.
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ void TriggerAllHooks(const std::multimap<CStr, std::function<void()>>& hooks, co
|
||||
// These entries will not be printed to logfiles, so that logfiles can be shared without leaking personal or sensitive data
|
||||
const std::unordered_set<std::string> g_UnloggedEntries = {
|
||||
"lobby.password",
|
||||
"lobby.buddies",
|
||||
"lobby.buddies", // The buddy list of older versions, now stored in the server roster and removed on migration.
|
||||
"userreport.id" // authentication token for GDPR personal data requests
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user