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;
}
}