using System.Collections.Generic; namespace AcDream.Core.Items; /// /// AP-129 (Campaign P Slice P4 review fix, 2026-07-30). Retail /// RestrictionDB — the access-control list carried on a house/dwelling /// object's PublicWeenieDesc (WeenieHeaderFlag.HouseRestrictions, /// 0x04000000) and refreshed live via House_UpdateRestrictions (0x0248). /// Wire shape confirmed verbatim against /// references/Chorizite.ACProtocol/Chorizite.ACProtocol/Types/RestrictionDB.generated.cs /// and protocol.xml:6270-6275: uint Version, uint Flags (0=private, /// 1=open), ObjectId MonarchId, PHashTable<ObjectId,uint> Permissions. /// /// Wire Flags != 0 — retail's _bitmask /// & 1. When true, every mover is admitted regardless of the guest /// list. /// Wire MonarchId — retail /// _monarch_iid. A mover whose own monarch matches this id is admitted /// (allegiance-wide access), independent of the guest list. /// Wire Permissions — guid to permission value /// (0 = dwelling access only, 1 = storage access also). Retail's /// IsAllowedIn only consults key membership for entry; the permission /// value is preserved for wire fidelity but not consulted here. public sealed record HouseRestrictionRecord( bool OpenToPublic, uint AllegianceMonarchId, IReadOnlyDictionary Guests) { /// /// Verbatim port of retail RestrictionDB::IsAllowedIn /// (named-retail pc:444493-444516, 0x005ae8f0): /// if ((_bitmask & 1) == 0) { if (_monarch_iid == 0 || arg3 != /// _monarch_iid) { if (arg2 == 0) return 0; if (!table.find(arg2)) return /// 0; } } return 1; — open bit set, OR mover shares the house's /// allegiance monarch, OR mover's own guid is a table member. /// public bool IsAllowedIn(uint moverId, uint moverMonarchId) { if (OpenToPublic) return true; if (AllegianceMonarchId != 0 && moverMonarchId == AllegianceMonarchId) return true; return moverId != 0 && Guests.ContainsKey(moverId); } }