From 4bdaeb8d3c9c61174080b8860dce46a072e807ab Mon Sep 17 00:00:00 2001 From: Aaron Kimbrell Date: Tue, 29 Sep 2026 06:17:43 -0500 Subject: [PATCH] docs: how DLU does guilds; guild commands and the Guilds page docs/Guilds.md gains what DLU does with the client's guild system: the chat server as the authority, the world <-> chat packets, the rank rules, the invite and name rules, the slash commands, the dashboard page and what is not done (a member's name change reaches guildmates only with the next GUILD_DATA; reputation is 0). docs/Commands.md lists the guild commands, docs/Dashboard.md the Guilds page, the guild names in the Review Queue and guild chat under chat_private. Check: nothing in game (documentation only). Co-Authored-By: Claude Opus 5.5 --- docs/Commands.md | 13 +++++++++++++ docs/Dashboard.md | 9 +++++++-- docs/Guilds.md | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/docs/Commands.md b/docs/Commands.md index 2800fb251..43ba78596 100644 --- a/docs/Commands.md +++ b/docs/Commands.md @@ -56,6 +56,19 @@ These commands are registered by the server so they appear in help, but their be |team|`/team `|Send a message to your teammates. Aliases: `/t`.|0| |tell|`/tell `|Send a private message to another player. Aliases: `/w`, `/whisper`.|0| +### Guilds + +The client has no guild commands (docs/Guilds.md); these are the server's. Its guild chat tab sends `/g`. + +|Command|Usage|Description|Admin Level Requirement| +|--- |--- |--- |--- | +|g|`/g `|Send a message to your guild. Aliases: `/guild`.|0| +|guildcreate|`/guildcreate`|Open the window to create a guild. Aliases: `/createguild`.|0| +|gkick|`/gkick `|Remove a player from your guild: the leader can remove anyone, officers veterans and recruits. Aliases: `/guildkick`.|0| +|grank|`/grank `|Set a guild member's rank. The leader sets any rank; officers move members between veteran and recruit. Aliases: `/guildrank`.|0| +|gleader|`/gleader `|Make another member the guild's leader; you become an officer. Aliases: `/guildleader`.|0| +|gdisband|`/gdisband confirm`|The leader removes every member and the guild itself. Aliases: `/guilddisband`.|0| + ### Actions |Command|Usage|Description|Admin Level Requirement| diff --git a/docs/Dashboard.md b/docs/Dashboard.md index 4ff1d5477..f0ad938c7 100644 --- a/docs/Dashboard.md +++ b/docs/Dashboard.md @@ -60,8 +60,8 @@ What people can do depends on their account's GM level. Out of the box: | 2+ | Kick and mute; read and write the moderation history; read player reports | | 3+ | Approve names; handle player reports and bug reports; give strikes; see linked accounts, mailboxes, character history and who is online; rescue, teleport and restrict characters; read the chat log; send mail; economy reports and the world map | | 4+ | Ban and lock accounts; email password reset links | -| 5+ | Moderate pet names, properties and leaderboards; revoke strikes; change a character's missions; change the chat filter's words; send and schedule announcements | -| 8+ | Manage accounts (create, change email or password, reset two-factor login) and GM levels; edit characters and replace their XML; give items back; read whispers and team chat; send chat into the game; attach items to mail, to one player or everyone; import models; shut down worlds; schedule restarts and events; run economy checks; play keys, client files and the vanity files; see scheduled tasks, the audit log, server logs, crash dumps, server health and instance load; the developer tools | +| 5+ | Moderate pet names, guilds, properties and leaderboards; revoke strikes; change a character's missions; change the chat filter's words; send and schedule announcements | +| 8+ | Manage accounts (create, change email or password, reset two-factor login) and GM levels; edit characters and replace their XML; give items back; read whispers, team and guild chat; send chat into the game; attach items to mail, to one player or everyone; import models; shut down worlds; schedule restarts and events; run economy checks; play keys, client files and the vanity files; see scheduled tasks, the audit log, server logs, crash dumps, server health and instance load; the developer tools | | 9 | Delete accounts; grant permissions to single accounts and characters; change scheduled tasks, instance limits, settings and permissions (these two are always GM 9 only), webhooks and email settings; backups | Each of these is a named permission, and you can change the lowest GM level allowed for any of them without rebuilding @@ -894,6 +894,11 @@ tells the player in game if they're online. Rejecting asks for an optional reaso account page next to what they asked for. The queues show only what the game itself would still review: rejected properties and names whose player must pick a new one no longer appear. +Guild names the chat filter doesn't allow wait there too (`guilds_manage`, GM 5+). The **Guilds** page (Moderation) +lists every guild with its members and history; staff approve or reject a pending name (a rejected guild becomes +"Guild "), rename a guild, remove a member or disband a guild. Online members see the change at once (the chat +server is told through master). See docs/Guilds.md. + Pet names show what kind of pet each one is (its icon and name from the CDClient), from the pet's LOT that the game stores with the name (`pet_names.pet_lot`). Names set before that column existed get their LOT the next time the pet's owner loads into a world; until then they show as Unknown. diff --git a/docs/Guilds.md b/docs/Guilds.md index 9e23f5367..eadad4c18 100644 --- a/docs/Guilds.md +++ b/docs/Guilds.md @@ -160,3 +160,38 @@ routes 10 to the guild tab [G][F]. Channel 11 has no UI box [F]. `MSG_GUILD_*` (41 ids) and `UI_GUILD_*`, `UI_GUILDCREATE_*`, `UI_CHAT_CHGUILD`, `UI_CHAT_GUILD_CHAT` in `locale.xml`. No cdclient table is about guilds (besides `FeatureGating`, which lacks the row). + +## DLU implementation + +- **The chat server is the guild authority** (`dChatServer/GuildManager`, connected in `ChatGuilds`): create, invite, + answer, leave, kick, ranks, disband, online status, guild chat. State is in the database (`guilds`, `guild_members`, + `guild_invites`, `guild_events`; MySQL migration 97, SQLite 80); client packets go to members through their worlds + (`WorldRoutePacket`). +- World → chat: `GUILD_CREATE` (from the client's `TMP_GUILD_CREATE`), `GUILD_KICK`, `GUILD_SET_RANK` and + `GUILD_DISBAND` (DLU ids appended to `MessageType::Chat`), guild chat as `GENERAL_CHAT_MESSAGE` channel 10. Chat → world: + `GUILD_GET_STATUS` with a character's guild id and the name others may see; the world puts it in the character + component. The character component reads the guild from the database when the character loads. +- Ranks: leader and officers invite; the leader kicks anyone, officers kick veterans and recruits; the leader sets any + rank, officers move members between veteran and recruit. New members are recruits. A leader who leaves hands the + guild to the highest-ranked, longest-serving member; the last member out ends it. A guild whose leader's character was + deleted gets the next member as leader. Rank changes send every online member `GUILD_DATA` again. +- A new member's inviter gets `GUILD_INVITE_FINAL_RESPONSE` joined and the list again; the other online members get + `GUILD_ADD_PLAYER` (both would print "has joined" for the inviter). Disbanding sends each online member a + `GUILD_REMOVE_PLAYER` about themselves, which makes their client drop the guild. +- One pending invite per character, answerable for `guild_invite_timeout` seconds (600) and dropped when the character + logs off. `guild_max_members` (100) per guild. Both in chatconfig.ini. +- Names: `GuildNameRules` (3-30 of letters, digits, space ' - ., no space at either end or twice; surrounding spaces the + player typed are dropped); unique without regard to case; the chat filter's deny list refuses a name (`BAD_NAME`); a + name the allow list doesn't cover makes the guild but waits for moderation, and until it is approved other players see + no guild name (members see it in the guild window). +- `GUILD_DATA` dates are `MM/DD/YYYY` (UTC): the member's join date and the guild's creation date. +- Slash commands (the client has none for guilds): `/g` or `/guild ` (what the guild chat tab sends; chat filter + and mute as zone chat), `/guildcreate` (opens the create box), `/gkick `, `/grank + `, `/gleader `, `/gdisband confirm`. The Guild Master script (LOT 3001) opens the + create box when used. +- Dashboard: **Guilds** page (`guilds_manage`): list, members, history, approve or reject a name (rejected: renamed + "Guild "), rename, remove a member, disband; pending names also in the Review Queue. Changes are audited, added to + the guild's history, and sent to the chat server (`ePlayerAction::GUILD_CHANGED` through master), which tells online + members. Guild chat is logged as channel "guild" and is private chat (`chat_private`). +- Not done: the client has no packet for a member's name change (`GuildUpdatePlayerName` is local), so a renamed + character shows under the new name after the members' next `GUILD_DATA`; the guild reputation field is always 0.