Esempio n. 1
0
        public override void Perform(Vec3U16[] marks, Player p, Level lvl, Brush brush)
        {
            UndoCache     cache = p.UndoBuffer;
            UndoCacheNode node  = cache.Tail;

            if (node == null)
            {
                return;
            }
            int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;

            while (node != null)
            {
                lvl = LevelInfo.FindExact(node.MapName);
                if (lvl == null || (p.level != null && !p.level.name.CaselessEq(lvl.name)))
                {
                    node = node.Prev; continue;
                }
                List <UndoCacheItem> items  = node.Items;
                BufferedBlockSender  buffer = new BufferedBlockSender(lvl);

                for (int i = items.Count - 1; i >= 0; i--)
                {
                    UndoCacheItem item = items[i];
                    ushort        x, y, z;
                    node.Unpack(item.Index, out x, out y, out z);

                    DateTime time = node.BaseTime.AddTicks(item.TimeDelta * TimeSpan.TicksPerSecond);
                    if (time > End)
                    {
                        continue;
                    }
                    if (time < Start)
                    {
                        buffer.CheckIfSend(true); return;
                    }

                    byte tile, extTile;
                    item.GetBlock(out tile, out extTile);
                    if (lvl.DoBlockchange(p, x, y, z, tile, extTile))
                    {
                        buffer.Add(lvl.PosToInt(x, y, z), tile, extTile);
                        buffer.CheckIfSend(false);
                    }
                }
                buffer.CheckIfSend(true);
                node = node.Prev;
            }
        }
Esempio n. 2
0
        static void PerformHighlight(Player p, long seconds, UndoCache cache)
        {
            UndoCacheNode node = cache.Tail;

            if (node == null)
            {
                return;
            }

            while (node != null)
            {
                Level lvl = LevelInfo.FindExact(node.MapName);
                if (lvl != p.level)
                {
                    node = node.Prev; continue;
                }
                List <UndoCacheItem> items = node.Items;

                for (int i = items.Count - 1; i >= 0; i--)
                {
                    UndoCacheItem item = items[i];
                    ushort        x, y, z;
                    node.Unpack(item.Index, out x, out y, out z);
                    DateTime time = node.BaseTime.AddSeconds(item.TimeDelta + seconds);
                    if (time < DateTime.UtcNow)
                    {
                        return;
                    }

                    byte newTile = 0, newExtTile = 0;
                    item.GetNewBlock(out newTile, out newExtTile);
                    p.SendBlockchange(x, y, z, newTile == Block.air ? Block.red : Block.green);
                }
                node = node.Prev;
            }
        }
Esempio n. 3
0
        void PerformUndo(Player p, ref Level saveLvl)
        {
            UndoCache     cache = who.UndoBuffer;
            UndoCacheNode node  = cache.Tail;

            if (node == null)
            {
                return;
            }

            Vec3U16 min = Min, max = Max;
            bool    undoArea = min.X != ushort.MaxValue;

            Player.UndoPos Pos       = default(Player.UndoPos);
            int            timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;

            while (node != null)
            {
                Level lvl = LevelInfo.FindExact(node.MapName);
                if (lvl == null || (p.level != null && !p.level.name.CaselessEq(lvl.name)))
                {
                    node = node.Prev; continue;
                }
                Pos.mapName = lvl.name;

                saveLvl = lvl;
                List <UndoCacheItem> items  = node.Items;
                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));
                }

                for (int i = items.Count - 1; i >= 0; i--)
                {
                    UndoCacheItem item = items[i];
                    node.Unpack(item.Index, out Pos.x, out Pos.y, out Pos.z);
                    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;
                    }

                    DateTime time = node.BaseTime.AddTicks(item.TimeDelta * TimeSpan.TicksPerSecond);
                    if (time > End)
                    {
                        continue;
                    }
                    if (time < Start)
                    {
                        buffer.CheckIfSend(true); return;
                    }

                    item.GetNewBlock(out Pos.newtype, out Pos.newExtType);
                    item.GetBlock(out Pos.type, out Pos.extType);
                    UndoFile.UndoBlock(p, lvl, Pos, timeDelta, buffer);
                }
                buffer.CheckIfSend(true);
                node = node.Prev;
            }
        }