mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-08 14:48:47 -04:00
Fix /undo physics, allow configuring server max undo physics, gzip compress copy state files.
This commit is contained in:
parent
33464a72ea
commit
20192c70c9
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user