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

@@ -1,4 +1,6 @@
#include "ChatPacketHandler.h"
#include "ChatGuilds.h"
#include "GuildManager.h"
#include "PlayerContainer.h"
#include "Database.h"
#include <ctime>
@@ -470,6 +472,17 @@ void ChatPacketHandler::HandleChatMessage(const ChatPackets::GeneralChatMessage&
}
break;
}
case eChatChannel::GUILD: {
// Sent by the world for /g, which is what the client's guild chat tab sends
const auto members = ChatGuilds::Get().OnlineGuildmates(playerID);
if (members.empty()) return;
LogChat(sender, "guild", message.GetAsString());
for (const auto memberId : members) {
const auto& member = Game::playerContainer.GetPlayerData(memberId);
if (member) SendPrivateChatMessage(sender, member, member, message, eChatChannel::GUILD, eChatMessageResponseCode::SENT);
}
break;
}
default:
LOG("Unhandled Chat channel [%s]", StringifiedEnum::ToString(channel).data());
break;