diff --git a/Drawing/DrawOps/RedoDrawOp.cs b/Drawing/DrawOps/RedoDrawOp.cs index 51ae04706..54e4a5e62 100644 --- a/Drawing/DrawOps/RedoDrawOp.cs +++ b/Drawing/DrawOps/RedoDrawOp.cs @@ -37,43 +37,19 @@ namespace MCGalaxy.Drawing.Ops { public override IEnumerable Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { UndoCache cache = p.UndoBuffer; using (IDisposable locker = cache.ClearLock.AccquireReadLock()) { - RedoBlocks(p); + if (RedoBlocks(p)) yield break; } + + bool found = false; + UndoFormat.DoRedo(p, p.name.ToLower(), Start, End, ref found); yield break; } - void RedoBlocks(Player p) { - UndoCache cache = p.UndoBuffer; - UndoCacheNode node = p.UndoBuffer.Tail; - if (node == null) return; - - 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; - } - List 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, true)) { - buffer.Add(lvl.PosToInt(x, y, z), tile, extTile); - buffer.CheckIfSend(false); - } - } - buffer.CheckIfSend(true); - node = node.Prev; - } + bool RedoBlocks(Player p) { + UndoFormatArgs args = new UndoFormatArgs(p, Start); + UndoFormat format = new UndoFormatOnline(p.UndoBuffer); + UndoFormat.DoRedo(null, End, format, args); + return args.Stop; } } } diff --git a/Drawing/DrawOps/UndoDrawOp.cs b/Drawing/DrawOps/UndoDrawOp.cs index 65483f4e5..e349bc603 100644 --- a/Drawing/DrawOps/UndoDrawOp.cs +++ b/Drawing/DrawOps/UndoDrawOp.cs @@ -44,7 +44,7 @@ namespace MCGalaxy.Drawing.Ops { UndoCache cache = p.UndoBuffer; using (IDisposable locker = cache.ClearLock.AccquireReadLock()) { if (UndoBlocks(p)) yield break; - } + } bool found = false; string target = who.name.ToLower(); diff --git a/Player/Undo/UndoFormat.Helpers.cs b/Player/Undo/UndoFormat.Helpers.cs index db0e02b06..74e40e0fd 100644 --- a/Player/Undo/UndoFormat.Helpers.cs +++ b/Player/Undo/UndoFormat.Helpers.cs @@ -127,6 +127,37 @@ namespace MCGalaxy.Undo { } + public static void DoRedo(Player p, string target, + DateTime start, DateTime end, ref bool found) { + List files = GetUndoFiles(target); + UndoFormatArgs args = new UndoFormatArgs(p, start); + + foreach (string file in files) { + found = true; + using (Stream s = File.OpenRead(file)) { + DoRedo(s, end, GetFormat(file), args); + if (args.Stop) break; + } + } + } + + public static void DoRedo(Stream s, DateTime end, + UndoFormat format, UndoFormatArgs args) { + Level lvl = args.Player.level; + BufferedBlockSender buffer = new BufferedBlockSender(lvl); + Player p = args.Player; + + foreach (UndoFormatEntry P in format.GetEntries(s, args)) { + if (P.Time > end) continue; + if (!lvl.DoBlockchange(p, P.X, P.Y, P.Z, P.Block, P.ExtBlock, true)) continue; + + buffer.Add(lvl.PosToInt(P.X, P.Y, P.Z), P.Block, P.ExtBlock); + buffer.CheckIfSend(false); + } + buffer.CheckIfSend(true); + } + + public static void UpgradePlayerUndoFiles(string name) { UpgradeFiles(undoDir, name); UpgradeFiles(prevUndoDir, name);