public static void SendVendorBuyList(this NetState ns, Mobile vendor, List <BuyItemState> list) { if (ns.CannotSendPackets()) { return; } var length = 8; for (int i = 0; i < list.Count; i++) { length += 6 + list[i].Description?.Length ?? 0; } var writer = new SpanWriter(stackalloc byte[length]); writer.Write((byte)0x74); // Packet ID writer.Write((ushort)length); writer.Write((vendor.FindItemOnLayer(Layer.ShopBuy) as Container)?.Serial ?? Serial.MinusOne); writer.Write((byte)list.Count); for (var i = 0; i < list.Count; ++i) { var bis = list[i]; writer.Write(bis.Price); var desc = bis.Description ?? ""; writer.Write((byte)(desc.Length + 1)); writer.WriteAsciiNull(desc); } ns.Send(writer.Span); }
public static void SendDamage(this NetState ns, Serial serial, int amount) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[ns.DamagePacket ? 7 : 11]); if (ns.DamagePacket) { writer.Write((byte)0x0B); // Packet ID writer.Write(serial); writer.Write((ushort)Math.Clamp(amount, 0, 0xFFFF)); } else { writer.Write((byte)0xBF); // Packet ID writer.Write((ushort)11); // Length writer.Write((ushort)0x22); writer.Write((byte)1); writer.Write(serial); writer.Write((byte)Math.Clamp(amount, 0, 0xFF)); } ns.Send(writer.Span); }
public static void SendBookCover(this NetState ns, Mobile from, BaseBook book) { if (ns.CannotSendPackets()) { return; } var title = book.Title ?? ""; var titleLength = TextEncoding.UTF8.GetByteCount(title); var author = book.Author ?? ""; var authorLength = TextEncoding.UTF8.GetByteCount(author); var length = 17 + titleLength + authorLength; var writer = new SpanWriter(stackalloc byte[length]); writer.Write((byte)0xD4); // Packet ID writer.Write((ushort)length); writer.Write(book.Serial); writer.Write((byte)0x1); // Flag on writer.Write(book.Writable && from.InRange(book.GetWorldLocation(), 1)); writer.Write((ushort)book.PagesCount); writer.Write((ushort)(titleLength + 1)); writer.WriteUTF8Null(title); writer.Write((ushort)(authorLength + 1)); writer.WriteUTF8Null(author); ns.Send(writer.Span); }
public static void SendNewSpellbookContent(this NetState ns, Serial book, int graphic, int offset, ulong content) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[23]); writer.Write((byte)0xBF); // Packet ID writer.Write((ushort)23); // Length writer.Write((short)0x1B); // Subpacket writer.Write((short)0x01); // Command writer.Write(book); writer.Write((short)graphic); writer.Write((short)offset); for (var i = 0; i < 8; ++i) { writer.Write((byte)(content >> (i * 8))); } ns.Send(writer.Span); }
public static void SendSecureTradeEquip(this NetState ns, Item item, Mobile m) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[ns.ContainerGridLines ? 21 : 20]); writer.Write((byte)0x25); // Packet ID writer.Write(item.Serial); writer.Write((short)item.ItemID); writer.Write((byte)0); writer.Write((short)item.Amount); writer.Write((short)item.X); writer.Write((short)item.Y); if (ns.ContainerGridLines) { writer.Write((byte)0); } writer.Write(m.Serial); writer.Write((short)item.Hue); ns.Send(writer.Span); }
public static void SendMultiTargetReq(this NetState ns, MultiTarget t) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[ns.HighSeas ? 30 : 26]); writer.Write((byte)0x99); // Packet ID writer.Write(t.AllowGround); writer.Write(t.TargetID); writer.Write((byte)t.Flags); writer.Clear(11); writer.Write((short)t.MultiID); writer.Write((short)t.Offset.X); writer.Write((short)t.Offset.Y); writer.Write((short)t.Offset.Z); if (ns.HighSeas) { writer.Write(0); } ns.Send(writer.Span); }
public static void SendMapPatches(this NetState ns) { if (ns.CannotSendPackets()) { return; } if (_mapPatchesPacket[0] == 0) { var writer = new SpanWriter(_mapPatchesPacket); writer.Write((byte)0xBF); // Packet ID writer.Write((ushort)41); // Length writer.Write((ushort)0x18); // Subpacket writer.Write(4); for (int i = 0; i < 4; i++) { var map = Map.Maps[i]; writer.Write(map?.Tiles.Patch.StaticBlocks ?? 0); writer.Write(map?.Tiles.Patch.LandBlocks ?? 0); } } ns.Send(_mapPatchesPacket); }
public static void SendVendorBuyContent(this NetState ns, List <BuyItemState> list) { if (ns.CannotSendPackets()) { return; } var length = 5 + list.Count * (ns.ContainerGridLines ? 20 : 19); var writer = new SpanWriter(stackalloc byte[length]); writer.Write((byte)0x3C); // Packet ID writer.Write((ushort)length); writer.Write((short)list.Count); for (var i = list.Count - 1; i >= 0; --i) { var bis = list[i]; writer.Write(bis.MySerial); writer.Write((ushort)bis.ItemID); writer.Write((byte)0); // itemID offset writer.Write((ushort)bis.Amount); writer.Write((short)(i + 1)); // x writer.Write((short)1); // y if (ns.ContainerGridLines) { writer.Write((byte)0); // Grid Location? } writer.Write(bis.ContainerSerial); writer.Write((ushort)bis.Hue); } ns.Send(writer.Span); }
public static void SendStatueAnimation(this NetState ns, Serial serial, int status, int anim, int frame) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[StatueAnimationPacketLength].InitializePacket(); CreateStatueAnimation(buffer, serial, status, anim, frame); ns.Send(buffer); }
public static void SendHairEquipUpdatePacket(this NetState ns, Mobile m, uint hairSerial, int itemId, int hue, Layer layer) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[EquipUpdatePacketLength]; CreateHairEquipUpdatePacket(buffer, m, hairSerial, itemId, hue, layer); ns.Send(buffer); }
public static void SendDeathAnimation(this NetState ns, Serial killed, Serial corpse) { if (ns.CannotSendPackets()) { return; } Span <byte> span = stackalloc byte[DeathAnimationPacketLength]; CreateDeathAnimation(span, killed, corpse); ns.Send(span); }
public static void SendMobileMoving(this NetState ns, Mobile target, int noto) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[MobileMovingPacketLength].InitializePacket(); CreateMobileMoving(buffer, target, noto, ns.StygianAbyss); ns.Send(buffer); }
public static void SendRemoveHairPacket(this NetState ns, uint hairSerial) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[RemovePacketLength]; CreateRemoveHairPacket(buffer, hairSerial); ns.Send(buffer); }
public static void SendSoundEffect(this NetState ns, int soundID, IPoint3D target) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[SoundPacketLength].InitializePacket(); CreateSoundEffect(buffer, soundID, target); ns.Send(buffer); }
public static void SendPartyRemoveMember(this NetState ns, Serial m, Party p = null) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[GetPartyRemoveMemberPacketLength(p)]; CreatePartyRemoveMember(buffer, m, p); ns.Send(buffer); }
public static void SendPartyMemberList(this NetState ns, Party p) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[GetPartyMemberListPacketLength(p)]; CreatePartyMemberList(buffer, p); ns.Send(buffer); }
public static void SendRemoveEntity(this NetState ns, Serial serial) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[RemoveEntityLength].InitializePacket(); CreateRemoveEntity(buffer, serial); ns.Send(buffer); }
public static void SendOPLInfo(this NetState ns, Serial serial, int hash) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[OPLPacketLength].InitializePacket(); CreateOPLInfo(buffer, serial, hash); ns.Send(buffer); }
public static void SendWorldItem(this NetState ns, Item item) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[OutgoingEntityPackets.MaxWorldEntityPacketLength].InitializePacket(); var length = ns.StygianAbyss ? OutgoingEntityPackets.CreateWorldEntity(buffer, item, ns.HighSeas) : CreateWorldItem(buffer, item); ns.Send(buffer[..length]);
public static void SendBookContent(this NetState ns, BaseBook book) { if (ns.CannotSendPackets()) { return; } var count = book.PagesCount; // Practical limit is 24 full pages at full unicode, or 96 full pages at ascii-only // For pure ascii, finding byte count is fast enough. // If perf becomes an issue, then switch to resizable SpanWriter var length = 9; for (var i = 0; i < count; i++) { var page = book.Pages[i]; length += 4; // max is 8 for (var j = 0; j < page.Lines.Length; j++) { length += TextEncoding.UTF8.GetByteCount(page.Lines[j]) + 1; } } var writer = new SpanWriter(stackalloc byte[length]); writer.Write((byte)0x66); // Packet ID writer.Write((ushort)length); writer.Write(book.Serial); writer.Write((ushort)count); for (var i = 0; i < count; i++) { var page = book.Pages[i]; writer.Write((ushort)(i + 1)); writer.Write((ushort)page.Lines.Length); for (var j = 0; j < page.Lines.Length; j++) { writer.WriteUTF8Null(page.Lines[j]); } } writer.WritePacketLength(); ns.Send(writer.Span); }
public static void SendContainerContent(this NetState ns, Mobile beholder, Item beheld) { if (ns.CannotSendPackets()) { return; } var items = beheld.Items; var count = items.Count; var writer = new SpanWriter(stackalloc byte[5 + items.Count * (ns.ContainerGridLines ? 20 : 19)]); writer.Write((byte)0x3C); // Packet ID writer.Seek(4, SeekOrigin.Current); // Length & written count var written = 0; for (var i = 0; i < count; ++i) { var child = items[i]; if (!child.Deleted && beholder.CanSee(child)) { var loc = child.Location; writer.Write(child.Serial); writer.Write((ushort)child.ItemID); writer.Write((byte)0); // signed, itemID offset writer.Write((ushort)Math.Min(child.Amount, ushort.MaxValue)); writer.Write((short)loc.X); writer.Write((short)loc.Y); if (ns.ContainerGridLines) { writer.Write((byte)0); // Grid Location? } writer.Write(beheld.Serial); writer.Write((ushort)(child.QuestItem ? Item.QuestItemHue : child.Hue)); ++written; } } writer.Seek(1, SeekOrigin.Begin); writer.Write((ushort)writer.BytesWritten); writer.Write((ushort)written); writer.Seek(0, SeekOrigin.End); ns.Send(writer.Span); }
public static void SendDisplayEquipmentInfo( this NetState ns, Serial serial, int number, string crafterName, bool unidentified, List <EquipInfoAttribute> attrs ) { if (ns.CannotSendPackets()) { return; } crafterName = crafterName.DefaultIfNullOrEmpty(""); var length = 17 + (crafterName.Length > 0 ? 6 + crafterName.Length : 0) + (unidentified ? 4 : 0) + attrs.Count * 6; var writer = new SpanWriter(stackalloc byte[length]); writer.Write((byte)0xBF); // Packet ID writer.Write((ushort)length); writer.Write((ushort)0x10); // Subpacket writer.Write(serial); writer.Write(number); if (crafterName.Length > 0) { writer.Write(-3); // crafted by writer.Write((ushort)crafterName.Length); writer.WriteAscii(crafterName); } if (unidentified) { writer.Write(-4); } for (var i = 0; i < attrs.Count; ++i) { var attr = attrs[i]; writer.Write(attr.Number); writer.Write((short)attr.Charges); } writer.Write(-1); ns.Send(writer.Span); }
public static void SendPersonalLightLevel(this NetState ns, Serial serial, int level) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[6]); writer.Write((byte)0x4E); // Packet ID writer.Write(serial); writer.Write((byte)level); ns.Send(writer.Span); }
public static void SendPartyMemberLocations(this NetState ns, Mobile from, Party party) { if (ns.CannotSendPackets()) { return; } var count = party?.Members.Count ?? 0; var maxLength = 9 + (count > 1 ? (count - 1) * 9 : 0); var writer = new SpanWriter(stackalloc byte[maxLength]); writer.Write((byte)0xF0); // Packet ID writer.Seek(2, SeekOrigin.Current); writer.Write((byte)0x01); // Command bool sendPacket = false; for (var i = 0; i < count; i++) { var pmi = party !.Members[i]; Mobile mob = pmi?.Mobile; if (mob?.NetState == null || mob == from) { continue; } if (Utility.InUpdateRange(from.Location, mob.Location) && from.CanSee(mob)) { continue; } sendPacket = true; writer.Write(mob.Serial); writer.Write((short)mob.X); writer.Write((short)mob.Y); writer.Write((byte)(mob.Map?.MapID ?? 0)); } if (!sendPacket) { return; } writer.Write(0); writer.WritePacketLength(); ns.Send(writer.Span); }
public static void SendMessageLocalized( this NetState ns, Serial serial, int graphic, MessageType type, int hue, int font, int number, string name = "", string args = "" ) { if (ns.CannotSendPackets()) { return; } Span <byte> buffer = stackalloc byte[GetMaxMessageLocalizedLength(args)]; var length = CreateMessageLocalized( buffer, serial, graphic, type, hue, font, number, name, args ); ns.Send(buffer[..length]);
public static void SendEndVendorSell(this NetState ns, Serial vendor) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[8]); writer.Write((byte)0x3B); // Packet ID writer.Write((ushort)8); writer.Write(vendor); writer.Write((byte)0); ns.Send(writer.Span); }
public static void SendSpellbookContent(this NetState ns, Serial book, int graphic, int offset, ulong content) { if (ns.CannotSendPackets()) { return; } if (ObjectPropertyList.Enabled && ns.NewSpellbook) { ns.SendNewSpellbookContent(book, graphic, offset, content); } else { ns.SendOldSpellbookContent(book, offset, content); } }
// Requires a buffer of 14 packets, 17 bytes per packet (238 bytes). // Requires cache to have the first byte of each packet initially zeroed. public static void SendMobileMovingUsingCache(this NetState ns, Span <byte> cache, Mobile target, int noto) { if (ns.CannotSendPackets()) { return; } var stygianAbyss = ns.StygianAbyss; // Indexes 0-6 for pre-SA, and 7-13 for SA var row = noto + (stygianAbyss ? 6 : -1); var buffer = cache.Slice(row * MobileMovingPacketLength, MobileMovingPacketLength); CreateMobileMoving(buffer, target, noto, stygianAbyss); ns.Send(buffer); }
public static void SendSwing(this NetState ns, Serial attacker, Serial defender) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[10]); writer.Write((byte)0x2F); // Packet ID writer.Write((byte)0); writer.Write(attacker); writer.Write(defender); ns.Send(writer.Span); }
public static void SendScreenEffect(this NetState ns, ScreenEffectType type) { if (ns.CannotSendPackets()) { return; } var writer = new SpanWriter(stackalloc byte[28]); writer.Write((byte)0x70); // Packet ID writer.Write((byte)0x4); writer.Clear(8); writer.Write((ushort)type); writer.Clear(16); ns.Send(writer.Span); }