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");
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;

View File

@ -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();
}

View File

@ -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());

View File

@ -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<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)
{
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)
{