public static void WritePacketLength(this SpanWriter writer) { var length = writer.Position; writer.Seek(1, SeekOrigin.Begin); writer.Write((ushort)length); writer.Seek(length, SeekOrigin.Begin); }
public static int CreateMessageLocalized( Span <byte> buffer, Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = "" ) { name ??= ""; args ??= ""; if (hue == 0) { hue = 0x3B2; } var writer = new SpanWriter(buffer); writer.Write((byte)0xC1); writer.Seek(2, SeekOrigin.Current); writer.Write(serial); writer.Write((short)graphic); writer.Write((byte)type); writer.Write((short)hue); writer.Write((short)font); writer.Write(number); writer.WriteAscii(name, 30); writer.WriteLittleUniNull(args); writer.WritePacketLength(); return(writer.Position); }
public void Terminate() { int length = _position + 4; if (length != _buffer.Length) { Resize(length); } var writer = new SpanWriter(_buffer); writer.Seek(_position, SeekOrigin.Begin); writer.Write(0); writer.Seek(11, SeekOrigin.Begin); writer.Write(_hash); writer.WritePacketLength(); }
public static int CreateMessage( Span <byte> buffer, Serial serial, int graphic, MessageType type, int hue, int font, bool ascii, string lang, string name, string text ) { if (buffer[0] != 0) { return(buffer.Length); } name ??= ""; text ??= ""; lang ??= "ENU"; if (hue == 0) { hue = 0x3B2; } var writer = new SpanWriter(buffer); writer.Write((byte)(ascii ? 0x1C : 0xAE)); // Packet ID writer.Seek(2, SeekOrigin.Current); writer.Write(serial); writer.Write((short)graphic); writer.Write((byte)type); writer.Write((short)hue); writer.Write((short)font); if (ascii) { writer.WriteAscii(name, 30); writer.WriteAsciiNull(text); } else { writer.WriteAscii(lang, 4); writer.WriteAscii(name, 30); writer.WriteBigUniNull(text); } writer.WritePacketLength(); return(writer.Position); }
public ObjectPropertyList(IEntity e) { Entity = e; _buffer = GC.AllocateUninitializedArray <byte>(64); var writer = new SpanWriter(_buffer); writer.Write((byte)0xD6); // Packet ID writer.Seek(2, SeekOrigin.Current); writer.Write((ushort)1); writer.Write(e.Serial); writer.Write((ushort)0); _position = writer.Position + 4; // Hash }
private static void WritePacked(ReadOnlySpan <byte> source, ref SpanWriter writer, out int length) { var size = source.Length; var dest = writer.RawBuffer.Slice(writer.Position + 3); length = dest.Length; var ce = Zlib.Pack(dest, ref length, source, ZlibQuality.Default); if (ce != ZlibError.Okay) { Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce); length = 0; size = 0; } writer.Write((byte)size); writer.Write((byte)length); writer.Write((byte)(((size >> 4) & 0xF0) | ((length >> 8) & 0xF))); writer.Seek(length, SeekOrigin.Current); }
public void Add(int number, string arguments = null) { if (number == 0) { return; } arguments ??= ""; if (Header == 0) { Header = number; HeaderArgs = arguments; } AddHash(number); if (arguments.Length > 0) { AddHash(arguments.GetHashCode(StringComparison.Ordinal)); } int strLength = Utility.Unicode.GetByteCount(arguments); int length = _position + 6 + strLength; while (length > _buffer.Length) { Flush(); } var writer = new SpanWriter(_buffer); writer.Seek(_position, SeekOrigin.Begin); writer.Write(number); writer.Write((ushort)strLength); writer.WriteBigUni(arguments); }
public static void WritePacketLength(this SpanWriter writer) { writer.Seek(1, SeekOrigin.Begin); writer.Write((ushort)writer.BytesWritten); writer.Seek(0, SeekOrigin.End); }
(Zlib.MaxPackSize(stairsPerBuffer * stairsLength) + 4) * stairsCount; // 22602 public static byte[] CreateHouseDesignStateDetailed(uint serial, int revision, MultiComponentList components) { var xMin = components.Min.X; var yMin = components.Min.Y; var xMax = components.Max.X; var yMax = components.Max.Y; var tiles = components.List; const int totalPlaneLength = planeLength * planeCount; const int stairsBufferLength = stairsPerBuffer * stairsLength; const int maxUnpackedSize = totalPlaneLength + stairsBufferLength * stairsCount; using var inflatedWriter = new SpanWriter(maxUnpackedSize); Span <bool> planesUsed = stackalloc bool[9]; var index = 0; var stairsIndex = totalPlaneLength; var totalStairsUsed = 0; var width = xMax - xMin + 1; var height = yMax - yMin + 1; for (var i = 0; i < tiles.Length; ++i) { var mte = tiles[i]; var x = mte.OffsetX - xMin; var y = mte.OffsetY - yMin; int z = mte.OffsetZ; var floor = TileData.ItemTable[mte.ItemId & TileData.MaxItemValue].Height <= 0; int plane = z switch { 0 => 0, 7 => 1, 27 => 2, 47 => 3, 67 => 4, _ => - 1 }; if (plane > -1) { int size; if (plane == 0) { size = height; } else if (floor) { size = height - 2; x -= 1; y -= 1; } else { size = height - 1; plane += 4; } index = (x * size + y) * 2; if (x >= 0 && y >= 0 && y < size && index + 1 < 0x400) { var planeUsed = planesUsed[plane]; if (!planeUsed) { inflatedWriter.Seek(plane * planeLength, SeekOrigin.Begin); inflatedWriter.Clear(planeLength); planesUsed[plane] = true; } inflatedWriter.Seek(index, SeekOrigin.Begin); inflatedWriter.Write(mte.ItemId); continue; } } inflatedWriter.Seek(stairsIndex, SeekOrigin.Begin); inflatedWriter.Write(mte.ItemId); inflatedWriter.Write((byte)mte.OffsetX); inflatedWriter.Write((byte)mte.OffsetY); inflatedWriter.Write((byte)mte.OffsetZ); stairsIndex = inflatedWriter.Position; totalStairsUsed++; } var buffer = GC.AllocateUninitializedArray <byte>(maxPacketLength); var writer = new SpanWriter(buffer); writer.Write((byte)0xD8); // Packet ID writer.Seek(2, SeekOrigin.Current); // Length writer.Write((byte)0x03); // Compression Type writer.Write((byte)0x00); // Unknown writer.Write(serial); writer.Write(revision); writer.Write((short)tiles.Length); writer.Seek(3, SeekOrigin.Current); // Buffer Length, Plane Count var totalPlanes = 0; var totalLength = 1; // includes plane count for (var i = 0; i < planeCount; i++) { if (!planesUsed[i]) { inflatedWriter.Seek(planeCount, SeekOrigin.Current); continue; } int size = i switch { 0 => width * height * 2, < 5 => (width - 1) * (height - 2) * 2, _ => width * (height - 1) * 2 }; var source = inflatedWriter.RawBuffer.Slice(i * planeLength, size); writer.Write((byte)(0x20 | i)); WritePacked(source, ref writer, out int destLength); totalLength += 4 + destLength; totalPlanes++; } index = 0; while (totalStairsUsed > 0) { var count = Math.Min(stairsPerBuffer, totalStairsUsed); totalStairsUsed -= count; var start = totalPlaneLength + index * stairsLength; var size = count * 5; var source = inflatedWriter.RawBuffer.Slice(start, size); writer.Write((byte)(9 + index++)); WritePacked(source, ref writer, out int destLength); totalLength += 4 + destLength; totalPlanes++; } writer.Seek(15, SeekOrigin.Begin); writer.Write((short)totalLength); writer.Write((byte)totalPlanes); writer.WritePacketLength(); // TODO: Avoid this somehow. Array.Resize(ref buffer, writer.BytesWritten); return(buffer); }
public static void SendDisplayGump(this NetState ns, Gump gump, out int switches, out int entries) { switches = 0; entries = 0; if (ns == null) { return; } var packed = ns.Unpack; var writer = new SpanWriter(512, true); writer.Write((byte)(packed ? 0xDD : 0xB0)); // Packet ID writer.Seek(2, SeekOrigin.Current); writer.Write(gump.Serial); writer.Write(gump.TypeID); writer.Write(gump.X); writer.Write(gump.Y); var spanWriter = new SpanWriter(512, true); if (!gump.Draggable) { spanWriter.Write(Gump.NoMove); } if (!gump.Closable) { spanWriter.Write(Gump.NoClose); } if (!gump.Disposable) { spanWriter.Write(Gump.NoDispose); } if (!gump.Resizable) { spanWriter.Write(Gump.NoResize); } var stringsList = new OrderedHashSet <string>(11); foreach (var entry in gump.Entries) { entry.AppendTo(ref spanWriter, stringsList, ref entries, ref switches); } if (packed) { spanWriter.Write((byte)0); // Layout text terminator WritePacked(ref writer, spanWriter.Span); } else { writer.Write((ushort)spanWriter.BytesWritten); writer.Write(spanWriter.Span); } if (packed) { writer.Write(stringsList.Count); } else { writer.Write((ushort)stringsList.Count); } spanWriter.Seek(0, SeekOrigin.Begin); foreach (var str in stringsList) { var s = str ?? ""; spanWriter.Write((ushort)s.Length); spanWriter.WriteBigUni(s); } if (packed) { WritePacked(ref writer, spanWriter.Span); } else { writer.Write(spanWriter.Span); } writer.WritePacketLength(); ns.Send(writer.Span); spanWriter.Dispose(); // Can't use using and refs, so we dispose manually }