Fix /undo physics, allow configuring server max undo physics, gzip compress copy state files.

This commit is contained in:
UnknownShadow200 2016-02-02 22:24:27 +11:00
parent 33464a72ea
commit 20192c70c9
4 changed files with 49 additions and 57 deletions

View File

@ -133,18 +133,22 @@ namespace MCGalaxy.Commands
Command.all.Find("physics").Use(p, "0"); Command.all.Find("physics").Use(p, "0");
if (p.level.UndoBuffer.Count != Server.physUndo) { 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 { try {
Level.UndoPos uP = p.level.UndoBuffer[i]; if (!CheckBlockPhysics(p, seconds, i, p.level.UndoBuffer[i])) break;
if (!CheckBlockPhysics(p, seconds, uP)) break;
} catch { } } catch { }
} }
} else { } 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 { try {
if (i < 0) i = p.level.UndoBuffer.Count - 1; if (!CheckBlockPhysics(p, seconds, i, p.level.UndoBuffer[i])) break;
Level.UndoPos uP = p.level.UndoBuffer[i]; } catch { }
if (!CheckBlockPhysics(p, seconds, uP)) break; }
for (int i = p.level.UndoBuffer.Count - 1; i > count; i--) {
try {
if (!CheckBlockPhysics(p, seconds, i, p.level.UndoBuffer[i])) break;
} catch { } } catch { }
} }
} }
@ -174,14 +178,17 @@ namespace MCGalaxy.Commands
return true; 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); byte b = p.level.GetTile(undo.location);
if (undo.timePerformed.AddSeconds(seconds) < DateTime.Now) if (undo.timePerformed.AddSeconds(seconds) < DateTime.Now)
return false; return false;
if (b == undo.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) { if (b == undo.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
ushort x, y, z; 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); p.level.Blockchange(x, y, z, undo.oldType, true, "", undo.oldExtType);
} }
return true; return true;

View File

@ -28,6 +28,7 @@ namespace MCGalaxy.Drawing {
public int Width, Height, Length; public int Width, Height, Length;
const int identifier = 0x434F5059; // 'COPY' const int identifier = 0x434F5059; // 'COPY'
const int identifierC = 0x434F5043; // 'COPC' (Copy compressed)
public int Volume { public int Volume {
get { return Width * Height * Length; } get { return Width * Height * Length; }
@ -74,24 +75,38 @@ namespace MCGalaxy.Drawing {
public void SaveTo(Stream stream) { public void SaveTo(Stream stream) {
BinaryWriter w = new BinaryWriter(stream); BinaryWriter w = new BinaryWriter(stream);
w.Write(identifier); w.Write(identifierC);
w.Write(X); w.Write(Y); w.Write(Z); w.Write(X); w.Write(Y); w.Write(Z);
w.Write(Width); w.Write(Height); w.Write(Length); 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); w.Write(OriginX); w.Write(OriginY); w.Write(OriginZ);
} }
public void LoadFrom(Stream stream) { public void LoadFrom(Stream stream) {
BinaryReader r = new BinaryReader(stream); BinaryReader r = new BinaryReader(stream);
if (r.ReadInt32() != identifier) int header = r.ReadInt32();
if (!(header == identifier || header == identifierC))
throw new InvalidDataException("invalid identifier"); throw new InvalidDataException("invalid identifier");
X = r.ReadInt32(); Y = r.ReadInt32(); Z = r.ReadInt32(); X = r.ReadInt32(); Y = r.ReadInt32(); Z = r.ReadInt32();
Width = r.ReadInt32(); Height = r.ReadInt32(); Length = r.ReadInt32(); Width = r.ReadInt32(); Height = r.ReadInt32(); Length = r.ReadInt32();
Blocks = r.ReadBytes(Width * Height * Length); if (header == identifier) {
ExtBlocks = r.ReadBytes(Width * Height * Length); 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(); OriginX = r.ReadInt32(); OriginY = r.ReadInt32(); OriginZ = r.ReadInt32();
} }

View File

@ -554,7 +554,11 @@ namespace MCGalaxy {
try { Server.totalUndo = int.Parse(value); } try { Server.totalUndo = int.Parse(value); }
catch { Server.s.Log("Invalid " + key + ". Using default"); } catch { Server.s.Log("Invalid " + key + ". Using default"); }
break; 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": case "review-view-perm":
try { try {
sbyte parsed = sbyte.Parse(value); sbyte parsed = sbyte.Parse(value);
@ -820,7 +824,8 @@ namespace MCGalaxy {
w.WriteLine("guest-limit-notify = " + Server.guestLimitNotify.ToString().ToLower()); w.WriteLine("guest-limit-notify = " + Server.guestLimitNotify.ToString().ToLower());
w.WriteLine("guest-join-notify = " + Server.guestJoinNotify.ToString().ToLower()); w.WriteLine("guest-join-notify = " + Server.guestJoinNotify.ToString().ToLower());
w.WriteLine("guest-leave-notify = " + Server.guestLeaveNotify.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();
w.WriteLine("# backup options"); w.WriteLine("# backup options");
w.WriteLine("backup-time = " + Server.backupInterval.ToString()); w.WriteLine("backup-time = " + Server.backupInterval.ToString());

View File

@ -51,7 +51,7 @@ namespace MCGalaxy
} }
return bytes; 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. // Create a GZIP stream with decompression mode.
// ... Then create a buffer and write into while reading from the GZIP stream. // ... Then create a buffer and write into while reading from the GZIP stream.
@ -59,47 +59,19 @@ namespace MCGalaxy
{ {
const int size = 4096; const int size = 4096;
byte[] buffer = new byte[size]; byte[] buffer = new byte[size];
using (MemoryStream memory = new MemoryStream()) using (MemoryStream memory = new MemoryStream(capacity))
{ {
int count = 0; int count = 0;
do do {
{
count = stream.Read(buffer, 0, size); count = stream.Read(buffer, 0, size);
if (count > 0) if (count > 0)
{
memory.Write(buffer, 0, count); memory.Write(buffer, 0, count);
} } while (count > 0);
}
while (count > 0);
return memory.ToArray(); 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<string> 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) public static string Capitalize(this string str)
{ {
if (String.IsNullOrEmpty(str)) if (String.IsNullOrEmpty(str))
@ -144,13 +116,6 @@ namespace MCGalaxy
return sb.ToString(); 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) public static void DeleteLine(string file, string line)
{ {