mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-25 22:30:52 -04:00
Shave two bytes off each undo entry, reduces memory usage even further.
This commit is contained in:
parent
1d48c3822a
commit
9c2d3f14bf
@ -77,12 +77,14 @@ namespace MCGalaxy.Commands {
|
||||
for (int i = items.Count - 1; i >= 0; i--) {
|
||||
UndoCacheItem item = items[i];
|
||||
ushort x, y, z;
|
||||
node.Unpack(item.Index, out x, out y, out z);
|
||||
node.Unpack(item.Index, out x, out y, out z);
|
||||
DateTime time = node.BaseTime.AddSeconds(item.TimeDelta + seconds);
|
||||
if (time < DateTime.UtcNow) return;
|
||||
|
||||
byte b = lvl.GetTile(x, y, z);
|
||||
if (b == item.NewType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
||||
byte newTile = 0, newExtTile = 0;
|
||||
item.GetNewExtBlock(out newTile, out newExtTile);
|
||||
if (b == newTile || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
||||
if (b == Block.air || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
|
||||
p.SendBlockchange(x, y, z, Block.red);
|
||||
else
|
||||
|
@ -49,13 +49,12 @@ namespace MCGalaxy.Commands {
|
||||
for (int i = items.Count - 1; i >= 0; i--) {
|
||||
UndoCacheItem item = items[i];
|
||||
ushort x, y, z;
|
||||
node.Unpack(item.Index, out x, out y, out z);
|
||||
node.Unpack(item.Index, out x, out y, out z);
|
||||
byte tile, extTile;
|
||||
item.GetExtBlock(out tile, out extTile);
|
||||
|
||||
byte type = lvl.GetTile(x, y, z), extType = 0;
|
||||
if (type == Block.custom_block)
|
||||
extType = lvl.GetExtTile(x, y, z);
|
||||
if (lvl.DoBlockchange(p, x, y, z, item.Type, item.ExtType)) {
|
||||
buffer.Add(lvl.PosToInt(x, y, z), item.Type, item.ExtType);
|
||||
if (lvl.DoBlockchange(p, x, y, z, tile, extTile)) {
|
||||
buffer.Add(lvl.PosToInt(x, y, z), tile, extTile);
|
||||
buffer.CheckIfSend(false);
|
||||
}
|
||||
}
|
||||
|
@ -177,16 +177,21 @@ namespace MCGalaxy.Commands
|
||||
if (time < DateTime.UtcNow) { buffer.CheckIfSend(true); return; }
|
||||
|
||||
byte b = lvl.GetTile(x, y, z);
|
||||
if (b == item.NewType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
||||
byte newTile = 0, newExtTile = 0;
|
||||
item.GetNewExtBlock(out newTile, out newExtTile);
|
||||
if (b == newTile || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {
|
||||
Player.UndoPos uP = default(Player.UndoPos);
|
||||
uP.newtype = item.Type; uP.newExtType = item.ExtType;
|
||||
byte extType = 0;
|
||||
if (b == Block.custom_block) extType = lvl.GetExtTile(x, y, z);
|
||||
if (lvl.DoBlockchange(p, x, y, z, item.Type, item.ExtType)) {
|
||||
buffer.Add(lvl.PosToInt(x, y, z), item.Type, item.ExtType);
|
||||
if (b == Block.custom_block) extType = lvl.GetExtTile(x, y, z);
|
||||
byte tile = 0, extTile = 0;
|
||||
item.GetExtBlock(out tile, out extTile);
|
||||
|
||||
if (lvl.DoBlockchange(p, x, y, z, tile, extTile)) {
|
||||
buffer.Add(lvl.PosToInt(x, y, z), tile, extTile);
|
||||
buffer.CheckIfSend(false);
|
||||
}
|
||||
|
||||
uP.newtype = tile; uP.newExtType = extTile;
|
||||
uP.type = b; uP.extType = extType;
|
||||
uP.x = x; uP.y = y; uP.z = z;
|
||||
uP.mapName = node.MapName;
|
||||
|
@ -34,6 +34,8 @@ namespace MCGalaxy.Util {
|
||||
/// <summary> Total number of items in the cache. </summary>
|
||||
public volatile int Count;
|
||||
|
||||
public const int TimeDeltaMax = (1 << 13) - 1;
|
||||
|
||||
/// <summary> Appends an item to the cache. </summary>
|
||||
public void Add(Level lvl, Player.UndoPos item) {
|
||||
DateTime time = Server.StartTime.AddTicks(item.timeDelta * TimeSpan.TicksPerSecond);
|
||||
@ -43,7 +45,7 @@ namespace MCGalaxy.Util {
|
||||
}
|
||||
|
||||
if (lvl.name != Tail.MapName || lvl.Width != Tail.Width || lvl.Height != Tail.Height ||
|
||||
lvl.Length != Tail.Length || Math.Abs((time - Tail.BaseTime).TotalSeconds) > 32767) {
|
||||
lvl.Length != Tail.Length || Math.Abs((time - Tail.BaseTime).TotalSeconds) > TimeDeltaMax) {
|
||||
UndoCacheNode node = UndoCacheNode.Make(lvl, time);
|
||||
Tail.Next = node; node.Prev = Tail;
|
||||
Tail = node;
|
||||
@ -95,16 +97,53 @@ namespace MCGalaxy.Util {
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct UndoCacheItem {
|
||||
public int Index;
|
||||
public byte Type, ExtType;
|
||||
public byte NewType, NewExtType;
|
||||
public short TimeDelta;
|
||||
public byte Type, NewType;
|
||||
public ushort Flags; // upper 2 bits for 'ext' or 'physics' type, lower 14 bits for time delta.
|
||||
|
||||
public short TimeDelta {
|
||||
get {
|
||||
int delta = Flags & 0x3FFF;
|
||||
return delta >= 0x2000 ? (short)(delta - 16384) : (short)delta;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetExtBlock(out byte type, out byte extType) {
|
||||
if ((Flags & (1 << 14)) != 0) {
|
||||
type = Block.custom_block;
|
||||
extType = Type;
|
||||
} else {
|
||||
type = Type;
|
||||
extType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetNewExtBlock(out byte type, out byte extType) {
|
||||
if ((Flags & (1 << 15)) != 0) {
|
||||
type = Block.custom_block;
|
||||
extType = NewType;
|
||||
} else {
|
||||
type = NewType;
|
||||
extType = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static UndoCacheItem Make(UndoCacheNode node, short timeDelta, ref Player.UndoPos pos) {
|
||||
UndoCacheItem item = default(UndoCacheItem);
|
||||
item.Index = pos.x + node.Width * (pos.z + node.Length * pos.y);
|
||||
item.Type = pos.type; item.ExtType = pos.extType;
|
||||
item.NewType = pos.newtype; item.NewExtType = pos.newExtType;
|
||||
item.TimeDelta = timeDelta;
|
||||
item.Flags = (ushort)(timeDelta & 0x3FFF);
|
||||
|
||||
if (pos.type == Block.custom_block) {
|
||||
item.Type = pos.extType;
|
||||
item.Flags |= (ushort)(1 << 14);
|
||||
} else {
|
||||
item.Type = pos.type;
|
||||
}
|
||||
if (pos.newtype == Block.custom_block) {
|
||||
item.NewType = pos.newExtType;
|
||||
item.Flags |= (ushort)(1 << 15);
|
||||
} else {
|
||||
item.NewType = pos.newtype;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
@ -70,13 +70,18 @@ namespace MCGalaxy.Util {
|
||||
WriteChunkEntries(w, last.Entries, entriesPos);
|
||||
last = WriteEmptyChunk(w, node.MapName, time, ref entriesPos);
|
||||
}
|
||||
|
||||
ushort x, y, z;
|
||||
node.Unpack(uP.Index, out x, out y, out z);
|
||||
byte tile = 0, extTile = 0;
|
||||
uP.GetExtBlock(out tile, out extTile);
|
||||
byte newTile = 0, newExtTile = 0;
|
||||
uP.GetNewExtBlock(out newTile, out newExtTile);
|
||||
|
||||
w.Write((ushort)timeDiff);
|
||||
w.Write(x); w.Write(y); w.Write(z);
|
||||
w.Write(uP.Type); w.Write(uP.ExtType);
|
||||
w.Write(uP.NewType); w.Write(uP.NewExtType);
|
||||
w.Write(tile); w.Write(extTile);
|
||||
w.Write(newTile); w.Write(newExtTile);
|
||||
last.Entries++;
|
||||
}
|
||||
if (last.Entries > 0)
|
||||
@ -152,7 +157,7 @@ namespace MCGalaxy.Util {
|
||||
Pos.newtype = oldType; Pos.newExtType = oldExtType;
|
||||
Pos.extType = newExtType; 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.Add(lvl.PosToInt(Pos.x, Pos.y, Pos.z), Pos.newtype, Pos.newExtType);
|
||||
buffer.CheckIfSend(false);
|
||||
}
|
||||
if (p != null) p.RedoBuffer.Add(lvl, Pos);
|
||||
|
Loading…
x
Reference in New Issue
Block a user