using System; using System.Buffers.Binary; namespace AcDream.Core.Net.Messages; /// /// Inbound 0xF7E0 ServerMessage top-level GameMessage. /// General-purpose server-broadcast text — admin announcements, /// combat logs, and routine error messages routed by the server /// instead of via WeenieError. /// /// /// This is a standalone GameMessage — NOT wrapped in 0xF7B0 /// GameEvent envelope. Dispatched directly from /// . /// /// /// /// Wire layout (port from holtburger /// references/holtburger/.../messages/chat/types.rs::ServerMessageData, /// see also opcodes.rs:167): /// /// u32 opcode // 0xF7E0 /// string16L message /// u32 chatType // ChatMessageType (Broadcast / System / etc) /// /// /// public static class ServerMessage { public const uint Opcode = 0xF7E0u; public readonly record struct Parsed(string Message, uint ChatType); public static Parsed? TryParse(byte[] body) { if (body is null || body.Length < 8) return null; uint opcode = BinaryPrimitives.ReadUInt32LittleEndian(body); if (opcode != Opcode) return null; try { int pos = 4; string message = StringReader.ReadString16L(body, ref pos); if (body.Length - pos < 4) return null; uint chatType = BinaryPrimitives.ReadUInt32LittleEndian(body.AsSpan(pos)); return new Parsed(message, chatType); } catch { return null; } } }