diff --git a/Commands/building/CmdUndo.cs b/Commands/building/CmdUndo.cs index 55920164b..26079be04 100644 --- a/Commands/building/CmdUndo.cs +++ b/Commands/building/CmdUndo.cs @@ -133,18 +133,22 @@ namespace MCGalaxy.Commands Command.all.Find("physics").Use(p, "0"); if (p.level.UndoBuffer.Count != Server.physUndo) { - for (int i = p.level.currentUndo; i >= 0; i--) { + int count = p.level.currentUndo; + for (int i = count; i >= 0; i--) { try { - Level.UndoPos uP = p.level.UndoBuffer[i]; - if (!CheckBlockPhysics(p, seconds, uP)) break; + if (!CheckBlockPhysics(p, seconds, i, p.level.UndoBuffer[i])) break; } catch { } } } else { - for (int i = p.level.currentUndo; i != p.level.currentUndo + 1; i--) { + int count = p.level.currentUndo; + for (int i = count; i >= 0; i--) { try { - if (i < 0) i = p.level.UndoBuffer.Count - 1; - Level.UndoPos uP = p.level.UndoBuffer[i]; - if (!CheckBlockPhysics(p, seconds, uP)) break; + if (!CheckBlockPhysics(p, seconds, i, p.level.UndoBuffer[i])) break; + } catch { } + } + for (int i = p.level.UndoBuffer.Count - 1; i > count; i--) { + try { + if (!CheckBlockPhysics(p, seconds, i, p.level.UndoBuffer[i])) break; } catch { } } } @@ -174,14 +178,17 @@ namespace MCGalaxy.Commands return true; } - bool CheckBlockPhysics(Player p, long seconds, Level.UndoPos undo) { + bool CheckBlockPhysics(Player p, long seconds, int i, Level.UndoPos undo) { byte b = p.level.GetTile(undo.location); if (undo.timePerformed.AddSeconds(seconds) < DateTime.Now) return false; if (b == undo.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) { ushort x, y, z; - p.level.IntToPos(undo.location, out x, out y, out z); + int undoIndex = p.level.currentUndo; + p.level.currentUndo = i; + p.level.IntToPos(undo.location, out x, out y, out z); + p.level.currentUndo = undoIndex; p.level.Blockchange(x, y, z, undo.oldType, true, "", undo.oldExtType); } return true; diff --git a/Drawing/CopyState.cs b/Drawing/CopyState.cs index bbc3a93e7..56729a7ff 100644 --- a/Drawing/CopyState.cs +++ b/Drawing/CopyState.cs @@ -28,6 +28,7 @@ namespace MCGalaxy.Drawing { public int Width, Height, Length; const int identifier = 0x434F5059; // 'COPY' + const int identifierC = 0x434F5043; // 'COPC' (Copy compressed) public int Volume { get { return Width * Height * Length; } @@ -74,24 +75,38 @@ namespace MCGalaxy.Drawing { public void SaveTo(Stream stream) { BinaryWriter w = new BinaryWriter(stream); - w.Write(identifier); - + w.Write(identifierC); w.Write(X); w.Write(Y); w.Write(Z); w.Write(Width); w.Write(Height); w.Write(Length); - w.Write(Blocks); - w.Write(ExtBlocks); + + byte[] blocks = Blocks.GZip(); + w.Write(blocks.Length); + w.Write(blocks); + blocks = ExtBlocks.GZip(); + w.Write(blocks.Length); + w.Write(blocks); + w.Write(OriginX); w.Write(OriginY); w.Write(OriginZ); } public void LoadFrom(Stream stream) { BinaryReader r = new BinaryReader(stream); - if (r.ReadInt32() != identifier) + int header = r.ReadInt32(); + if (!(header == identifier || header == identifierC)) throw new InvalidDataException("invalid identifier"); X = r.ReadInt32(); Y = r.ReadInt32(); Z = r.ReadInt32(); Width = r.ReadInt32(); Height = r.ReadInt32(); Length = r.ReadInt32(); - Blocks = r.ReadBytes(Width * Height * Length); - ExtBlocks = r.ReadBytes(Width * Height * Length); + if (header == identifier) { + Blocks = r.ReadBytes(Width * Height * Length); + ExtBlocks = r.ReadBytes(Width * Height * Length); + } else { + int uncompressedLen = Width * Height * Length; + int blocksLen = r.ReadInt32(); + Blocks = r.ReadBytes(blocksLen).Decompress(uncompressedLen); + blocksLen = r.ReadInt32(); + ExtBlocks = r.ReadBytes(blocksLen).Decompress(uncompressedLen); + } OriginX = r.ReadInt32(); OriginY = r.ReadInt32(); OriginZ = r.ReadInt32(); } diff --git a/Server/Properties.cs b/Server/Properties.cs index c3879cfa9..03c693b97 100644 --- a/Server/Properties.cs +++ b/Server/Properties.cs @@ -554,7 +554,11 @@ namespace MCGalaxy { try { Server.totalUndo = int.Parse(value); } catch { Server.s.Log("Invalid " + key + ". Using default"); } break; - + case "phys-max-undo": + try { Server.physUndo = int.Parse(value); } + catch { Server.s.Log("Invalid " + key + ". Using default"); Server.physUndo = 20000; } + break; + case "review-view-perm": try { sbyte parsed = sbyte.Parse(value); @@ -820,7 +824,8 @@ namespace MCGalaxy { w.WriteLine("guest-limit-notify = " + Server.guestLimitNotify.ToString().ToLower()); w.WriteLine("guest-join-notify = " + Server.guestJoinNotify.ToString().ToLower()); w.WriteLine("guest-leave-notify = " + Server.guestLeaveNotify.ToString().ToLower()); - w.WriteLine("total-undo = " + Server.totalUndo.ToString()); + w.WriteLine("total-undo = " + Server.totalUndo); + w.WriteLine("physics-undo-max = " + Server.physUndo); w.WriteLine(); w.WriteLine("# backup options"); w.WriteLine("backup-time = " + Server.backupInterval.ToString()); diff --git a/util/Extensions.cs b/util/Extensions.cs index ae2d2accc..492108083 100644 --- a/util/Extensions.cs +++ b/util/Extensions.cs @@ -51,7 +51,7 @@ namespace MCGalaxy } return bytes; } - public static byte[] Decompress(this byte[] gzip) + public static byte[] Decompress(this byte[] gzip, int capacity = 16) { // Create a GZIP stream with decompression mode. // ... Then create a buffer and write into while reading from the GZIP stream. @@ -59,47 +59,19 @@ namespace MCGalaxy { const int size = 4096; byte[] buffer = new byte[size]; - using (MemoryStream memory = new MemoryStream()) + using (MemoryStream memory = new MemoryStream(capacity)) { int count = 0; - do - { + do { count = stream.Read(buffer, 0, size); if (count > 0) - { memory.Write(buffer, 0, count); - } - } - while (count > 0); + } while (count > 0); return memory.ToArray(); } } } - public static string[] Slice(this string[] str, int offset) - { - return str.Slice(offset, 0); - } - public static string[] Slice(this string[] str, int offset, int length) - { - IEnumerable tmp = str.ToList(); - if (offset > 0) - { - tmp = str.Skip(offset); - } - else throw new NotImplementedException("This function only supports positive integers for offset"); - if (length > 0) - { - tmp = tmp.Take(length); - } - else if (length == 0) - { - // Do nothing - } - else throw new NotImplementedException("This function only supports non-negative integers for length"); - - return tmp.ToArray(); - } public static string Capitalize(this string str) { if (String.IsNullOrEmpty(str)) @@ -144,13 +116,6 @@ namespace MCGalaxy return sb.ToString(); } - public static string GetMimeType(this FileInfo file) - { - Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(file.Extension.ToLower()); - if (rk != null && rk.GetValue("Content Type") != null) - return rk.GetValue("Content Type").ToString(); - return "application/octet-stream"; - } public static void DeleteLine(string file, string line) {