예제 #1
0
    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);
    }
예제 #2
0
    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);
    }
예제 #3
0
        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);
        }
예제 #4
0
    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);
    }
예제 #5
0
    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);
    }
예제 #6
0
    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);
    }
예제 #7
0
    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);
    }
예제 #8
0
    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);
    }
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
    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);
    }
예제 #12
0
    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);
    }
예제 #13
0
        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);
        }
예제 #14
0
    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);
    }
예제 #15
0
        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);
        }
예제 #16
0
        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);
        }
예제 #17
0
    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);
    }
예제 #18
0
    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);
    }
예제 #19
0
    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]);
예제 #20
0
        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);
        }
예제 #21
0
    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);
    }
예제 #22
0
    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);
    }
예제 #23
0
    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);
    }
예제 #24
0
파일: MapUO.cs 프로젝트: AsYlum-/ModernUO
    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);
    }
예제 #25
0
    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]);
예제 #26
0
    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);
    }
예제 #27
0
    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);
        }
    }
예제 #28
0
    // 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);
    }
예제 #29
0
    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);
    }
예제 #30
0
    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);
    }