Exemple #1
0
        protected override IEnumerable <UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args)
        {
            List <ChunkHeader> list = new List <ChunkHeader>();
            UndoFormatEntry    pos;
            UndoCacheItem      item = default(UndoCacheItem);
            bool     super          = Player.IsSuper(args.Player);
            DateTime start          = args.Start;

            ReadHeaders(list, s);
            for (int i = list.Count - 1; i >= 0; i--)
            {
                ChunkHeader chunk = list[i];
                // Can we safely discard the entire chunk?
                bool inRange = chunk.BaseTime.AddTicks((65536 >> 2) * TimeSpan.TicksPerSecond) >= start;
                if (!inRange)
                {
                    args.Stop = true; yield break;
                }
                if (!super && !args.Player.level.name.CaselessEq(chunk.LevelName))
                {
                    continue;
                }
                pos.LevelName = chunk.LevelName;

                s.Seek(chunk.DataPosition, SeekOrigin.Begin);
                if (args.Temp == null)
                {
                    args.Temp = new byte[ushort.MaxValue * entrySize];
                }
                s.Read(args.Temp, 0, chunk.Entries * entrySize);
                byte[] temp = args.Temp;

                for (int j = chunk.Entries - 1; j >= 0; j--)
                {
                    int offset = j * entrySize;
                    item.Flags = U16(temp, offset + 0);
                    pos.Time   = chunk.BaseTime.AddTicks((item.Flags & 0x3FFF) * TimeSpan.TicksPerSecond);
                    if (pos.Time < start)
                    {
                        args.Stop = true; yield break;
                    }

                    int index = I32(temp, offset + 2);
                    pos.X = (ushort)(index % chunk.Width);
                    pos.Y = (ushort)((index / chunk.Width) / chunk.Length);
                    pos.Z = (ushort)((index / chunk.Width) % chunk.Length);

                    item.Type    = temp[offset + 6];
                    item.NewType = temp[offset + 7];
                    item.GetBlock(out pos.Block, out pos.ExtBlock);
                    item.GetNewBlock(out pos.NewBlock, out pos.NewExtBlock);
                    yield return(pos);
                }
            }
        }
Exemple #2
0
        protected override IEnumerable <UndoFormatEntry> GetEntries(Stream s, UndoFormatArgs args)
        {
            UndoCacheNode node = cache.Tail;

            if (node == null)
            {
                yield break;
            }

            UndoFormatEntry pos;
            bool            super = Player.IsSuper(args.Player);
            DateTime        start = args.Start;

            while (node != null)
            {
                Level lvl = LevelInfo.FindExact(node.MapName);
                if (!super && !args.Player.level.name.CaselessEq(node.MapName))
                {
                    node = node.Prev; continue;
                }
                List <UndoCacheItem> items = node.Items;
                pos.LevelName = node.MapName;

                for (int i = items.Count - 1; i >= 0; i--)
                {
                    UndoCacheItem item = items[i];
                    DateTime      time = node.BaseTime.AddTicks(item.TimeDelta * TimeSpan.TicksPerSecond);
                    if (time < start)
                    {
                        args.Stop = true; yield break;
                    }
                    pos.Time = time;

                    node.Unpack(item.Index, out pos.X, out pos.Y, out pos.Z);
                    item.GetBlock(out pos.Block, out pos.ExtBlock);
                    item.GetNewBlock(out pos.NewBlock, out pos.NewExtBlock);
                    yield return(pos);
                }
                node = node.Prev;
            }
        }