mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
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:
parent
4fefcf14e0
commit
cdc5619f9d
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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" />
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
66
Player/Undo/UndoFormatOnline.cs
Normal file
66
Player/Undo/UndoFormatOnline.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user