mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-26 06:43:25 -04:00
Update /undo and /highlight code to work between a given start and end time.
This commit is contained in:
parent
5c31e47667
commit
764bc394be
@ -56,7 +56,8 @@ namespace MCGalaxy.Commands {
|
||||
PerformHighlight(p, seconds, who.UndoBuffer);
|
||||
}
|
||||
|
||||
UndoFile.HighlightPlayer(p, name.ToLower(), seconds, ref FoundUser);
|
||||
DateTime start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
||||
UndoFile.HighlightPlayer(p, name.ToLower(), start, ref FoundUser);
|
||||
if (FoundUser) {
|
||||
Player.SendMessage(p, "Now highlighting &b" + seconds + " %Sseconds for " + Server.FindColor(name) + name);
|
||||
Player.SendMessage(p, "&cUse /reload to un-highlight");
|
||||
|
@ -94,7 +94,7 @@ namespace MCGalaxy.Commands
|
||||
}
|
||||
|
||||
UndoOnlineDrawOp op = new UndoOnlineDrawOp();
|
||||
op.seconds = seconds;
|
||||
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
||||
op.who = who;
|
||||
op.Perform(null, p, null, null);
|
||||
|
||||
@ -114,7 +114,7 @@ namespace MCGalaxy.Commands
|
||||
}
|
||||
|
||||
UndoOfflineDrawOp op = new UndoOfflineDrawOp();
|
||||
op.seconds = seconds;
|
||||
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
||||
op.whoName = whoName;
|
||||
op.Perform(null, p, null, null);
|
||||
|
||||
|
@ -160,20 +160,18 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
UndoDrawOpEntry entry = new UndoDrawOpEntry();
|
||||
entry.DrawOpName = op.Name;
|
||||
entry.LevelName = p.level.name;
|
||||
entry.SetStart(p);
|
||||
DateTime start = DateTime.UtcNow;
|
||||
entry.Start = DateTime.UtcNow;
|
||||
|
||||
bool needReveal = op.DetermineDrawOpMethod(p.level, affected);
|
||||
op.Perform(marks, p, p.level, brush);
|
||||
entry.SetEnd(p);
|
||||
entry.End = DateTime.UtcNow;
|
||||
|
||||
if (start > p.UndoBuffer.LastClear) {
|
||||
if (entry.Start > p.UndoBuffer.LastClear) {
|
||||
UndoDrawOpEntry[] items = p.UndoDrawOps.Items;
|
||||
if (items.Length == 20)
|
||||
p.UndoDrawOps.Remove(items[0]);
|
||||
} else { // UndoBuffer has been cleared during the draw op.
|
||||
entry.StartNode = p.UndoBuffer.Head;
|
||||
entry.StartIndex = 0;
|
||||
entry.Start = p.UndoBuffer.LastClear;
|
||||
p.RemoveInvalidUndos();
|
||||
}
|
||||
p.UndoDrawOps.Add(entry);
|
||||
|
@ -26,7 +26,12 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
|
||||
public override string Name { get { return "UndoOnline"; } }
|
||||
|
||||
internal long seconds;
|
||||
/// <summary> Point in time that the /undo should go backwards up to. </summary>
|
||||
public DateTime Start = DateTime.MinValue;
|
||||
|
||||
/// <summary> Point in time that the /undo should start updating blocks. </summary>
|
||||
public DateTime End = DateTime.MaxValue;
|
||||
|
||||
internal Player who;
|
||||
internal Level saveLevel = null;
|
||||
|
||||
@ -35,7 +40,7 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
|
||||
PerformUndo(p, ref saveLevel);
|
||||
bool foundUser = false;
|
||||
UndoFile.UndoPlayer(p, who.name.ToLower(), seconds, ref foundUser);
|
||||
UndoFile.UndoPlayer(p, who.name.ToLower(), Start, ref foundUser);
|
||||
}
|
||||
|
||||
void PerformUndo(Player p, ref Level saveLvl) {
|
||||
@ -54,8 +59,9 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
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 + seconds) * TimeSpan.TicksPerSecond);
|
||||
if (time < DateTime.UtcNow) { buffer.CheckIfSend(true); return; }
|
||||
DateTime time = node.BaseTime.AddTicks(item.TimeDelta * TimeSpan.TicksPerSecond);
|
||||
if (time > End) continue;
|
||||
if (time < Start) { buffer.CheckIfSend(true); return; }
|
||||
|
||||
byte b = lvl.GetTile(x, y, z);
|
||||
byte newTile = 0, newExtTile = 0;
|
||||
@ -91,14 +97,16 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
|
||||
public override string Name { get { return "UndoOffline"; } }
|
||||
|
||||
internal long seconds;
|
||||
/// <summary> Point in time that the /undo should go backwards up to. </summary>
|
||||
public DateTime Start = DateTime.MinValue;
|
||||
|
||||
internal string whoName;
|
||||
internal bool foundUser = false;
|
||||
|
||||
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) { return 0; }
|
||||
|
||||
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
|
||||
UndoFile.UndoPlayer(p, whoName.ToLower(), seconds, ref foundUser);
|
||||
UndoFile.UndoPlayer(p, whoName.ToLower(), Start, ref foundUser);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,7 +480,6 @@
|
||||
<Compile Include="Player\Player.Handlers.cs" />
|
||||
<Compile Include="Player\PlayerInfo.cs" />
|
||||
<Compile Include="Player\Undo\UndoCache.cs" />
|
||||
<Compile Include="Player\Undo\UndoDrawOpEntry.cs" />
|
||||
<Compile Include="Player\Waypoint.cs" />
|
||||
<Compile Include="Player\Player.Timers.cs" />
|
||||
<Compile Include="Player\Undo\UndoFile.cs" />
|
||||
|
@ -951,7 +951,7 @@ Next: continue;
|
||||
internal void RemoveInvalidUndos() {
|
||||
UndoDrawOpEntry[] items = UndoDrawOps.Items;
|
||||
for (int i = 0; i < items.Length; i++) {
|
||||
if (!items[i].IsValid(this))
|
||||
if (items[i].End < UndoBuffer.LastClear)
|
||||
UndoDrawOps.Remove(items[i]);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace MCGalaxy.Util {
|
||||
|
||||
@ -101,7 +100,7 @@ namespace MCGalaxy.Util {
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct UndoCacheItem {
|
||||
public int Index;
|
||||
public byte Type, NewType;
|
||||
public byte Type, NewType;
|
||||
public ushort Flags; // upper 2 bits for 'ext' or 'physics' type, lower 14 bits for time delta.
|
||||
|
||||
public short TimeDelta {
|
||||
@ -141,7 +140,7 @@ namespace MCGalaxy.Util {
|
||||
item.Flags |= (ushort)(1 << 14);
|
||||
} else {
|
||||
item.Type = pos.type;
|
||||
}
|
||||
}
|
||||
if (pos.newtype == Block.custom_block) {
|
||||
item.NewType = pos.newExtType;
|
||||
item.Flags |= (ushort)(1 << 15);
|
||||
@ -151,4 +150,10 @@ namespace MCGalaxy.Util {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class UndoDrawOpEntry {
|
||||
public string DrawOpName;
|
||||
public string LevelName;
|
||||
public DateTime Start, End;
|
||||
}
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
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;
|
||||
|
||||
namespace MCGalaxy.Util {
|
||||
|
||||
public class UndoDrawOpEntry {
|
||||
|
||||
public string DrawOpName;
|
||||
public string LevelName;
|
||||
public UndoCacheNode StartNode;
|
||||
public int StartIndex;
|
||||
public UndoCacheNode EndNode;
|
||||
public int EndIndex;
|
||||
|
||||
public void SetStart(Player p) {
|
||||
StartNode = p.UndoBuffer.Tail;
|
||||
if (StartNode != null)
|
||||
StartIndex = StartNode.Items.Count;
|
||||
}
|
||||
|
||||
public void SetEnd(Player p) {
|
||||
EndNode = p.UndoBuffer.Tail;
|
||||
if (EndNode != null)
|
||||
EndIndex = EndNode.Items.Count;
|
||||
}
|
||||
|
||||
public bool IsValid(Player p) {
|
||||
UndoCache buffer = p.UndoBuffer;
|
||||
if (p.UndoBuffer.Tail == null) return false;
|
||||
|
||||
UndoCacheNode node = p.UndoBuffer.Tail;
|
||||
while ((node = node.Prev) != null) {
|
||||
if (node == EndNode) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -34,9 +34,9 @@ namespace MCGalaxy.Util {
|
||||
|
||||
protected abstract void ReadUndoData(List<Player.UndoPos> buffer, string path);
|
||||
|
||||
protected abstract bool UndoEntry(Player p, string path, ref byte[] temp, long seconds);
|
||||
protected abstract bool UndoEntry(Player p, string path, ref byte[] temp, DateTime start);
|
||||
|
||||
protected abstract bool HighlightEntry(Player p, string path, ref byte[] temp, long seconds);
|
||||
protected abstract bool HighlightEntry(Player p, string path, ref byte[] temp, DateTime start);
|
||||
|
||||
protected abstract string Extension { get; }
|
||||
|
||||
@ -59,17 +59,17 @@ namespace MCGalaxy.Util {
|
||||
NewFormat.SaveUndoData(p.UndoBuffer, path);
|
||||
}
|
||||
|
||||
public static void UndoPlayer(Player p, string targetName, long seconds, ref bool FoundUser) {
|
||||
FilterEntries(p, undoDir, targetName, seconds, false, ref FoundUser);
|
||||
FilterEntries(p, prevUndoDir, targetName, seconds, false, ref FoundUser);
|
||||
public static void UndoPlayer(Player p, string targetName, DateTime start, ref bool FoundUser) {
|
||||
FilterEntries(p, undoDir, targetName, start, false, ref FoundUser);
|
||||
FilterEntries(p, prevUndoDir, targetName, start, false, ref FoundUser);
|
||||
}
|
||||
|
||||
public static void HighlightPlayer(Player p, string targetName, long seconds, ref bool FoundUser) {
|
||||
FilterEntries(p, undoDir, targetName, seconds, true, ref FoundUser);
|
||||
FilterEntries(p, prevUndoDir, targetName, seconds, true, ref FoundUser);
|
||||
public static void HighlightPlayer(Player p, string targetName, DateTime start, ref bool FoundUser) {
|
||||
FilterEntries(p, undoDir, targetName, start, true, ref FoundUser);
|
||||
FilterEntries(p, prevUndoDir, targetName, start, true, ref FoundUser);
|
||||
}
|
||||
|
||||
static void FilterEntries(Player p, string dir, string name, long seconds, bool highlight, ref bool FoundUser) {
|
||||
static void FilterEntries(Player p, string dir, string name, DateTime start, bool highlight, ref bool FoundUser) {
|
||||
string path = Path.Combine(dir, name);
|
||||
if (!Directory.Exists(path))
|
||||
return;
|
||||
@ -89,9 +89,9 @@ namespace MCGalaxy.Util {
|
||||
if (format == null) continue;
|
||||
|
||||
if (highlight) {
|
||||
if (!format.HighlightEntry(p, path, ref temp, seconds)) break;
|
||||
if (!format.HighlightEntry(p, path, ref temp, start)) break;
|
||||
} else {
|
||||
if (!format.UndoEntry(p, path, ref temp, seconds)) break;
|
||||
if (!format.UndoEntry(p, path, ref temp, start)) break;
|
||||
}
|
||||
}
|
||||
FoundUser = true;
|
||||
|
@ -116,13 +116,11 @@ namespace MCGalaxy.Util {
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool UndoEntry(Player p, string path, ref byte[] temp, long seconds) {
|
||||
protected override bool UndoEntry(Player p, string path, ref byte[] temp, DateTime start) {
|
||||
List<ChunkHeader> list = new List<ChunkHeader>();
|
||||
DateTime now = DateTime.UtcNow;
|
||||
int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
|
||||
Player.UndoPos Pos;
|
||||
bool isPlayer = p != null && p.group.Permission < LevelPermission.Nobody;
|
||||
seconds *= TimeSpan.TicksPerSecond;
|
||||
|
||||
using (Stream fs = File.OpenRead(path))
|
||||
using (BinaryReader r = new BinaryReader(fs))
|
||||
@ -131,7 +129,7 @@ namespace MCGalaxy.Util {
|
||||
for (int i = list.Count - 1; i >= 0; i--) {
|
||||
ChunkHeader chunk = list[i];
|
||||
Level lvl;
|
||||
if (!CheckChunk(chunk, now, seconds, p, out lvl))
|
||||
if (!CheckChunk(chunk, start, p, out lvl))
|
||||
return false;
|
||||
if (lvl == null || (isPlayer && lvl != p.level)) continue;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
@ -144,7 +142,7 @@ namespace MCGalaxy.Util {
|
||||
for (int j = chunk.Entries - 1; j >= 0; j-- ) {
|
||||
int offset = j * entrySize;
|
||||
DateTime time = chunk.BaseTime.AddTicks(U16(temp, offset + 0) * TimeSpan.TicksPerSecond);
|
||||
if (time.AddTicks(seconds) < now) { buffer.CheckIfSend(true); return false; }
|
||||
if (time < start) { buffer.CheckIfSend(true); return false; }
|
||||
Pos.x = U16(temp, offset + 2); Pos.y = U16(temp, offset + 4); Pos.z = U16(temp, offset + 6);
|
||||
|
||||
Pos.type = lvl.GetTile(Pos.x, Pos.y, Pos.z);
|
||||
@ -169,10 +167,8 @@ namespace MCGalaxy.Util {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool HighlightEntry(Player p, string path, ref byte[] temp, long seconds) {
|
||||
protected override bool HighlightEntry(Player p, string path, ref byte[] temp, DateTime start) {
|
||||
List<ChunkHeader> list = new List<ChunkHeader>();
|
||||
DateTime now = DateTime.UtcNow;
|
||||
seconds *= TimeSpan.TicksPerSecond;
|
||||
|
||||
using (Stream fs = File.OpenRead(path))
|
||||
using (BinaryReader r = new BinaryReader(fs))
|
||||
@ -181,7 +177,7 @@ namespace MCGalaxy.Util {
|
||||
for (int i = list.Count - 1; i >= 0; i--) {
|
||||
ChunkHeader chunk = list[i];
|
||||
Level lvl;
|
||||
if (!CheckChunk(chunk, now, seconds, p, out lvl))
|
||||
if (!CheckChunk(chunk, start, p, out lvl))
|
||||
return false;
|
||||
if (lvl == null || lvl != p.level) continue;
|
||||
|
||||
@ -192,7 +188,7 @@ namespace MCGalaxy.Util {
|
||||
for (int j = chunk.Entries - 1; j >= 0; j-- ) {
|
||||
int offset = j * entrySize;
|
||||
DateTime time = chunk.BaseTime.AddTicks(U16(temp, offset + 0) * TimeSpan.TicksPerSecond);
|
||||
if (time.AddTicks(seconds) < now) return false;
|
||||
if (time < start) return false;
|
||||
ushort x = U16(temp, offset + 2), y = U16(temp, offset + 4), z = U16(temp, offset + 6);
|
||||
|
||||
byte lvlTile = lvl.GetTile(x, y, z);
|
||||
@ -215,12 +211,11 @@ namespace MCGalaxy.Util {
|
||||
return (ushort)(buffer[offset + 0] | buffer[offset + 1] << 8);
|
||||
}
|
||||
|
||||
static bool CheckChunk(ChunkHeader chunk, DateTime now, long ticks, Player p, out Level lvl) {
|
||||
static bool CheckChunk(ChunkHeader chunk, DateTime start, Player p, out Level lvl) {
|
||||
DateTime time = chunk.BaseTime;
|
||||
lvl = null;
|
||||
if (time.AddTicks(65536 * TimeSpan.TicksPerSecond + ticks) < now)
|
||||
return false; // we can safely discard the entire chunk
|
||||
|
||||
if (time.AddTicks(65536 * TimeSpan.TicksPerSecond) < start)
|
||||
return false; // we can safely discard the entire chunk
|
||||
lvl = LevelInfo.FindExact(chunk.LevelName);
|
||||
return true;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ namespace MCGalaxy.Util {
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool UndoEntry(Player p, string path, ref byte[] temp, long seconds) {
|
||||
protected override bool UndoEntry(Player p, string path, ref byte[] temp, DateTime start) {
|
||||
Player.UndoPos Pos;
|
||||
int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
|
||||
Pos.extType = 0; Pos.newExtType = 0;
|
||||
@ -77,7 +77,7 @@ namespace MCGalaxy.Util {
|
||||
for (int i = (lines.Length - 1) / 7; i >= 0; i--) {
|
||||
try {
|
||||
// line format: mapName x y z date oldblock newblock
|
||||
if (!InTime(lines[(i * 7) - 3], seconds)) return false;
|
||||
if (!InTime(lines[(i * 7) - 3], start)) return false;
|
||||
Level lvl = LevelInfo.FindExact(lines[(i * 7) - 7]);
|
||||
if (lvl == null) continue;
|
||||
|
||||
@ -102,7 +102,7 @@ namespace MCGalaxy.Util {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override bool HighlightEntry(Player p, string path, ref byte[] temp, long seconds) {
|
||||
protected override bool HighlightEntry(Player p, string path, ref byte[] temp, DateTime start) {
|
||||
Player.UndoPos Pos;
|
||||
Pos.extType = 0; Pos.newExtType = 0;
|
||||
string[] lines = File.ReadAllText(path).Split(' ');
|
||||
@ -110,7 +110,7 @@ namespace MCGalaxy.Util {
|
||||
for (int i = (lines.Length - 1) / 7; i >= 0; i--) {
|
||||
try {
|
||||
// line format: mapName x y z date oldblock newblock
|
||||
if (!InTime(lines[(i * 7) - 3], seconds)) return false;
|
||||
if (!InTime(lines[(i * 7) - 3], start)) return false;
|
||||
Level foundLevel = LevelInfo.FindExact(lines[(i * 7) - 7]);
|
||||
if (foundLevel == null || foundLevel != p.level) continue;
|
||||
|
||||
@ -133,11 +133,10 @@ namespace MCGalaxy.Util {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool InTime(string line, long seconds) {
|
||||
static bool InTime(string line, DateTime start) {
|
||||
line = line.Replace('&', ' ');
|
||||
DateTime time = DateTime.Parse(line, CultureInfo.InvariantCulture)
|
||||
.AddSeconds(seconds);
|
||||
return time >= DateTime.Now;
|
||||
DateTime time = DateTime.Parse(line, CultureInfo.InvariantCulture);
|
||||
return time >= start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user