using System.Buffers.Binary; using System.Text; using AcDream.Core.Items; using AcDream.Core.Net.Messages; namespace AcDream.Core.Net.Tests.Messages; public sealed class CreateObjectTests { [Fact] public void TryParse_WeenieHeaderPrefix_ReturnsNameAndItemType() { byte[] body = BuildMinimalCreateObjectWithWeenieHeader( guid: 0x50000002u, name: "Drudge", itemType: (uint)ItemType.Creature); var parsed = CreateObject.TryParse(body); Assert.NotNull(parsed); Assert.Equal(0x50000002u, parsed.Value.Guid); Assert.Equal("Drudge", parsed.Value.Name); Assert.Equal((uint)ItemType.Creature, parsed.Value.ItemType); } private static byte[] BuildMinimalCreateObjectWithWeenieHeader( uint guid, string name, uint itemType) { var bytes = new List(); WriteU32(bytes, CreateObject.Opcode); WriteU32(bytes, guid); // ModelData header: marker, subpalette count, texture count, animpart count. bytes.Add(0x11); bytes.Add(0); bytes.Add(0); bytes.Add(0); // PhysicsData: no flags, empty physics state, then 9 sequence stamps. WriteU32(bytes, 0); WriteU32(bytes, 0); for (int i = 0; i < 9; i++) WriteU16(bytes, 0); Align4(bytes); // Fixed WeenieHeader prefix per ACE SerializeCreateObject. WriteU32(bytes, 0); // weenieFlags WriteString16L(bytes, name); WritePackedDword(bytes, 0x1234); // WeenieClassId WritePackedDword(bytes, 0); // IconId via known-type writer WriteU32(bytes, itemType); WriteU32(bytes, 0); // ObjectDescriptionFlags Align4(bytes); return bytes.ToArray(); } private static void WriteU32(List bytes, uint value) { Span tmp = stackalloc byte[4]; BinaryPrimitives.WriteUInt32LittleEndian(tmp, value); bytes.AddRange(tmp.ToArray()); } private static void WriteU16(List bytes, ushort value) { Span tmp = stackalloc byte[2]; BinaryPrimitives.WriteUInt16LittleEndian(tmp, value); bytes.AddRange(tmp.ToArray()); } private static void WritePackedDword(List bytes, uint value) { if (value <= 0x7FFF) { WriteU16(bytes, (ushort)value); return; } WriteU16(bytes, (ushort)(((value >> 16) & 0x7FFF) | 0x8000)); WriteU16(bytes, (ushort)(value & 0xFFFF)); } private static void WriteString16L(List bytes, string value) { byte[] encoded = Encoding.GetEncoding(1252).GetBytes(value); WriteU16(bytes, checked((ushort)encoded.Length)); bytes.AddRange(encoded); Align4(bytes); } private static void Align4(List bytes) { while ((bytes.Count & 3) != 0) bytes.Add(0); } }