using System;
using System.Buffers.Binary;
namespace AcDream.Core.Net.Messages;
///
/// SetTurbineChatChannels (0x0295) — GameEvent (0xF7B0 sub-opcode)
/// the server fires once at login (and after a chat-server reconnect)
/// listing the runtime room ids assigned to the global community
/// channels (General, Trade, LFG, Roleplay, Society + sub-societies,
/// Olthoi, plus the optional Allegiance Turbine room).
///
///
/// Wire layout (10 sequential u32s, payload only — the 0xF7B0 envelope
/// is parsed by ; this parser consumes
/// the payload slice):
///
/// u32 allegianceRoom // 0 = None (server-side flag)
/// u32 generalRoom
/// u32 tradeRoom
/// u32 lfgRoom
/// u32 roleplayRoom
/// u32 olthoiRoom
/// u32 societyRoom // 0 = None (player not in a society)
/// u32 societyCelestialHandRoom
/// u32 societyEldrytchWebRoom
/// u32 societyRadiantBloodRoom
///
///
///
///
/// Source: holtburger
/// references/holtburger/crates/holtburger-protocol/src/messages/chat/turbine.rs
/// lines 132-209 (struct + ProtocolUnpack/ProtocolPack).
///
///
public static class SetTurbineChatChannels
{
/// GameEvent sub-opcode (NOT a top-level GameMessage opcode).
public const uint EventType = 0x0295u;
/// Payload size in bytes (10 u32 fields).
public const int PayloadSize = 40;
///
/// Parsed channel ids. Optional fields (,
/// ) carry 0u when the server signals
/// "not applicable" — callers should treat 0 as None.
///
public readonly record struct Parsed(
uint AllegianceRoom,
uint GeneralRoom,
uint TradeRoom,
uint LfgRoom,
uint RoleplayRoom,
uint OlthoiRoom,
uint SocietyRoom,
uint SocietyCelestialHandRoom,
uint SocietyEldrytchWebRoom,
uint SocietyRadiantBloodRoom);
///
/// Parse the payload of a 0xF7B0 envelope whose event type is
/// . The slice must contain exactly the 10
/// channel u32s (40 bytes); shorter buffers return null.
///
public static Parsed? TryParse(ReadOnlySpan payload)
{
if (payload.Length < PayloadSize) return null;
uint allegiance = BinaryPrimitives.ReadUInt32LittleEndian(payload[..4]);
uint general = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(4, 4));
uint trade = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(8, 4));
uint lfg = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(12, 4));
uint roleplay = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(16, 4));
uint olthoi = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(20, 4));
uint society = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(24, 4));
uint societyCelHan = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(28, 4));
uint societyEldWeb = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(32, 4));
uint societyRadBlo = BinaryPrimitives.ReadUInt32LittleEndian(payload.Slice(36, 4));
return new Parsed(
AllegianceRoom: allegiance,
GeneralRoom: general,
TradeRoom: trade,
LfgRoom: lfg,
RoleplayRoom: roleplay,
OlthoiRoom: olthoi,
SocietyRoom: society,
SocietyCelestialHandRoom: societyCelHan,
SocietyEldrytchWebRoom: societyEldWeb,
SocietyRadiantBloodRoom: societyRadBlo);
}
///
/// Serialize into a 40-byte payload buffer
/// (the 0xF7B0 envelope is the caller's responsibility). Used by
/// fixture round-trip tests.
///
public static byte[] Serialize(Parsed parsed)
{
var buf = new byte[PayloadSize];
var span = buf.AsSpan();
BinaryPrimitives.WriteUInt32LittleEndian(span, parsed.AllegianceRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(4, 4), parsed.GeneralRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(8, 4), parsed.TradeRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(12, 4), parsed.LfgRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(16, 4), parsed.RoleplayRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(20, 4), parsed.OlthoiRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(24, 4), parsed.SocietyRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(28, 4), parsed.SocietyCelestialHandRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(32, 4), parsed.SocietyEldrytchWebRoom);
BinaryPrimitives.WriteUInt32LittleEndian(span.Slice(36, 4), parsed.SocietyRadiantBloodRoom);
return buf;
}
}