Пример #1
0
        /// <summary>
        /// Processes the sending of a message.
        /// </summary>
        private void ProcessMessage()
        {
            if (input.StartsWith("::"))
            {
                var packet = new Packet(103);
                packet.WriteString(input.Substring(2), 10);
                GameContext.NetworkHandler.Write(packet);
            }
            else if (input.Length > 0)
            {
                var msg = new ChatMessage(MessageType.Player, name, input);
                msg.CrownIndex = GameContext.LocalRights;
                Add(msg);

                var self = GameContext.Self;
                if (self != null)
                {
                    self.SpokenMessage = input;
                    self.SpokenLife    = 150;
                    self.SpokenTex     = null;
                }

                var @out = new Packet(4);
                @out.WriteByte(0);
                var pos = @out.Position();
                @out.WriteByteS(0);
                @out.WriteByteS(0);
                var buf = new DefaultJagexBuffer(new byte[5000]);
                StringUtils.Pack(input, buf);
                @out.WriteBytesReversedA(buf.Array(), 0, buf.Position());
            }
        }
Пример #2
0
        public Bitmap(CacheArchive archive, string imageArchive, int fileIndex)
        {
            JagexBuffer data = new DefaultJagexBuffer(archive.GetFile(imageArchive + ".dat"));
            JagexBuffer idx  = new DefaultJagexBuffer(archive.GetFile("index.dat"));

            idx.Position(data.ReadUShort());

            this.CropWidth  = idx.ReadUShort();
            this.CropHeight = idx.ReadUShort();

            this.Palette = new int[idx.ReadUByte()];

            for (int i = 0; i < this.Palette.Length - 1; i++)
            {
                this.Palette[i + 1] = idx.ReadTriByte();
            }

            for (int l = 0; l < fileIndex; l++)
            {
                idx.Position(idx.Position() + 2);
                data.Position(data.Position() + idx.ReadUShort() * idx.ReadUShort());
                idx.Position(idx.Position() + 1);
            }

            this.OffsetX = idx.ReadUByte();
            this.OffsetY = idx.ReadUByte();
            this.Width   = idx.ReadUShort();
            this.Height  = idx.ReadUShort();
            int type = idx.ReadUByte();

            this.Pixels = new sbyte[this.Width * this.Height];

            if (type == 0)
            {
                for (int i = 0; i < this.Pixels.Length; i++)
                {
                    this.Pixels[i] = (sbyte)data.ReadByte();
                    if (this.Palette[this.Pixels[i]] == 0)
                    {
                        HadTransparent = true;
                    }
                }
            }
            else if (type == 1)
            {
                for (int x = 0; x < this.Width; x++)
                {
                    for (int y = 0; y < this.Height; y++)
                    {
                        this.Pixels[x + (y * this.Width)] = (sbyte)data.ReadByte();
                        if (this.Palette[this.Pixels[x + (y * this.Width)]] == 0)
                        {
                            HadTransparent = true;
                        }
                    }
                }
            }
        }
Пример #3
0
        private void SetupMidiIndices(CacheArchive archive)
        {
            var midiIdxStream = new DefaultJagexBuffer(archive.GetFile("midi_index"));
            var size          = midiIdxStream.Capacity();

            MidiIndex = new int[size];
            for (int i = 0; i < size; i++)
            {
                MidiIndex[i] = midiIdxStream.ReadUByte();
            }
        }
Пример #4
0
        private void SetupAnimIndices(CacheArchive archive)
        {
            var animIdxStream = new DefaultJagexBuffer(archive.GetFile("anim_index"));
            var size          = animIdxStream.Capacity() / 2;

            AnimIndex = new int[size];
            for (int i = 0; i < size; i++)
            {
                AnimIndex[i] = animIdxStream.ReadUShort();
            }
        }
Пример #5
0
        public SequenceProvider(CacheArchive a)
        {
            var b = new DefaultJagexBuffer(a.GetFile("seq.dat"));

            count    = b.ReadUShort();
            instance = new Animation[count];
            for (int i = 0; i < count; i++)
            {
                instance[i] = new Animation(b);
            }
        }
Пример #6
0
        public UnderlayFloorDescriptorProvider(CacheArchive archive)
        {
            JagexBuffer s = new DefaultJagexBuffer(archive.GetFile("flo.dat"));

            count = s.ReadUShort();
            cache = new TileConfig[count];
            for (int i = 0; i < count; i++)
            {
                cache[i] = new TileConfig(s);
            }
        }
        public IdentityKitProvider(CacheArchive a)
        {
            JagexBuffer s = new DefaultJagexBuffer(a.GetFile("idk.dat"));

            count    = s.ReadUShort();
            instance = new PlayerAppearanceConfig[count];

            for (int i = 0; i < count; i++)
            {
                instance[i] = new PlayerAppearanceConfig(s);
            }
        }
Пример #8
0
        private void SetupFileCrcs(CacheArchive archive)
        {
            for (var i = 0; i < CrcFiles.Length; i++)
            {
                var b = new DefaultJagexBuffer(archive.GetFile(CrcFiles[i]));

                FileCrcs[i] = new int[b.Capacity() / 4];
                for (int j = 0; j < FileCrcs[i].Length; j++)
                {
                    FileCrcs[i][j] = b.ReadInt();
                }
            }
        }
Пример #9
0
        public ItemConfigProvider(CacheArchive archive)
        {
            dataStream = new DefaultJagexBuffer(archive.GetFile("obj.dat"));
            var idxStream = new DefaultJagexBuffer(archive.GetFile("obj.idx"));

            pointer = new int[idxStream.ReadUShort()];

            var position = 2;

            for (var i = 0; i < pointer.Length; i++)
            {
                pointer[i] = position;
                position  += idxStream.ReadUShort();
            }
        }
Пример #10
0
        private void SetupFileInfo(CacheArchive archive)
        {
            for (var i = 0; i < VersionFiles.Length; i++)
            {
                var b     = new DefaultJagexBuffer(archive.GetFile(VersionFiles[i]));
                int count = b.Capacity() / 2;

                FileVersions[i]   = new int[count];
                FilePriorities[i] = new byte[count];

                for (int j = 0; j < count; j++)
                {
                    FileVersions[i][j] = b.ReadUShort();
                }
            }
        }
Пример #11
0
        private void SetupMapIndices(CacheArchive archive)
        {
            var mapIdxStream = new DefaultJagexBuffer(archive.GetFile("map_index"));
            var size         = mapIdxStream.Capacity() / 7;

            Debug.Log("Map count: " + size);

            MapIndices       = new int[size];
            ObjectFileIds    = new int[size];
            LandscapeFileIds = new int[size];
            MapMembers       = new int[size];

            for (int i = 0; i < size; i++)
            {
                MapIndices[i]       = mapIdxStream.ReadUShort();
                ObjectFileIds[i]    = mapIdxStream.ReadUShort();
                LandscapeFileIds[i] = mapIdxStream.ReadUShort();
                mapIdxStream.ReadByte();
            }

            Debug.Log(mapIdxStream.Position() + " " + mapIdxStream.Capacity());
        }
Пример #12
0
        private void UpdatePlayerMask(int mask, int index, JagexBuffer b, Player p)
        {
            if ((mask & 0x400) != 0)
            {
                p.MoveStartX     = b.ReadUByteS();
                p.MoveStartY     = b.ReadUByteS();
                p.MoveEndX       = b.ReadUByteS();
                p.MoveEndY       = b.ReadUByteS();
                p.MoveCycleEnd   = b.ReadLEUShortA() + (int)GameContext.LoopCycle;
                p.MoveCycleStart = b.ReadUShortA() + (int)GameContext.LoopCycle;
                p.MoveDirection  = b.ReadUByteS();
                p.ResetQueuedMovements();
            }

            if ((mask & 0x100) != 0)
            {
                p.SpotAnimIndex = b.ReadLEUShort();
                var info = b.ReadInt();
                p.GraphicOffsetY   = info >> 16;
                p.SpotAnimCycleEnd = (int)GameContext.LoopCycle + (info & 0xffff);
                p.SpotAnimFrame    = 0;
                p.SpotAnimCycle    = 0;

                if (p.SpotAnimCycleEnd > GameContext.LoopCycle)
                {
                    p.SpotAnimFrame = -1;
                }

                if (p.SpotAnimIndex == 65535)
                {
                    p.SpotAnimIndex = -1;
                }
            }

            if ((mask & 8) != 0)
            {
                var seqIndex = b.ReadLEUShort();
                var delay    = b.ReadUByteC();
                if (seqIndex == 65535)
                {
                    seqIndex = -1;
                }

                var seq = GameContext.Cache.GetSeq(seqIndex);
                if (seq != null)
                {
                    if (seqIndex == p.SeqIndex && seqIndex != -1)
                    {
                        var type = seq.Type;
                        if (type == 1)
                        {
                            p.SeqFrame      = 0;
                            p.SeqCycle      = 0;
                            p.SeqDelayCycle = delay;
                            p.SeqResetCycle = 0;
                        }
                        else if (type == 2)
                        {
                            p.SeqResetCycle = 0;
                        }
                    }
                    else if (seqIndex == -1 || p.SeqIndex == -1 || (GameContext.Cache.GetSeq(p.SeqIndex) != null && seq.Priority >= GameContext.Cache.GetSeq(p.SeqIndex).Priority))
                    {
                        p.SeqIndex          = seqIndex;
                        p.SeqFrame          = 0;
                        p.SeqCycle          = 0;
                        p.SeqDelayCycle     = delay;
                        p.SeqResetCycle     = 0;
                        p.StillPathPosition = p.PathPosition;
                    }
                }
            }

            if ((mask & 4) != 0)
            {
                p.SpokenMessage = b.ReadString(10);

                if (p.SpokenMessage.ToCharArray()[0] == '~')
                {
                    p.SpokenMessage = p.SpokenMessage.Substring(1);
                    GameContext.Chat.Add(new ChatMessage(MessageType.Player, p.Name, p.SpokenMessage));
                }
                else if (p == GameContext.Self)
                {
                    GameContext.Chat.Add(new ChatMessage(MessageType.Player, p.Name, p.SpokenMessage));
                }

                p.SpokenColor  = 0;
                p.SpokenEffect = 0;
                p.SpokenLife   = 150;
            }

            if ((mask & 0x80) != 0)
            {
                var settings = b.ReadShort();
                var rights   = b.ReadByte();
                b.ReadByte();
                var length   = b.ReadUByteC();
                var startOff = b.Position();
                if (p.Name != null)
                {
                    var buf = new DefaultJagexBuffer(new byte[5000]);
                    b.ReadBytesReversed(buf.Array(), 0, length);
                    p.SpokenMessage = StringUtils.GetFormatted(length, buf);
                    p.SpokenEffect  = settings & 0xFF;
                    p.SpokenColor   = settings >> 8;
                    p.SpokenLife    = 150;

                    var sb = new StringBuilder();
                    sb.Append(p.Name);

                    var msg = new ChatMessage(MessageType.Player, sb.ToString(), p.SpokenMessage);
                    if (rights > 0)
                    {
                        msg.CrownIndex = rights;
                    }

                    GameContext.Chat.Add(msg);
                }

                b.Position(startOff + length);
            }

            if ((mask & 1) != 0)
            {
                p.FaceEntity = b.ReadLEUShort();

                if (p.FaceEntity == 65535)
                {
                    p.FaceEntity = -1;
                }
            }

            if ((mask & 0x10) != 0)
            {
                var payload = new byte[b.ReadUByteC()];
                b.ReadBytes(payload, 0, payload.Length);
                var pb = new DefaultJagexBuffer(payload);
                GameContext.PlayerBuffers[index] = pb;
                p.Update(pb);
            }

            if ((mask & 2) != 0)
            {
                p.FaceX = b.ReadLEUShortA();
                p.FaceY = b.ReadLEUShort();
            }

            if ((mask & 0x20) != 0)
            {
                var damage = b.ReadUShortA();
                var type   = b.ReadUByte();
                var icon   = b.ReadUByte();
                var soak   = b.ReadUShortA();
                p.QueueHit(type, damage, (int)GameContext.LoopCycle);
                p.CurrentHealth  = b.ReadUShortA();
                p.MaxHealth      = b.ReadUShortA();
                p.EndCombatCycle = (int)GameContext.LoopCycle + 300;
            }

            if ((mask & 0x200) != 0)
            {
                var damage = b.ReadUShortA();
                var type   = b.ReadUByte();
                var icon   = b.ReadUByte();
                var soak   = b.ReadUShortA();
                p.QueueHit(type, damage, (int)GameContext.LoopCycle);
                p.CurrentHealth  = b.ReadUShortA();
                p.MaxHealth      = b.ReadUShortA();
                p.EndCombatCycle = (int)GameContext.LoopCycle + 300;
            }
        }
Пример #13
0
        public BitmapFont(string name, CacheArchive archive)
        {
            Mask          = new int[256][];
            MaskWidth     = new int[256];
            MaskHeight    = new int[256];
            OffsetX       = new int[256];
            OffsetY       = new int[256];
            CharWidths    = new int[256];
            Strikethrough = false;

            var data = new DefaultJagexBuffer(archive.GetFile(name + ".dat"));
            var idx  = new DefaultJagexBuffer(archive.GetFile("index.dat"));

            idx.Position(data.ReadUShort() + 4);

            var offset = idx.ReadUByte();

            if (offset > 0)
            {
                idx.Position(idx.Position() + (3 * (offset - 1)));
            }

            for (var i = 0; i < 256; i++)
            {
                OffsetX[i] = idx.ReadByte();
                OffsetY[i] = idx.ReadByte();
                int width  = MaskWidth[i] = idx.ReadUShort();
                int height = MaskHeight[i] = idx.ReadUShort();
                int type   = idx.ReadUByte();
                Mask[i] = new int[width * height];

                if (type == 0)
                {
                    for (var j = 0; j < Mask[i].Length; j++)
                    {
                        Mask[i][j] = data.ReadByte();
                    }
                }
                else if (type == 1)
                {
                    for (var x = 0; x < width; x++)
                    {
                        for (var y = 0; y < height; y++)
                        {
                            Mask[i][x + y * width] = data.ReadByte();
                        }
                    }
                }

                if (height > CharHeight && i < 128)
                {
                    CharHeight = height;
                }

                OffsetX[i]    = 1;
                CharWidths[i] = (byte)(width + 2);

                var k2 = 0;
                for (var y = height / 7; y < height; y++)
                {
                    k2 += Mask[i][y * width];
                }

                if (k2 <= height / 7)
                {
                    CharWidths[i]--;
                    OffsetX[i] = 0;
                }

                k2 = 0;
                for (var y = height / 7; y < height; y++)
                {
                    k2 += Mask[i][(width - 1) + y * width];
                }

                if (k2 <= height / 7)
                {
                    CharWidths[i]--;
                }
            }

            if (name.Equals("q8_full"))
            {
                CharWidths[32] = CharWidths[73];
            }
            else
            {
                CharWidths[32] = CharWidths[105];
            }
        }
Пример #14
0
        public WidgetConfigProvider(CacheArchive archive)
        {
            var b = new DefaultJagexBuffer(archive.GetFile("data"));

            configs = new WidgetConfig[b.ReadUShort()];

            int parent = -1;

            while (b.Position() < b.Capacity())
            {
                int index = b.ReadUShort();

                if (index == 65535)
                {
                    parent = b.ReadUShort();
                    index  = b.ReadUShort();
                }

                var w = new WidgetConfig();

                w.Index      = index;
                w.Parent     = parent;
                w.Type       = b.ReadByte();
                w.OptionType = b.ReadByte();
                w.ActionType = b.ReadUShort();
                w.Width      = b.ReadUShort();
                w.Height     = b.ReadUShort();
                w.Opacity    = b.ReadUByte();
                w.HoverIndex = b.ReadUByte();

                if (w.HoverIndex != 0)
                {
                    w.HoverIndex = (w.HoverIndex - 1 << 8) + b.ReadUByte();
                }
                else
                {
                    w.HoverIndex = -1;
                }

                w.LoadScript(b);

                if (w.Type == 0)
                {
                    w.ScrollHeight = b.ReadUShort();
                    w.Hidden       = b.ReadByte() == 1;

                    var count = b.ReadUShort();
                    w.ChildIds = new int[count];
                    w.ChildX   = new int[count];
                    w.ChildY   = new int[count];

                    for (var i = 0; i < count; i++)
                    {
                        w.ChildIds[i] = b.ReadUShort();
                        w.ChildX[i]   = b.ReadUShort();
                        w.ChildY[i]   = b.ReadUShort();
                    }
                }

                if (w.Type == 2)
                {
                    w.ItemIndices      = new int[w.Width * w.Height];
                    w.ItemAmounts      = new int[w.Width * w.Height];
                    w.ItemsDraggable   = b.ReadByte() == 1;
                    w.ItemsHaveActions = b.ReadByte() == 1;
                    w.ItemsUsable      = b.ReadByte() == 1;
                    w.ItemsSwappable   = b.ReadByte() == 1;
                    w.ItemMarginX      = (short)b.ReadUByte();
                    w.ItemMarginY      = (short)b.ReadUByte();
                    w.ItemSlotX        = new int[20];
                    w.ItemSlotY        = new int[20];
                    w.SlotImage        = new string[20];

                    for (int i = 0; i < 20; i++)
                    {
                        if (b.ReadUByte() == 1)
                        {
                            w.ItemSlotX[i] = (short)b.ReadUShort();
                            w.ItemSlotY[i] = (short)b.ReadUShort();
                            var str = b.ReadString(10);

                            w.SlotImage[i] = str;
                        }
                    }

                    w.ItemActions = new string[5];
                    for (int i = 0; i < 5; i++)
                    {
                        w.ItemActions[i] = b.ReadString(10);
                        if (w.ItemActions[i].Length == 0)
                        {
                            w.ItemActions[i] = null;
                        }
                    }
                }

                if (w.Type == 3)
                {
                    w.Filled = b.ReadByte() == 1;
                }

                if (w.Type == 4 || w.Type == 1)
                {
                    w.Centered = b.ReadByte() == 1;
                    w.FontIdx  = b.ReadUByte();
                    w.Shadow   = b.ReadByte() == 1;
                }

                if (w.Type == 4)
                {
                    w.MessageDisabled = b.ReadString(10);
                    w.MessageEnabled  = b.ReadString(10);
                }

                if (w.Type == 1 || w.Type == 3 || w.Type == 4)
                {
                    w.RGBDisabled = b.ReadInt();
                }

                if (w.Type == 3 || w.Type == 4)
                {
                    w.RGBEnabled         = b.ReadInt();
                    w.ColorHoverDisabled = b.ReadInt();
                    w.ColorHoverEnabled  = b.ReadInt();
                }

                if (w.Type == 5)
                {
                    var str = b.ReadString(10);
                    if (str.Length > 0)
                    {
                        w.ImageDisabled = str;
                    }

                    str = b.ReadString(10);
                    if (str.Length > 0)
                    {
                        w.ImageEnabled = str;
                    }
                }

                if (w.Type == 6)
                {
                    int i = b.ReadUByte();
                    if (i != 0)
                    {
                        w.ModelTypeDisabled  = 1;
                        w.ModelIndexDisabled = (i - 1 << 8) + b.ReadUByte();
                    }

                    i = b.ReadUByte();
                    if (i != 0)
                    {
                        w.ModelTypeEnabled  = 1;
                        w.ModelIndexEnabled = (i - 1 << 8) + b.ReadUByte();
                    }

                    i = b.ReadUByte();
                    if (i != 0)
                    {
                        w.AnimationIndexDisabled = (i - 1 << 8) + b.ReadUByte();
                    }
                    else
                    {
                        w.AnimationIndexDisabled = -1;
                    }

                    i = b.ReadUByte();
                    if (i != 0)
                    {
                        w.AnimationIndexEnabled = (i - 1 << 8) + b.ReadUByte();
                    }
                    else
                    {
                        w.AnimationIndexEnabled = -1;
                    }

                    w.ModelZoom  = b.ReadUShort();
                    w.ModelPitch = b.ReadUShort();
                    w.ModelYaw   = b.ReadUShort();
                }

                if (w.Type == 7)
                {
                    w.ItemIndices      = new int[w.Width * w.Height];
                    w.ItemAmounts      = new int[w.Width * w.Height];
                    w.Centered         = b.ReadUByte() == 1;
                    w.FontIdx          = b.ReadUByte();
                    w.Shadow           = b.ReadByte() == 1;
                    w.RGBDisabled      = b.ReadInt();
                    w.ItemMarginX      = b.ReadUShort();
                    w.ItemMarginY      = b.ReadUShort();
                    w.ItemsHaveActions = b.ReadByte() == 1;
                    w.ItemActions      = new string[5];

                    for (var i = 0; i < 5; i++)
                    {
                        w.ItemActions[i] = b.ReadString(10);
                        if (w.ItemActions[i].Length == 0)
                        {
                            w.ItemActions[i] = null;
                        }
                    }
                }

                if (w.OptionType == 2 || w.Type == 2)
                {
                    w.OptionPrefix = b.ReadString(10);
                    w.OptionSuffix = b.ReadString(10);
                    w.OptionAction = b.ReadUShort();
                }

                if (w.OptionType == 1 || w.OptionType == 4 || w.OptionType == 5 || w.OptionType == 6)
                {
                    w.Option = b.ReadString(10);
                    if (w.Option.Length == 0)
                    {
                        if (w.OptionType == 1)
                        {
                            w.Option = "Ok";
                        }
                        if (w.OptionType == 4)
                        {
                            w.Option = "Select";
                        }
                        if (w.OptionType == 5)
                        {
                            w.Option = "Select";
                        }
                        if (w.OptionType == 6)
                        {
                            w.Option = "Continue";
                        }
                    }
                }

                configs[index] = w;
            }
        }
Пример #15
0
        public LoginResponse WriteAuthBlock(string username, string password)
        {
            var stream = client.GetStream();

            stream.ReadTimeout = 5000;

            var nameHash = StringUtils.StringToLong(username);
            var i        = (int)(nameHash >> 16 & 31L);

            var @out = new DefaultJagexBuffer(5000);

            @out.Position(0);
            @out.WriteByte(14);
            @out.WriteByte(i);
            stream.Write(@out.Array(), 0, @out.Position());
            @out.Position(0);
            stream.Flush();
            for (var j = 0; j < 8; j++)
            {
                stream.ReadByte();
            }

            int response = stream.ReadByte();

            if (response == 0)
            {
                InBuffer.Position(0);
                stream.Read(InBuffer.Array(), 0, 8);
                var serverSeed = InBuffer.ReadLong();

                var seed = new int[4];
                var rand = new System.Random();

                seed[0] = (int)(rand.NextDouble() * 9.9999999E7D);
                seed[1] = (int)(rand.NextDouble() * 9.9999999E7D);
                seed[2] = (int)(serverSeed >> 32);
                seed[3] = (int)(serverSeed);

                @out.Position(0);
                @out.WriteByte(10);
                @out.WriteInt(seed[0]);
                @out.WriteInt(seed[1]);
                @out.WriteInt(seed[2]);
                @out.WriteInt(seed[3]);
                @out.WriteInt(350 >> 2240);
                @out.WriteString(username, 10);
                @out.WriteString(password, 10);
                @out.WriteShort(222);
                @out.WriteByte(0);
                @out.RSA(GameConstants.LoginRsaExp, GameConstants.LoginRsaMod);

                wrapperBuffer.Position(0);
                wrapperBuffer.WriteByte(16);
                wrapperBuffer.WriteByte(@out.Position() + 36 + 1 + 2);
                wrapperBuffer.WriteByte(255);
                wrapperBuffer.WriteShort(13);
                wrapperBuffer.WriteByte(1);
                for (var j = 0; j < 9; j++)
                {
                    wrapperBuffer.WriteInt(0);
                }

                GameContext.OutCipher = new ISAACCipher(seed);
                for (var j = 0; j < seed.Length; j++)
                {
                    seed[j] += 50;
                }
                GameContext.InCipher = new ISAACCipher(seed);

                wrapperBuffer.WriteBytes(@out.Array(), 0, @out.Position());
                stream.Write(wrapperBuffer.Array(), 0, wrapperBuffer.Position());
                stream.Flush();

                response = stream.ReadByte();
                @out.Position(0);

                if (response == 2)
                {
                    GameContext.LocalRights = stream.ReadByte();
                    stream.ReadByte();
                    Connected = true;
                    return(LoginResponse.SuccessfulLogin);
                }
            }
            return(LoginResponse.Unknown);
        }
Пример #16
0
        public void Load(int findex, byte[] payload)
        {
            var s = new DefaultJagexBuffer(payload);

            s.Position(payload.Length - 8);

            int flagPos = s.ReadUShort();
            int modPos  = s.ReadUShort();
            int lenPos  = s.ReadUShort();
            int skinPos = s.ReadUShort();

            int position   = 0;
            var infoStream = new DefaultJagexBuffer(payload);

            infoStream.Position(position);

            position += flagPos + 2;
            var flagStream = new DefaultJagexBuffer(payload);

            flagStream.Position(position);

            position += modPos;
            var modifierStream = new DefaultJagexBuffer(payload);

            modifierStream.Position(position);

            position += lenPos;
            var lengthStream = new DefaultJagexBuffer(payload);

            lengthStream.Position(position);

            position += skinPos;
            var skinStream = new DefaultJagexBuffer(payload);

            skinStream.Position(position);

            var sl = new SkinList(skinStream);

            var count = infoStream.ReadUShort();
            var skins = new int[500];
            var vertX = new int[500];
            var vertY = new int[500];
            var vertZ = new int[500];

            for (var i = 0; i < count; i++)
            {
                var id = infoStream.ReadUShort();
                if (id >= instance.Length)
                {
                    continue;
                }

                var a = instance[id] = new SequenceFrame();
                a.Length   = lengthStream.ReadUByte();
                a.Skinlist = sl;

                var frameCount = infoStream.ReadUByte();
                var lastIdx    = -1;
                var frameIdx   = 0;
                for (var index = 0; index < frameCount; index++)
                {
                    var vertex_mask = flagStream.ReadUByte();
                    if (vertex_mask > 0)
                    {
                        if (sl.Opcodes[index] != 0)
                        {
                            for (var opp = index - 1; opp > lastIdx; opp--)
                            {
                                if (sl.Opcodes[opp] == 0)
                                {
                                    skins[frameIdx] = opp;
                                    vertX[frameIdx] = 0;
                                    vertY[frameIdx] = 0;
                                    vertZ[frameIdx] = 0;
                                    frameIdx++;
                                    break;
                                }
                            }
                        }

                        skins[frameIdx] = index;
                        var vertex = 0;
                        if (sl.Opcodes[index] == 3)
                        {
                            vertex = 128;
                        }

                        if ((vertex_mask & 1) != 0)
                        {
                            vertX[frameIdx] = modifierStream.ReadSmart();
                        }
                        else
                        {
                            vertX[frameIdx] = vertex;
                        }

                        if ((vertex_mask & 2) != 0)
                        {
                            vertY[frameIdx] = modifierStream.ReadSmart();
                        }
                        else
                        {
                            vertY[frameIdx] = vertex;
                        }

                        if ((vertex_mask & 4) != 0)
                        {
                            vertZ[frameIdx] = modifierStream.ReadSmart();
                        }
                        else
                        {
                            vertZ[frameIdx] = vertex;
                        }

                        lastIdx = index;
                        frameIdx++;
                    }
                }

                a.FrameCount = frameIdx;
                a.Vertices   = new int[frameIdx];
                a.VertexX    = new int[frameIdx];
                a.VertexY    = new int[frameIdx];
                a.VertexZ    = new int[frameIdx];
                for (var j = 0; j < frameIdx; j++)
                {
                    a.Vertices[j] = skins[j];
                    a.VertexX[j]  = vertX[j];
                    a.VertexY[j]  = vertY[j];
                    a.VertexZ[j]  = vertZ[j];
                }
            }
        }