using System.Buffers.Binary; namespace AcDream.Core.Net.Messages; /// /// Outbound allegiance GameActions. Both Swear and Break carry a /// single uint32 target-guid payload inside the standard /// 0xF7B1 GameAction envelope. /// /// /// Wire layout (r11 §2.1 / §2.3): /// /// u32 0xF7B1 /// u32 gameActionSequence /// u32 subOpcode (0x001D or 0x001E) /// u32 targetGuid /// /// /// /// /// Server replies with GameEventAllegianceUpdate (0x0020) and /// GameEventAllegianceAllegianceUpdateDone (0x01C8) on success, /// or a WeenieError on failure (already sworn, already maxed /// vassals, target not online, etc — see r11 §2.1 for the full list). /// /// public static class AllegianceRequests { public const uint GameActionEnvelope = 0xF7B1u; public const uint SwearOpcode = 0x001Du; public const uint BreakOpcode = 0x001Eu; /// Pledge yourself to the given patron. public static byte[] BuildSwear(uint gameActionSequence, uint patronGuid) { return Build(gameActionSequence, SwearOpcode, patronGuid); } /// /// Break your pledge to . Target can be /// your patron (breaking from) OR your vassal (breaking them away). /// public static byte[] BuildBreak(uint gameActionSequence, uint targetGuid) { return Build(gameActionSequence, BreakOpcode, targetGuid); } private static byte[] Build(uint seq, uint sub, uint targetGuid) { byte[] body = new byte[16]; BinaryPrimitives.WriteUInt32LittleEndian(body, GameActionEnvelope); BinaryPrimitives.WriteUInt32LittleEndian(body.AsSpan(4), seq); BinaryPrimitives.WriteUInt32LittleEndian(body.AsSpan(8), sub); BinaryPrimitives.WriteUInt32LittleEndian(body.AsSpan(12), targetGuid); return body; } }