From ee6ef9d82902e87472adbc31aefb7c332f5f46c5 Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 23 Aug 2026 05:16:58 +0400 Subject: [PATCH 01/12] feat(family): a character's family is loaded, named, and described MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Family, FamilyCharacter and FamilyLog tables have been in the schema since the first migration and nothing has ever read them. A character who belonged to a family looked, to everyone including themselves, like a character who did not. This adds the reading half: the membership is loaded at character select, the family tag goes into c_info, and the ginfo window is sent at login. SOURCE: a packet capture, field for field. * ginfo is confirmed all seventeen fields deep, which is worth stating because seventeen numbers in a row is exactly where an off-by-one hides — and this one would hand out the wrong permissions without throwing anything: ginfo -Nemesis- Yzigor 0 7 130000 640000 68 70 3 1 1 1 1 2 1 2 coin^afk^go^rush * the family tag is "Name(Rank)", and the brackets some families have are part of the NAME: [NDM](Gardien) KillaBeez(Gardien) Survival(Membre) * c_info carries the family id and that tag, and -1 with a bare "-" when there is none. TWO THINGS FOUND ALONG THE WAY, both written next to the code: * c_info's field 15 is NOT the family level, whatever the packet type calls it. PIKAZ in the capture belongs to a family gidx says is level 10, and their c_info carries 0 in that slot. Left at zero rather than filled with something the capture contradicts. * the inherited family experience table says a level-7 family needs 1 900 000 to advance. The captured ginfo says 640 000 — nearly three times less. One observation cannot rebuild nineteen rows, so the inherited numbers stay and the disagreement is written into the table's own comment. It only draws the bar; nothing levels a family up yet. NOT DONE, AND BLOCKED RATHER THAN SKIPPED: gidx, the tag over a character's head. The capture writes its third field as a single family id — 670 lines, not one containing a dot — and -1 when there is no family. GidxFamilySubPacket models it as a "serverId.familyId" compound, which cannot produce either shape; and leaving the sub-packet null makes the serializer drop the separating space and emit "gidx 1 741328-1 - 0", a packet the client cannot split. The same missing space happens on sc_n's empty equipment slots, so it looks like one defect in the packet library rather than two. Happy to send a NosCore.Packets change for both if you want it. The family lives in PlayerSocialComponent rather than a component of its own: it is social state, and Arch's World.Create is out of generic overloads at the player bundle's current size, so a further component would have to be added separately and would be easy to forget on the map-change path. Co-Authored-By: Claude Opus 5 --- .../Enumerations/I18N/LanguageKey.cs | 8 +- .../Resource/LocalizedResources.cs.resx | 12 + .../Resource/LocalizedResources.de.resx | 12 + .../Resource/LocalizedResources.es.resx | 14 +- .../Resource/LocalizedResources.fr.resx | 14 +- .../Resource/LocalizedResources.it.resx | 12 + .../Resource/LocalizedResources.pl.resx | 12 + .../Resource/LocalizedResources.resx | 12 + .../Resource/LocalizedResources.ru.resx | 12 + .../Resource/LocalizedResources.tr.resx | 12 + .../Ecs/Components/PlayerSocialComponent.cs | 14 +- .../Ecs/Extensions/PlayerBundleExtensions.cs | 15 +- .../Messaging/WolverineDependencyRegistrar.cs | 2 + .../Services/FamilyService/Family.cs | 112 +++++++++ .../Services/FamilyService/FamilyCharacter.cs | 29 +++ .../FamilyService/FamilyExperienceTable.cs | 63 ++++++ .../Services/FamilyService/FamilyService.cs | 67 ++++++ .../Services/FamilyService/IFamilyService.cs | 22 ++ .../CharacterScreen/SelectPacketHandler.cs | 10 +- .../Game/GameStartPacketHandler.cs | 11 + .../Services/FamilyService/FamilyTests.cs | 214 ++++++++++++++++++ .../SelectPacketHandlerTests.cs | 5 +- test/NosCore.Tests.Shared/TestHelpers.cs | 10 +- 23 files changed, 681 insertions(+), 13 deletions(-) create mode 100644 src/NosCore.GameObject/Services/FamilyService/Family.cs create mode 100644 src/NosCore.GameObject/Services/FamilyService/FamilyCharacter.cs create mode 100644 src/NosCore.GameObject/Services/FamilyService/FamilyExperienceTable.cs create mode 100644 src/NosCore.GameObject/Services/FamilyService/FamilyService.cs create mode 100644 src/NosCore.GameObject/Services/FamilyService/IFamilyService.cs create mode 100644 test/NosCore.GameObject.Tests/Services/FamilyService/FamilyTests.cs diff --git a/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs b/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs index b7396ace2..4169926d4 100644 --- a/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs +++ b/src/NosCore.Data/Enumerations/I18N/LanguageKey.cs @@ -1,4 +1,4 @@ -// __ _ __ __ ___ __ ___ ___ +// __ _ __ __ ___ __ ___ ___ // | \| |/__\ /' _/ / _//__\| _ \ __| // | | ' | \/ |`._`.| \_| \/ | v / _| // |_|\__|\__/ |___/ \__/\__/|_|_\___| @@ -198,6 +198,10 @@ public enum LanguageKey OBJECT_IN_BAZAAR, ITEM_GIFTED, NOT_IN_FRIENDLIST, - SPEAKER + SPEAKER, + FAMILY_AUTHORITY_HEAD, + FAMILY_AUTHORITY_ASSISTANT, + FAMILY_AUTHORITY_MANAGER, + FAMILY_AUTHORITY_MEMBER } } diff --git a/src/NosCore.Data/Resource/LocalizedResources.cs.resx b/src/NosCore.Data/Resource/LocalizedResources.cs.resx index 29d4ffac8..e373f379e 100644 --- a/src/NosCore.Data/Resource/LocalizedResources.cs.resx +++ b/src/NosCore.Data/Resource/LocalizedResources.cs.resx @@ -557,4 +557,16 @@ Načteno skriptovaných instancí: {0}! + + Head + + + Assistant + + + Manager + + + Member + \ No newline at end of file diff --git a/src/NosCore.Data/Resource/LocalizedResources.de.resx b/src/NosCore.Data/Resource/LocalizedResources.de.resx index 4aaf486bb..3697feaa0 100644 --- a/src/NosCore.Data/Resource/LocalizedResources.de.resx +++ b/src/NosCore.Data/Resource/LocalizedResources.de.resx @@ -580,4 +580,16 @@ {0} Skript-Instanzen geladen! + + Head + + + Assistant + + + Manager + + + Member + \ No newline at end of file diff --git a/src/NosCore.Data/Resource/LocalizedResources.es.resx b/src/NosCore.Data/Resource/LocalizedResources.es.resx index 7f9e36fbe..c8db32d73 100644 --- a/src/NosCore.Data/Resource/LocalizedResources.es.resx +++ b/src/NosCore.Data/Resource/LocalizedResources.es.resx @@ -1,4 +1,4 @@ - +