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; } }
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; } }
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; } }