예제 #1
0
        protected override void ReadUndoData(List <Player.UndoPos> buffer, string path)
        {
            Player.UndoPos Pos;
            UndoCacheItem  item = default(UndoCacheItem);

            using (Stream fs = File.OpenRead(path))
                using (BinaryReader r = new BinaryReader(fs))
                {
                    int approxEntries = (int)(fs.Length / entrySize);
                    if (buffer.Capacity < approxEntries)
                    {
                        buffer.Capacity = approxEntries;
                    }
                    while (fs.Position < fs.Length)
                    {
                        ChunkHeader chunk = ReadHeader(fs, r);
                        Pos.mapName = chunk.LevelName;

                        for (int j = 0; j < chunk.Entries; j++)
                        {
                            item.Flags = r.ReadUInt16();
                            DateTime time = chunk.BaseTime.AddTicks((item.Flags & 0x3FFF) * TimeSpan.TicksPerSecond);
                            Pos.timeDelta = (int)time.Subtract(Server.StartTime).TotalSeconds;
                            int index = r.ReadInt32();
                            Pos.x = (ushort)(index % chunk.Width);
                            Pos.y = (ushort)((index / chunk.Width) / chunk.Length);
                            Pos.z = (ushort)((index / chunk.Width) % chunk.Length);

                            item.Type    = r.ReadByte();
                            item.NewType = r.ReadByte();
                            item.GetBlock(out Pos.type, out Pos.extType);
                            item.GetNewBlock(out Pos.newtype, out Pos.newExtType);
                            buffer.Add(Pos);
                        }
                    }
                }
        }
예제 #2
0
        protected override bool UndoEntry(Player p, string path, Vec3U16[] marks,
                                          ref byte[] temp, DateTime start)
        {
            List <ChunkHeader> list = new List <ChunkHeader>();
            int timeDelta           = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;

            Player.UndoPos Pos = default(Player.UndoPos);
            Vec3U16        min = marks[0], max = marks[1];
            bool           undoArea = min.X != ushort.MaxValue;
            UndoCacheItem  item     = default(UndoCacheItem);

            using (Stream fs = File.OpenRead(path))
                using (BinaryReader r = new BinaryReader(fs))
                {
                    ReadHeaders(list, r);
                    for (int i = list.Count - 1; i >= 0; i--)
                    {
                        ChunkHeader chunk = list[i];
                        Level       lvl;
                        if (!CheckChunk(chunk, start, p, out lvl))
                        {
                            return(false);
                        }
                        if (lvl == null || (p.level != null && !p.level.name.CaselessEq(lvl.name)))
                        {
                            continue;
                        }
                        BufferedBlockSender buffer = new BufferedBlockSender(lvl);
                        if (!undoArea)
                        {
                            min = new Vec3U16(0, 0, 0);
                            max = new Vec3U16((ushort)(lvl.Width - 1), (ushort)(lvl.Height - 1), (ushort)(lvl.Length - 1));
                        }

                        Pos.mapName = chunk.LevelName;
                        fs.Seek(chunk.DataPosition, SeekOrigin.Begin);
                        if (temp == null)
                        {
                            temp = new byte[ushort.MaxValue * entrySize];
                        }
                        fs.Read(temp, 0, chunk.Entries * entrySize);

                        for (int j = chunk.Entries - 1; j >= 0; j--)
                        {
                            int offset = j * entrySize;
                            item.Flags = U16(temp, offset + 0);
                            DateTime time = chunk.BaseTime.AddTicks((item.Flags & 0x3FFF) * TimeSpan.TicksPerSecond);
                            if (time < start)
                            {
                                buffer.CheckIfSend(true); return(false);
                            }

                            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);
                            if (Pos.x < min.X || Pos.y < min.Y || Pos.z < min.Z ||
                                Pos.x > max.X || Pos.y > max.Y || Pos.z > max.Z)
                            {
                                continue;
                            }

                            item.Type    = temp[offset + 6];
                            item.NewType = temp[offset + 7];
                            item.GetBlock(out Pos.type, out Pos.extType);
                            item.GetNewBlock(out Pos.newtype, out Pos.newExtType);
                            UndoBlock(p, lvl, Pos, timeDelta, buffer);
                        }
                        buffer.CheckIfSend(true);
                    }
                }
            return(true);
        }