diff --git a/Commands/Chat/CmdGlobal.cs b/Commands/Chat/CmdGlobal.cs
index aba2864bd..6c647bef1 100644
--- a/Commands/Chat/CmdGlobal.cs
+++ b/Commands/Chat/CmdGlobal.cs
@@ -29,7 +29,7 @@ namespace MCGalaxy.Commands
//bla
public override void Use(Player p, string message)
{
- if (p != null && (p.isGCMod || p.isMod || p.isDev) && !p.verifiedName) { Player.SendMessage(p, "You can't use GC, because the server hasn't verify-names on"); return; }
+ if (p != null && !p.verifiedName) { Player.SendMessage(p, "You can't use GC, because the server hasn't verify-names on"); return; }
if (String.IsNullOrEmpty(message)) {
p.InGlobalChat = !p.InGlobalChat;
diff --git a/Drawing/DrawOps/UndoDrawOp.cs b/Drawing/DrawOps/UndoDrawOp.cs
index 2669c9de2..3b1b1e02b 100644
--- a/Drawing/DrawOps/UndoDrawOp.cs
+++ b/Drawing/DrawOps/UndoDrawOp.cs
@@ -78,11 +78,9 @@ namespace MCGalaxy.Drawing.Ops {
if (time > End) continue;
if (time < Start) { buffer.CheckIfSend(true); return; }
- byte newTile = 0, newExtTile = 0;
- item.GetNewExtBlock(out newTile, out newExtTile);
- byte tile = 0, extTile = 0;
- item.GetExtBlock(out tile, out extTile);
- UndoFile.UndoBlock(p, lvl, Pos, timeDelta, buffer, tile, extTile, newTile, newExtTile);
+ item.GetNewExtBlock(out Pos.newtype, out Pos.newExtType);
+ item.GetExtBlock(out Pos.type, out Pos.extType);
+ UndoFile.UndoBlock(p, lvl, Pos, timeDelta, buffer);
}
buffer.CheckIfSend(true);
node = node.Prev;
diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj
index b049534c4..3cdae749f 100644
--- a/MCGalaxy_.csproj
+++ b/MCGalaxy_.csproj
@@ -481,6 +481,7 @@
+
diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs
index e561cd748..522fd3072 100644
--- a/Player/Player.Handlers.cs
+++ b/Player/Player.Handlers.cs
@@ -474,7 +474,7 @@ namespace MCGalaxy {
SetPrefix();
playerDb.Dispose();
- if (Server.server_owner != "" && Server.server_owner.ToLower().Equals(name.ToLower())) {
+ if (Server.server_owner != "" && Server.server_owner.CaselessEq(name)) {
if (color == Group.standard.color) color = "&c";
if (title == "") title = "Owner";
SetPrefix();
diff --git a/Player/Undo/UndoCache.cs b/Player/Undo/UndoCache.cs
index 6488aadde..24cc35da8 100644
--- a/Player/Undo/UndoCache.cs
+++ b/Player/Undo/UndoCache.cs
@@ -112,21 +112,17 @@ namespace MCGalaxy.Util {
public void GetExtBlock(out byte type, out byte extType) {
if ((Flags & (1 << 14)) != 0) {
- type = Block.custom_block;
- extType = Type;
+ type = Block.custom_block; extType = Type;
} else {
- type = Type;
- extType = 0;
+ type = Type; extType = 0;
}
}
public void GetNewExtBlock(out byte type, out byte extType) {
if ((Flags & (1 << 15)) != 0) {
- type = Block.custom_block;
- extType = NewType;
+ type = Block.custom_block; extType = NewType;
} else {
- type = NewType;
- extType = 0;
+ type = NewType; extType = 0;
}
}
@@ -149,6 +145,10 @@ namespace MCGalaxy.Util {
}
return item;
}
+
+ public static UndoCacheItem Make(UndoCacheNode node, short timeDelta, Player.UndoPos pos) {
+ return Make(node, timeDelta, ref pos);
+ }
}
public sealed class UndoDrawOpEntry {
diff --git a/Player/Undo/UndoFile.cs b/Player/Undo/UndoFile.cs
index 3057da2eb..84772b506 100644
--- a/Player/Undo/UndoFile.cs
+++ b/Player/Undo/UndoFile.cs
@@ -25,8 +25,9 @@ namespace MCGalaxy.Util {
public abstract class UndoFile {
protected const string undoDir = "extra/undo", prevUndoDir = "extra/undoPrevious";
- public static UndoFile OldFormat = new UndoFileText();
- public static UndoFile NewFormat = new UndoFileBin();
+ public static UndoFile TxtFormat = new UndoFileText();
+ public static UndoFile BinFormat = new UndoFileBin();
+ public static UndoFile NewFormat = new UndoFileCBin();
protected abstract void SaveUndoData(List buffer, string path);
@@ -57,8 +58,8 @@ namespace MCGalaxy.Util {
Directory.CreateDirectory(playerDir);
int numFiles = Directory.GetFiles(playerDir).Length;
- string path = Path.Combine(playerDir, numFiles + NewFormat.Extension);
- NewFormat.SaveUndoData(p.UndoBuffer, path);
+ string path = Path.Combine(playerDir, numFiles + BinFormat.Extension);
+ BinFormat.SaveUndoData(p.UndoBuffer, path);
}
public static void UndoPlayer(Player p, string target, Vec3U16[] marks, DateTime start, ref bool FoundUser) {
@@ -87,7 +88,8 @@ namespace MCGalaxy.Util {
continue;
UndoFile format = null;
- if (path.EndsWith(OldFormat.Extension)) format = OldFormat;
+ if (path.EndsWith(TxtFormat.Extension)) format = TxtFormat;
+ if (path.EndsWith(BinFormat.Extension)) format = BinFormat;
if (path.EndsWith(NewFormat.Extension)) format = NewFormat;
if (format == null) continue;
@@ -115,14 +117,15 @@ namespace MCGalaxy.Util {
}
protected internal static void UndoBlock(Player p, Level lvl, Player.UndoPos Pos,
- int timeDelta, BufferedBlockSender buffer,
- byte oldType, byte oldExtType, byte newType, byte newExtType) {
- Pos.type = lvl.GetTile(Pos.x, Pos.y, Pos.z);
- if (Pos.type == newType || Block.Convert(Pos.type) == Block.water
- || Block.Convert(Pos.type) == Block.lava || Pos.type == Block.grass) {
+ int timeDelta, BufferedBlockSender buffer) {
+ byte lvlTile = lvl.GetTile(Pos.x, Pos.y, Pos.z);
+ if (lvlTile == Pos.newtype || Block.Convert(lvlTile) == Block.water
+ || Block.Convert(lvlTile) == Block.lava || lvlTile == Block.grass) {
- Pos.newtype = oldType; Pos.newExtType = oldExtType;
- Pos.extType = newExtType; Pos.timeDelta = timeDelta;
+ byte newExtType = Pos.newExtType;
+ Pos.newtype = Pos.type; Pos.newExtType = Pos.extType;
+ Pos.extType = newExtType; Pos.type = lvlTile;
+ Pos.timeDelta = timeDelta;
if (lvl.DoBlockchange(p, Pos.x, Pos.y, Pos.z, Pos.newtype, Pos.newExtType)) {
buffer.Add(lvl.PosToInt(Pos.x, Pos.y, Pos.z), Pos.newtype, Pos.newExtType);
buffer.CheckIfSend(false);
@@ -131,6 +134,15 @@ namespace MCGalaxy.Util {
}
}
+ protected static void HighlightBlock(Player p, Level lvl, byte type, ushort x, ushort y, ushort z) {
+ byte lvlTile = lvl.GetTile(x, y, z);
+ if (lvlTile == type || Block.Convert(lvlTile) == Block.water || Block.Convert(lvlTile) == Block.lava) {
+ byte block = (lvlTile == Block.air || Block.Convert(lvlTile) == Block.water
+ || Block.Convert(lvlTile) == Block.lava) ? Block.red : Block.green;
+ p.SendBlockchange(x, y, z, block);
+ }
+ }
+
public static void CreateDefaultDirectories() {
if (!Directory.Exists(undoDir))
Directory.CreateDirectory(undoDir);
@@ -152,10 +164,13 @@ namespace MCGalaxy.Util {
for (int i = 0; i < files.Length; i++) {
path = files[i];
- if (!path.EndsWith(OldFormat.Extension))
- continue;
- buffer.Clear();
- OldFormat.ReadUndoData(buffer, path);
+ if (path.EndsWith(BinFormat.Extension)) {
+ buffer.Clear();
+ BinFormat.ReadUndoData(buffer, path);
+ } else if (path.EndsWith(TxtFormat.Extension)) {
+ buffer.Clear();
+ TxtFormat.ReadUndoData(buffer, path);
+ }
string newPath = Path.ChangeExtension(path, NewFormat.Extension);
NewFormat.SaveUndoData(buffer, newPath);
diff --git a/Player/Undo/UndoFileBin.cs b/Player/Undo/UndoFileBin.cs
index c95c60462..371ec0829 100644
--- a/Player/Undo/UndoFileBin.cs
+++ b/Player/Undo/UndoFileBin.cs
@@ -93,7 +93,6 @@ namespace MCGalaxy.Util {
}
protected override void ReadUndoData(List buffer, string path) {
- DateTime now = DateTime.Now;
Player.UndoPos Pos;
using (Stream fs = File.OpenRead(path))
using (BinaryReader r = new BinaryReader(fs))
@@ -155,9 +154,9 @@ namespace MCGalaxy.Util {
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;
- byte oldType = temp[offset + 8], oldExtType = temp[offset + 9];
- byte newType = temp[offset + 10], newExtType = temp[offset + 11];
- UndoBlock(p, lvl, Pos, timeDelta, buffer, oldType, oldExtType, newType, newExtType);
+ Pos.type = temp[offset + 8]; Pos.extType = temp[offset + 9];
+ Pos.newtype = temp[offset + 10]; Pos.newExtType = temp[offset + 11];
+ UndoBlock(p, lvl, Pos, timeDelta, buffer);
}
buffer.CheckIfSend(true);
}
@@ -189,17 +188,7 @@ namespace MCGalaxy.Util {
DateTime time = chunk.BaseTime.AddTicks(U16(temp, offset + 0) * TimeSpan.TicksPerSecond);
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);
- byte oldType = temp[offset + 8], oldExtType = temp[offset + 9];
- byte newType = temp[offset + 10], newExtType = temp[offset + 11];
-
- if (lvlTile == newType || Block.Convert(lvlTile) == Block.water || Block.Convert(lvlTile) == Block.lava) {
-
- byte block = (lvlTile == Block.air || Block.Convert(lvlTile) == Block.water
- || Block.Convert(lvlTile) == Block.lava) ? Block.red : Block.green;
- p.SendBlockchange(x, y, z, block);
- }
+ HighlightBlock(p, lvl, temp[offset + 10], x, y, z);
}
}
}
diff --git a/Player/Undo/UndoFileCBin.cs b/Player/Undo/UndoFileCBin.cs
new file mode 100644
index 000000000..01e50a561
--- /dev/null
+++ b/Player/Undo/UndoFileCBin.cs
@@ -0,0 +1,296 @@
+/*
+ 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;
+using System.Linq;
+using System.Text;
+using MCGalaxy.Drawing;
+using MCGalaxy.Levels.IO;
+
+namespace MCGalaxy.Util {
+
+ public sealed class UndoFileCBin : UndoFile {
+
+ protected override string Extension { get { return ".uncbin"; } }
+ const int entrySize = 8;
+
+ protected override void SaveUndoData(List buffer, string path) {
+ UndoCacheNode node = new UndoCacheNode();
+ string lastLoggedName = "";
+
+ using (FileStream fs = File.Create(path)) {
+ BinaryWriter w = new BinaryWriter(fs);
+ long entriesPos = 0;
+ ChunkHeader last = default(ChunkHeader);
+
+ foreach (Player.UndoPos uP in buffer) {
+ DateTime time = Server.StartTime.AddSeconds(uP.timeDelta);
+ int timeDiff = (int)(time - last.BaseTime).TotalSeconds;
+ if (last.LevelName != uP.mapName || timeDiff > (65535 >> 2) || last.Entries == ushort.MaxValue) {
+ if (!LevelInfo.ExistsOffline(uP.mapName)) {
+ if (uP.mapName != lastLoggedName) {
+ lastLoggedName = uP.mapName;
+ Server.s.Log("Missing map file\"" + lastLoggedName+ "\", skipping undo entries");
+ }
+ continue;
+ }
+
+ ushort width, height, length;
+ LvlFile.LoadDimensions(LevelInfo.LevelPath(uP.mapName), out width, out height, out length);
+ node.Width = width; node.Height = height; node.Length = length;
+ WriteChunkEntries(w, last.Entries, entriesPos);
+ node.MapName = uP.mapName;
+ last = WriteEmptyChunk(w, node, time, ref entriesPos);
+ }
+
+ UndoCacheItem item = UndoCacheItem.Make(node, 0, uP);
+ int flags = (item.Flags & 0xC000) | timeDiff;
+ w.Write((ushort)flags); w.Write(item.Index);
+ w.Write(item.Type); w.Write(item.NewType);
+ last.Entries++;
+ }
+ if (last.Entries > 0)
+ WriteChunkEntries(w, last.Entries, entriesPos);
+ }
+ }
+
+ protected override void SaveUndoData(UndoCache buffer, string path) {
+ using (FileStream fs = File.Create(path)) {
+ BinaryWriter w = new BinaryWriter(fs);
+ long entriesPos = 0;
+ ChunkHeader last = default(ChunkHeader);
+ UndoCacheNode node = buffer.Tail;
+
+ while (node != null) {
+ List items = node.Items;
+ for (int i = 0; i < items.Count; i++) {
+ UndoCacheItem uP = items[i];
+ DateTime time = node.BaseTime.AddSeconds(uP.TimeDelta);
+ int timeDiff = (int)(time - last.BaseTime).TotalSeconds;
+ if (last.LevelName != node.MapName || timeDiff > (65535 >> 2) || last.Entries == ushort.MaxValue) {
+ WriteChunkEntries(w, last.Entries, entriesPos);
+ last = WriteEmptyChunk(w, node, time, ref entriesPos);
+ }
+
+ int flags = (uP.Flags & 0xC000) | timeDiff;
+ w.Write((ushort)flags); w.Write(uP.Index);
+ w.Write(uP.Type); w.Write(uP.NewType);
+ last.Entries++;
+ }
+ if (last.Entries > 0)
+ WriteChunkEntries(w, last.Entries, entriesPos);
+ node = node.Prev;
+ }
+ }
+ }
+
+ protected override void ReadUndoData(List buffer, string path) {
+ Player.UndoPos Pos;
+ UndoCacheItem item = default(UndoCacheItem);
+ using (Stream fs = File.OpenRead(path))
+ using (BinaryReader r = new BinaryReader(fs))
+ {
+ int approxEntries = (int)(fs.Length / entrySize);
+ if (buffer.Capacity < approxEntries)
+ buffer.Capacity = approxEntries;
+ while (fs.Position < fs.Length) {
+ ChunkHeader chunk = ReadHeader(fs, r);
+ Pos.mapName = chunk.LevelName;
+
+ for (int j = 0; j < chunk.Entries; j++ ) {
+ item.Flags = r.ReadUInt16();
+ DateTime time = chunk.BaseTime.AddTicks((item.Flags & 0x3FFF) * TimeSpan.TicksPerSecond);
+ Pos.timeDelta = (int)time.Subtract(Server.StartTime).TotalSeconds;
+ int index = r.ReadInt32();
+ Pos.x = (ushort)(index % chunk.Width);
+ Pos.y = (ushort)((index / chunk.Width) / chunk.Length);
+ Pos.z = (ushort)((index / chunk.Width) % chunk.Length);
+
+ item.Type = r.ReadByte();
+ item.NewType = r.ReadByte();
+ item.GetExtBlock(out Pos.type, out Pos.extType);
+ item.GetNewExtBlock(out Pos.newtype, out Pos.newExtType);
+ buffer.Add(Pos);
+ }
+ }
+ }
+ }
+
+ protected override bool UndoEntry(Player p, string path, Vec3U16[] marks,
+ ref byte[] temp, DateTime start) {
+ List list = new List();
+ int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
+ Player.UndoPos Pos = default(Player.UndoPos);
+ Vec3U16 min = marks[0], max = marks[1];
+ bool undoArea = min.X != ushort.MaxValue;
+ UndoCacheItem item = default(UndoCacheItem);
+
+ using (Stream fs = File.OpenRead(path))
+ using (BinaryReader r = new BinaryReader(fs))
+ {
+ ReadHeaders(list, r);
+ for (int i = list.Count - 1; i >= 0; i--) {
+ ChunkHeader chunk = list[i];
+ Level lvl;
+ if (!CheckChunk(chunk, start, p, out lvl))
+ return false;
+ if (lvl == null || (p.level != null && !p.level.name.CaselessEq(lvl.name)))
+ continue;
+ 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));
+ }
+
+ Pos.mapName = chunk.LevelName;
+ fs.Seek(chunk.DataPosition, SeekOrigin.Begin);
+ if (temp == null) temp = new byte[ushort.MaxValue * entrySize];
+ fs.Read(temp, 0, chunk.Entries * entrySize);
+
+ for (int j = chunk.Entries - 1; j >= 0; j-- ) {
+ int offset = j * entrySize;
+ item.Flags = U16(temp, offset + 0);
+ DateTime time = chunk.BaseTime.AddTicks((item.Flags & 0x3FFF) * TimeSpan.TicksPerSecond);
+ if (time < start) { buffer.CheckIfSend(true); return false; }
+
+ int index = NetUtils.ReadI32(temp, offset + 2);
+ Pos.x = (ushort)(index % chunk.Width);
+ Pos.y = (ushort)((index / chunk.Width) / chunk.Length);
+ Pos.z = (ushort)((index / chunk.Width) % chunk.Length);
+ 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;
+
+ item.Type = temp[offset + 6];
+ item.NewType = temp[offset + 7];
+ item.GetExtBlock(out Pos.type, out Pos.extType);
+ item.GetNewExtBlock(out Pos.newtype, out Pos.newExtType);
+ UndoBlock(p, lvl, Pos, timeDelta, buffer);
+ }
+ buffer.CheckIfSend(true);
+ }
+ }
+ return true;
+ }
+
+ protected override bool HighlightEntry(Player p, string path,
+ ref byte[] temp, DateTime start) {
+ List list = new List();
+
+ using (Stream fs = File.OpenRead(path))
+ using (BinaryReader r = new BinaryReader(fs))
+ {
+ ReadHeaders(list, r);
+ for (int i = list.Count - 1; i >= 0; i--) {
+ ChunkHeader chunk = list[i];
+ Level lvl;
+ if (!CheckChunk(chunk, start, p, out lvl))
+ return false;
+ if (lvl == null || lvl != p.level) continue;
+
+ fs.Seek(chunk.DataPosition, SeekOrigin.Begin);
+ if (temp == null) temp = new byte[ushort.MaxValue * entrySize];
+ fs.Read(temp, 0, chunk.Entries * entrySize);
+
+ for (int j = chunk.Entries - 1; j >= 0; j-- ) {
+ int offset = j * entrySize;
+ ushort flags = U16(temp, offset + 0);
+ DateTime time = chunk.BaseTime.AddTicks((flags & 0x3FFF) * TimeSpan.TicksPerSecond);
+ if (time < start) return false;
+
+ int index = NetUtils.ReadI32(temp, offset + 2);
+ ushort x = (ushort)(index % chunk.Width);
+ ushort y = (ushort)((index / chunk.Width) / chunk.Length);
+ ushort z = (ushort)((index / chunk.Width) % chunk.Length);
+ HighlightBlock(p, lvl, temp[offset + 7], x, y, z);
+ }
+ }
+ }
+ return true;
+ }
+
+ static ushort U16(byte[] buffer, int offset) {
+ return (ushort)(buffer[offset + 0] | buffer[offset + 1] << 8);
+ }
+
+ static bool CheckChunk(ChunkHeader chunk, DateTime start, Player p, out Level lvl) {
+ DateTime time = chunk.BaseTime;
+ lvl = null;
+ if (time.AddTicks((65536 >> 2) * TimeSpan.TicksPerSecond) < start)
+ return false; // we can safely discard the entire chunk
+ lvl = LevelInfo.FindExact(chunk.LevelName);
+ return true;
+ }
+
+ struct ChunkHeader {
+ public string LevelName;
+ public DateTime BaseTime;
+ public ushort Entries;
+ public ushort Width, Height, Length;
+ public long DataPosition;
+ }
+
+ static void ReadHeaders(List list, BinaryReader r) {
+ Stream s = r.BaseStream;
+ long len = s.Length;
+ while (s.Position < len) {
+ ChunkHeader header = ReadHeader(s, r);
+ s.Seek(header.Entries * entrySize, SeekOrigin.Current);
+ list.Add(header);
+ }
+ }
+
+ static ChunkHeader ReadHeader(Stream s, BinaryReader r) {
+ ChunkHeader header = default(ChunkHeader);
+ byte[] mapNameData = r.ReadBytes(r.ReadUInt16());
+ header.LevelName = Encoding.UTF8.GetString(mapNameData);
+ header.BaseTime = new DateTime(r.ReadInt64(), DateTimeKind.Utc);
+ header.Entries = r.ReadUInt16();
+
+ header.Width = r.ReadUInt16();
+ header.Height = r.ReadUInt16();
+ header.Length = r.ReadUInt16();
+ header.DataPosition = s.Position;
+ return header;
+ }
+
+ static void WriteChunkEntries(BinaryWriter w, ushort entries, long entriesPos) {
+ long curPos = w.BaseStream.Position;
+ w.BaseStream.Seek(entriesPos, SeekOrigin.Begin);
+
+ w.Write(entries);
+ w.BaseStream.Seek(curPos, SeekOrigin.Begin);
+ }
+
+ static ChunkHeader WriteEmptyChunk(BinaryWriter w, UndoCacheNode node, DateTime time, ref long entriesPos) {
+ ChunkHeader header = default(ChunkHeader);
+ time = time.ToUniversalTime();
+ byte[] mapBytes = Encoding.UTF8.GetBytes(node.MapName);
+ w.Write((ushort)mapBytes.Length);
+ w.Write(mapBytes); header.LevelName = node.MapName;
+ w.Write(time.Ticks); header.BaseTime = time;
+
+ entriesPos = w.BaseStream.Position;
+ w.Write((ushort)0);
+ w.Write((ushort)node.Width); header.Width = (ushort)node.Width;
+ w.Write((ushort)node.Height); header.Height = (ushort)node.Height;
+ w.Write((ushort)node.Length); header.Length = (ushort)node.Length;
+ return header;
+ }
+ }
+}
diff --git a/Player/Undo/UndoFileText.cs b/Player/Undo/UndoFileText.cs
index 790165477..151c27fb5 100644
--- a/Player/Undo/UndoFileText.cs
+++ b/Player/Undo/UndoFileText.cs
@@ -103,9 +103,9 @@ namespace MCGalaxy.Util {
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;
- byte newType = Convert.ToByte(lines[(i * 7) - 1]);
- byte oldType = Convert.ToByte(lines[(i * 7) - 2]);
- UndoBlock(p, lvl, Pos, timeDelta, buffer, oldType, 0, newType, 0);
+ Pos.newtype = Convert.ToByte(lines[(i * 7) - 1]);
+ Pos.type = Convert.ToByte(lines[(i * 7) - 2]);
+ UndoBlock(p, lvl, Pos, timeDelta, buffer);
} catch {
}
}
@@ -114,31 +114,19 @@ namespace MCGalaxy.Util {
}
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(' ');
// because we have space to end of each entry, need to subtract one otherwise we'll start at a "".
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], start)) return false;
- Level foundLevel = LevelInfo.FindExact(lines[(i * 7) - 7]);
- if (foundLevel == null || foundLevel != p.level) continue;
+ Level lvl = LevelInfo.FindExact(lines[(i * 7) - 7]);
+ if (lvl == null || lvl != p.level) continue;
- Pos.mapName = foundLevel.name;
- Pos.x = Convert.ToUInt16(lines[(i * 7) - 6]);
- Pos.y = Convert.ToUInt16(lines[(i * 7) - 5]);
- Pos.z = Convert.ToUInt16(lines[(i * 7) - 4]);
- Pos.type = foundLevel.GetTile(Pos.x, Pos.y, Pos.z);
-
- if (Pos.type == Convert.ToByte(lines[(i * 7) - 1]) ||
- Block.Convert(Pos.type) == Block.water || Block.Convert(Pos.type) == Block.lava) {
-
- if (Pos.type == Block.air || Block.Convert(Pos.type) == Block.water || Block.Convert(Pos.type) == Block.lava)
- p.SendBlockchange(Pos.x, Pos.y, Pos.z, Block.red);
- else
- p.SendBlockchange(Pos.x, Pos.y, Pos.z, Block.green);
- }
+ ushort x = Convert.ToUInt16(lines[(i * 7) - 6]);
+ ushort y = Convert.ToUInt16(lines[(i * 7) - 5]);
+ ushort z = Convert.ToUInt16(lines[(i * 7) - 4]);
+ HighlightBlock(p, lvl, Convert.ToByte(lines[(i * 7) - 1]), x, y, z);
} catch { }
}
return true;