mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-21 12:12:48 +00:00
feat(chat): GuildManager, the guild rules of the chat server
The chat server is the guild authority (docs/Guilds.md). GuildManager keeps guilds in the database (IGuilds) and tells clients through their worlds, with every outside dependency behind hooks so the rules are tested without a server: - Create: name rules (3-30 of letters, digits, space ' - ., no space at either end or twice), the chat filter's deny list refuses a name (BAD_NAME), names not on the allow list make the guild but wait for moderation (other players see no guild name until then), a taken name (case ignored) is EXISTS, someone in a guild can't make one. - Invite / answer: leaders and officers invite; the client's answers for not online, already in a guild, invite pending and could not invite; one invite per player, answerable for 10 minutes and gone when the player logs off; a full guild (guild_max_members) takes nobody. The new member is a recruit; the inviter hears the answer and gets the list again, the other members get GUILD_ADD_PLAYER. - Leave, and DLU's kick, rank and disband (the client has no controls for them): the leader kicks anyone, officers kick veterans and recruits; a leader who leaves hands the guild to the highest-ranked, longest-serving member, and the last one out ends it. Rank changes send everyone the list again (the client's GuildSetPlayerRank does nothing). - GUILD_DATA for GUILD_GET_ALL, login/logout/world-change updates to guildmates, a guild that lost its leader (character deleted) gets one again, and GuildChanged catches online players up with what the dashboard did. - Every change is a guild_events row. Each character's world gets GUILD_GET_STATUS with the guild and the name others may see. Not connected to the chat server's packets yet. Check: GuildManagerTests (18 tests) run every rule against an in-memory IGuilds. Nothing to check in game yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
27
dCommon/GuildNameRules.h
Normal file
27
dCommon/GuildNameRules.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef GUILDNAMERULES_H
|
||||
#define GUILDNAMERULES_H
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
// What a guild name may be (docs/Guilds.md), for the chat server and the dashboard
|
||||
namespace GuildNameRules {
|
||||
constexpr size_t MIN_LENGTH = 3;
|
||||
constexpr size_t MAX_LENGTH = 30; // the client sends at most 30 characters
|
||||
|
||||
// MIN_LENGTH to MAX_LENGTH of A-Z a-z 0-9, space, ' - . with no space at either end and no two in a row
|
||||
inline bool IsValid(const std::u16string& name) {
|
||||
if (name.size() < MIN_LENGTH || name.size() > MAX_LENGTH) return false;
|
||||
if (name.front() == u' ' || name.back() == u' ') return false;
|
||||
for (size_t i = 0; i < name.size(); i++) {
|
||||
const char16_t c = name[i];
|
||||
const bool allowed = (c >= u'a' && c <= u'z') || (c >= u'A' && c <= u'Z') || (c >= u'0' && c <= u'9') ||
|
||||
c == u' ' || c == u'\'' || c == u'-' || c == u'.';
|
||||
if (!allowed) return false;
|
||||
if (c == u' ' && i > 0 && name[i - 1] == u' ') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GUILDNAMERULES_H
|
||||
Reference in New Issue
Block a user