feat(chat): the chat server handles guilds

Connects GuildManager to the chat server (ChatGuilds): the client's GUILD_INVITE, GUILD_INVITE_RESPONSE, GUILD_LEAVE
and GUILD_GET_ALL (routed through its world), the worlds' GUILD_CREATE, GUILD_KICK, GUILD_SET_RANK and GUILD_DISBAND,
guild chat (GENERAL_CHAT_MESSAGE in channel 10, sent to the online members as channel 10 private chat, which the
client's guild tab shows, and logged as "guild"), guildmates told when a member logs in, out or changes worlds, and a
member's pending invite dropped when they log off. Client packets go through the member's world as WorldRoutePacket;
GUILD_GET_STATUS goes to the world itself.

Guild names: the chat filter's deny list refuses a name (dChatFilter::HasDenyList, since without a deny list the deny
check refuses everything); a name the allow list doesn't cover waits for moderation, as pet names do.

The dashboard's new player action GUILD_CHANGED goes from master to the chat server only (answered 1 when chat is
connected), which catches online members up. chatconfig.ini: guild_max_members (100) and guild_invite_timeout (600
seconds).

Check in game: nothing yet on its own (the world side makes guilds reachable). Server log: the chat server starts and
logs no unhandled guild packets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-29 05:56:57 -05:00
parent e49c22374b
commit d1eec7dacb
12 changed files with 155 additions and 0 deletions

View File

@@ -14,6 +14,8 @@
#include "MessageType/Chat.h"
#include "ChatWeb.h"
#include "TeamContainer.h"
#include "ChatGuilds.h"
#include "GuildManager.h"
void PlayerContainer::Initialize() {
m_MaxNumberOfBestFriends =
@@ -52,6 +54,8 @@ void PlayerContainer::InsertPlayer(const ChatPackets::LoginSessionNotify& notify
ChatPacketHandler::LoadFriends(data);
m_PlayersToRemove.erase(playerId);
LOG("Took over user: %s (%llu), zone: %i", data.playerName.c_str(), data.playerID, data.zoneID.GetMapID());
// Guildmates' clients only get the zone again (no "logged in" line)
ChatGuilds::Get().PlayerOnline(playerId, false);
return;
}
@@ -75,6 +79,7 @@ void PlayerContainer::InsertPlayer(const ChatPackets::LoginSessionNotify& notify
Database::Get()->UpdateActivityLog(data.playerID, isLogin ? eActivityType::PlayerLoggedIn : eActivityType::PlayerChangedZone, data.zoneID.GetMapID());
m_PlayersToRemove.erase(playerId);
ChatGuilds::Get().PlayerOnline(playerId, isLogin);
}
void PlayerContainer::ScheduleRemovePlayer(const ChatPackets::UnexpectedDisconnect& notify, const SystemAddress& sysAddr) {
@@ -117,6 +122,8 @@ void PlayerContainer::RemovePlayer(const LWOOBJID playerID) {
TeamContainer::RemoveMember(team, playerID, false, false, true);
}
ChatGuilds::Get().PlayerOffline(playerID);
ChatWeb::SendWSPlayerUpdate(player, eActivityType::PlayerLoggedOut);
m_PlayerCount--;