mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 02:43:44 +00:00
feat(world): guilds in the world: create box, character component, guild commands
The world side of guilds (docs/Guilds.md): - TMP_GUILD_CREATE, which the client's guild create box sends to its world, goes to the chat server as GUILD_CREATE. - The character component reads the character's guild from the database when it loads (instead of the old unused "gn" and "gid" charxml attributes) and takes GUILD_GET_STATUS from the chat server; a change is serialized once (the client redraws the name billboard every time it reads a guild name). A name waiting for moderation isn't shown. - Slash commands (the client has none for guilds): /g and /guild (guild chat; the client's guild tab sends /g, which goes through the chat filter and mute like zone chat, then to the chat server as channel 10), /guildcreate (opens the create box with DisplayGuildCreateBox), /gkick, /grank <name> <officer|veteran|recruit>, /gleader and /gdisband confirm. - The Guild Master script (LOT 3001, L_GUILD_CREATE.lua: using it opens the create box). Live never placed it; GMs can spawn it. Check in game (two accounts, a client with a FeatureGating row "guilds", 1, 0, 0 in its cdclient.fdb): /guildcreate, make a guild (the name shows under yours, the guild button appears on the status bar); invite the second character from the guild window, accept, both lists show both; guild chat tab; /grank, /gkick, /gleader; leave from the window; log the second character out and in (guildmate logged off/in lines). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -130,6 +130,46 @@ TEST_F(ReplicaConstructionTest, CharacterConstructionAlwaysWritesGmActivityAndSo
|
||||
player.SetCharacter(nullptr);
|
||||
}
|
||||
|
||||
// A guild change (docs/Guilds.md) is written once: the client reads guild id, a u8 length and 16-bit characters, and
|
||||
// redraws the name billboard every time it reads a name.
|
||||
TEST_F(ReplicaConstructionTest, CharacterGuildChangeIsWrittenOnce) {
|
||||
User user(UNASSIGNED_SYSTEM_ADDRESS, "tester", "key");
|
||||
Character character(1, &user);
|
||||
info.lot = 1;
|
||||
Entity player(1152921506064087004, info);
|
||||
player.SetCharacter(&character);
|
||||
character.SetEntity(&player);
|
||||
auto* const component = player.AddComponent<CharacterComponent>(-1, &character, UNASSIGNED_SYSTEM_ADDRESS);
|
||||
RakNet::BitStream construction;
|
||||
component->Serialize(construction, true);
|
||||
|
||||
component->SetGuild(7, u"Brick");
|
||||
EXPECT_EQ(component->GetGuildID(), 7);
|
||||
RakNet::BitStream serialization;
|
||||
component->Serialize(serialization, false);
|
||||
RakNet::BitStream expected;
|
||||
expected.Write0(); // gm_pvp_info
|
||||
expected.Write0(); // current_activity
|
||||
expected.Write1(); // social_info
|
||||
expected.Write<LWOOBJID>(7);
|
||||
expected.Write<uint8_t>(5);
|
||||
for (const char16_t c : std::u16string(u"Brick")) expected.Write<uint16_t>(c);
|
||||
expected.Write1();
|
||||
expected.Write<uint32_t>(0);
|
||||
ExpectSameBits(serialization, expected);
|
||||
|
||||
RakNet::BitStream again;
|
||||
component->Serialize(again, false);
|
||||
EXPECT_EQ(again.GetNumberOfBitsUsed(), 3u);
|
||||
// The same guild again changes nothing
|
||||
component->SetGuild(7, u"Brick");
|
||||
RakNet::BitStream same;
|
||||
component->Serialize(same, false);
|
||||
EXPECT_EQ(same.GetNumberOfBitsUsed(), 3u);
|
||||
|
||||
player.SetCharacter(nullptr);
|
||||
}
|
||||
|
||||
// Live wrote the cheat block (gravity scale, speed multiplier) on construction only when one of them was changed: 216
|
||||
// of 20,617 controllable-physics constructions had it (players at run speed 1.05, enemies with gravity 0), never 1/1.
|
||||
TEST_F(ReplicaConstructionTest, ControllablePhysicsConstructionWritesCheatsOnlyWhenChanged) {
|
||||
|
||||
Reference in New Issue
Block a user