Make UndoFile more modular, so now we access an online player's undo buffer the same way as offline undo binary files.

This commit is contained in:
UnknownShadow200 2016-08-20 14:02:30 +10:00
parent 4fefcf14e0
commit cdc5619f9d
15 changed files with 141 additions and 96 deletions

View File

@ -18,7 +18,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy.Commands {
@ -33,7 +33,7 @@ namespace MCGalaxy.Commands {
public override void Use(Player p, string message) {
long seconds;
bool FoundUser = false;
bool found = false;
if (Player.IsSuper(p)) { MessageInGameOnly(p); return; }
if (message == "") message = p.name + " 300";
string[] args = message.Split(' ');
@ -49,19 +49,20 @@ namespace MCGalaxy.Commands {
seconds = 300;
}
if (seconds <= 0) seconds = 5400;
DateTime start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
Player who = PlayerInfo.Find(name);
bool done = false;
if (who != null) {
FoundUser = true;
found = true;
UndoCache cache = who.UndoBuffer;
using (IDisposable locker = cache.ClearLock.AccquireReadLock()) {
HighlightBlocks(p, seconds, cache);
done = HighlightBlocks(p, start, cache);
}
}
DateTime start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
UndoFile.HighlightPlayer(p, name.ToLower(), start, ref FoundUser);
if (FoundUser) {
}
if (!done) UndoFormat.HighlightPlayer(p, name.ToLower(), start, ref found);
if (found) {
Player.Message(p, "Now highlighting &b" + seconds + " %Sseconds for " + Server.FindColor(name) + name);
Player.Message(p, "&cUse /reload to un-highlight");
} else {
@ -69,34 +70,12 @@ namespace MCGalaxy.Commands {
}
}
static void HighlightBlocks(Player p, long seconds, UndoCache cache) {
UndoCacheNode node = cache.Tail;
if (node == null) return;
BufferedBlockSender sender = new BufferedBlockSender(p);
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) { sender.CheckIfSend(true); return; }
byte newBlock = 0, newExtBlock = 0;
item.GetNewBlock(out newBlock, out newExtBlock);
int index = lvl.PosToInt(x, y, z);
byte highlightBlock = newBlock == Block.air ? Block.red : Block.green;
sender.Add(index, highlightBlock, 0);
sender.CheckIfSend(false);
}
node = node.Prev;
}
sender.CheckIfSend(true);
static bool HighlightBlocks(Player p, DateTime start, UndoCache cache) {
UndoEntriesArgs args = new UndoEntriesArgs(p, start);
UndoFormatOnline format = new UndoFormatOnline();
format.Cache = cache;
UndoFormat.DoHighlight(null, format, args);
return args.Stop;
}
public override void Help(Player p) {

View File

@ -17,7 +17,7 @@
*/
using System;
using MCGalaxy.Drawing.Ops;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy.Commands.Building {
public sealed class CmdRedo : Command {

View File

@ -17,7 +17,7 @@
*/
using System;
using MCGalaxy.Drawing.Ops;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy.Commands.Building {
public sealed class CmdUndo : Command {
@ -51,7 +51,7 @@ namespace MCGalaxy.Commands.Building {
long seconds = GetSeconds(p, who, parts.Length > 1 ? parts[1] : "30");
if (parts.Length > 1 && parts[1].CaselessEq("update")) {
UndoFile.UpgradePlayerUndoFiles(parts[0]);
UndoFormat.UpgradePlayerUndoFiles(parts[0]);
Player.Message(p, "Updated undo files for " + parts[0] + " to the new binary format.");
return;
}

View File

@ -20,7 +20,7 @@ using MCGalaxy.BlockPhysics;
using MCGalaxy.Commands;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Drawing.Ops;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy.Drawing {
internal struct PendingDrawOp {

View File

@ -19,7 +19,7 @@ using System;
using System.Collections.Generic;
using MCGalaxy.BlockPhysics;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy.Drawing.Ops {

View File

@ -19,7 +19,7 @@ using System;
using System.Collections.Generic;
using MCGalaxy.BlockPhysics;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy.Drawing.Ops {
@ -49,7 +49,7 @@ namespace MCGalaxy.Drawing.Ops {
bool foundUser = false;
Vec3S32[] bounds = { Min, Max };
UndoFile.UndoPlayer(p, who.name.ToLower(), bounds, Start, ref foundUser);
UndoFormat.UndoPlayer(p, who.name.ToLower(), bounds, Start, ref foundUser);
yield break;
}
@ -90,7 +90,7 @@ namespace MCGalaxy.Drawing.Ops {
item.GetNewBlock(out Pos.newtype, out Pos.newExtType);
item.GetBlock(out Pos.type, out Pos.extType);
UndoFile.UndoBlock(p, lvl, Pos, timeDelta, buffer);
UndoFormat.UndoBlock(p, lvl, Pos, timeDelta, buffer);
}
buffer.CheckIfSend(true);
node = node.Prev;
@ -112,7 +112,7 @@ namespace MCGalaxy.Drawing.Ops {
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3S32[] bounds = { Min, Max };
UndoFile.UndoPlayer(p, whoName.ToLower(), bounds, Start, ref foundUser);
UndoFormat.UndoPlayer(p, whoName.ToLower(), bounds, Start, ref foundUser);
yield break;
}
}

View File

@ -541,12 +541,13 @@
<Compile Include="Player\PlayerInfo.cs" />
<Compile Include="Player\TabList.cs" />
<Compile Include="Player\Undo\UndoCache.cs" />
<Compile Include="Player\Undo\UndoFileCBin.cs" />
<Compile Include="Player\Undo\UndoFormatCBin.cs" />
<Compile Include="Player\Undo\UndoFormatOnline.cs" />
<Compile Include="Player\Warp.cs" />
<Compile Include="Player\Player.Timers.cs" />
<Compile Include="Player\Undo\UndoFile.cs" />
<Compile Include="Player\Undo\UndoFileBin.cs" />
<Compile Include="Player\Undo\UndoFileText.cs" />
<Compile Include="Player\Undo\UndoFormat.cs" />
<Compile Include="Player\Undo\UndoFormatBin.cs" />
<Compile Include="Player\Undo\UndoFormatText.cs" />
<Compile Include="Plugins\Events\Enums.cs" />
<Compile Include="Plugins\Events\GroupEvents.cs" />
<Compile Include="Plugins\Events\IPluginEvent.cs" />

View File

@ -18,7 +18,7 @@ using System.Net.Sockets;
using System.Security.Cryptography;
using MCGalaxy.Drawing;
using MCGalaxy.Games;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy {

View File

@ -20,7 +20,7 @@ using System.Net.Sockets;
using System.Threading;
using MCGalaxy.Games;
using MCGalaxy.SQL;
using MCGalaxy.Util;
using MCGalaxy.Undo;
namespace MCGalaxy {
public sealed partial class Player : IDisposable {
@ -345,7 +345,7 @@ namespace MCGalaxy {
public static void SaveUndo(Player p) {
try {
UndoFile.SaveUndo(p);
UndoFormat.SaveUndo(p);
} catch (Exception e) {
Server.s.Log("Error saving undo data for " + p.name + "!"); Server.ErrorLog(e);
}

View File

@ -20,7 +20,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
namespace MCGalaxy.Util {
namespace MCGalaxy.Undo {
public sealed class UndoCache {

View File

@ -18,32 +18,19 @@
using System;
using System.Collections.Generic;
using System.IO;
using MCGalaxy.Drawing;
namespace MCGalaxy.Util {
namespace MCGalaxy.Undo {
public abstract class UndoFile {
public abstract class UndoFormat {
protected const string undoDir = "extra/undo", prevUndoDir = "extra/undoPrevious";
public static UndoFile TxtFormat = new UndoFileText();
public static UndoFile BinFormat = new UndoFileBin();
public static UndoFile NewFormat = new UndoFileCBin();
public static UndoFormat TxtFormat = new UndoFormatText();
public static UndoFormat BinFormat = new UndoFormatBin();
public static UndoFormat NewFormat = new UndoFormatCBin();
protected class UndoEntriesArgs {
public Player Player;
public byte[] Temp;
public bool Stop;
public DateTime StartRange;
public UndoEntriesArgs(Player p, DateTime start) {
Player = p;
StartRange = start;
}
}
protected abstract void Save(List<Player.UndoPos> buffer, string path);
protected abstract void SaveUndoData(List<Player.UndoPos> buffer, string path);
protected abstract void SaveUndoData(UndoCache buffer, string path);
protected abstract void Save(UndoCache buffer, string path);
protected abstract IEnumerable<Player.UndoPos> GetEntries(Stream s, UndoEntriesArgs args);
@ -68,7 +55,7 @@ namespace MCGalaxy.Util {
UndoCache cache = p.UndoBuffer;
using (IDisposable locker = cache.ClearLock.AccquireReadLock()) {
NewFormat.SaveUndoData(cache, path);
NewFormat.Save(cache, path);
}
using (IDisposable locker = cache.ClearLock.AccquireWriteLock()) {
@ -94,7 +81,7 @@ namespace MCGalaxy.Util {
return;
string[] files = Directory.GetFiles(path);
Array.Sort<string>(files, CompareFiles);
UndoEntriesArgs args = new UndoFile.UndoEntriesArgs(p, start);
UndoEntriesArgs args = new UndoEntriesArgs(p, start);
for (int i = files.Length - 1; i >= 0; i--) {
path = files[i];
@ -102,7 +89,7 @@ namespace MCGalaxy.Util {
if (file.Length == 0 || file[0] < '0' || file[0] > '9')
continue;
UndoFile format = null;
UndoFormat format = null;
if (path.EndsWith(TxtFormat.Ext)) format = TxtFormat;
if (path.EndsWith(BinFormat.Ext)) format = BinFormat;
if (path.EndsWith(NewFormat.Ext)) format = NewFormat;
@ -110,7 +97,7 @@ namespace MCGalaxy.Util {
using (Stream s = File.OpenRead(path)) {
if (highlight) {
DoHighlight(s, format, args);
DoHighlight(s, format, args);
} else {
// TODO: fixy fix if (!format.UndoEntry(p, path, marks, ref temp, start)) break;
}
@ -162,16 +149,16 @@ namespace MCGalaxy.Util {
}
}
static void DoHighlight(Stream s, UndoFile format, UndoEntriesArgs args) {
public static void DoHighlight(Stream s, UndoFormat format, UndoEntriesArgs args) {
BufferedBlockSender buffer = new BufferedBlockSender(args.Player);
Level lvl = args.Player.level;
foreach (Player.UndoPos P in format.GetEntries(s, args)) {
byte type = P.type, newType = P.newtype;
byte block = (newType == Block.air
|| Block.Convert(type) == Block.water || type == Block.waterstill
|| Block.Convert(type) == Block.lava || type == Block.lavastill)
? Block.red : Block.green;
|| Block.Convert(type) == Block.water || type == Block.waterstill
|| Block.Convert(type) == Block.lava || type == Block.lavastill)
? Block.red : Block.green;
buffer.Add(lvl.PosToInt(P.x, P.y, P.z), block, 0);
buffer.CheckIfSend(false);
@ -205,7 +192,7 @@ namespace MCGalaxy.Util {
IEnumerable<Player.UndoPos> data = null;
using (FileStream s = File.OpenRead(path)) {
data = path.EndsWith(BinFormat.Ext)
data = path.EndsWith(BinFormat.Ext)
? BinFormat.GetEntries(s, args)
: TxtFormat.GetEntries(s, args);
@ -213,10 +200,22 @@ namespace MCGalaxy.Util {
buffer.Add(pos);
buffer.Reverse();
string newPath = Path.ChangeExtension(path, NewFormat.Ext);
NewFormat.SaveUndoData(buffer, newPath);
NewFormat.Save(buffer, newPath);
}
File.Delete(path);
}
}
}
public class UndoEntriesArgs {
public Player Player;
public byte[] Temp;
public bool Stop;
public DateTime StartRange;
public UndoEntriesArgs(Player p, DateTime start) {
Player = p;
StartRange = start;
}
}
}

View File

@ -20,18 +20,18 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
namespace MCGalaxy.Util {
namespace MCGalaxy.Undo {
public sealed class UndoFileBin : UndoFile {
public sealed class UndoFormatBin : UndoFormat {
protected override string Ext { get { return ".unbin"; } }
const int entrySize = 12;
protected override void SaveUndoData(List<Player.UndoPos> buffer, string path) {
protected override void Save(List<Player.UndoPos> buffer, string path) {
throw new NotSupportedException("Non-optimised binary undo files have been deprecated");
}
protected override void SaveUndoData(UndoCache buffer, string path) {
protected override void Save(UndoCache buffer, string path) {
throw new NotSupportedException("Non-optimised binary undo files have been deprecated");
}

View File

@ -21,14 +21,14 @@ using System.IO;
using System.Text;
using MCGalaxy.Levels.IO;
namespace MCGalaxy.Util {
namespace MCGalaxy.Undo {
public sealed class UndoFileCBin : UndoFile {
public sealed class UndoFormatCBin : UndoFormat {
protected override string Ext { get { return ".uncbin"; } }
const int entrySize = 8;
protected override void SaveUndoData(List<Player.UndoPos> buffer, string path) {
protected override void Save(List<Player.UndoPos> buffer, string path) {
UndoCacheNode node = new UndoCacheNode();
string lastLoggedName = "";
@ -68,7 +68,7 @@ namespace MCGalaxy.Util {
}
}
protected override void SaveUndoData(UndoCache buffer, string path) {
protected override void Save(UndoCache buffer, string path) {
using (FileStream fs = File.Create(path)) {
BinaryWriter w = new BinaryWriter(fs);
long entriesPos = 0;

View File

@ -0,0 +1,66 @@
/*
Copyright 2015 MCGalaxy
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using System.IO;
namespace MCGalaxy.Undo {
public sealed class UndoFormatOnline : UndoFormat {
protected override string Ext { get { return null; } }
public UndoCache Cache;
protected override void Save(List<Player.UndoPos> buffer, string path) {
throw new NotSupportedException("UndoFileOnline is read only.");
}
protected override void Save(UndoCache buffer, string path) {
throw new NotSupportedException("UndoFileOnline is read only.");
}
protected override IEnumerable<Player.UndoPos> GetEntries(Stream s, UndoEntriesArgs args) {
UndoCacheNode node = Cache.Tail;
if (node == null) yield break;
Player.UndoPos pos;
bool super = args.Player == null || args.Player.ircNick != null;
DateTime start = args.StartRange;
while (node != null) {
Level lvl = LevelInfo.FindExact(node.MapName);
if (!super && !args.Player.level.name.CaselessEq(node.MapName)) continue;
List<UndoCacheItem> items = node.Items;
pos.mapName = 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.timeDelta = (int)time.Subtract(Server.StartTime).TotalSeconds;
node.Unpack(item.Index, out pos.x, out pos.y, out pos.z);
item.GetBlock(out pos.type, out pos.extType);
item.GetNewBlock(out pos.newtype, out pos.newExtType);
yield return pos;
}
node = node.Prev;
}
}
}
}

View File

@ -20,17 +20,17 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace MCGalaxy.Util {
namespace MCGalaxy.Undo {
public sealed class UndoFileText : UndoFile {
public sealed class UndoFormatText : UndoFormat {
protected override string Ext { get { return ".undo"; } }
protected override void SaveUndoData(List<Player.UndoPos> buffer, string path) {
protected override void Save(List<Player.UndoPos> buffer, string path) {
throw new NotSupportedException("Text undo files have been deprecated");
}
protected override void SaveUndoData(UndoCache buffer, string path) {
protected override void Save(UndoCache buffer, string path) {
throw new NotSupportedException("Text undo files have been deprecated");
}