mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-19 12:18:03 -04:00
Fallback to slower /undo if this /undo would overlap previous undos
Fixes when doing /z,/undo,/redo,/undo 1h, /undo 1h, /undo 1h etc, each /undo 1h would replay the previous /undo1h,/redo,/undo.. etc which could be abused to incredibly spam the BlockDB
This commit is contained in:
parent
1bef2d5315
commit
85aa55a84b
@ -62,7 +62,8 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
}
|
||||
|
||||
void PerformHighlight() {
|
||||
if (ids.Length > 0) {
|
||||
if (ids.Length == 0) return;
|
||||
|
||||
// can't use "using" as it creates a local var, and read lock reference may be changed by DrawOpPerformer class
|
||||
try {
|
||||
BlockDBReadLock = Level.BlockDB.Locker.AccquireRead();
|
||||
@ -71,7 +72,6 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
if (BlockDBReadLock != null) BlockDBReadLock.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DrawOpOutput output;
|
||||
Vec3U16 dims;
|
||||
|
@ -62,7 +62,8 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
}
|
||||
|
||||
void PerformUndo() {
|
||||
if (ids.Length > 0) {
|
||||
if (ids.Length == 0) return;
|
||||
|
||||
// can't use "using" as it creates a local var, and read lock reference may be changed by DrawOpPerformer class
|
||||
try {
|
||||
BlockDBReadLock = Level.BlockDB.Locker.AccquireRead();
|
||||
@ -70,11 +71,22 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
} finally {
|
||||
if (BlockDBReadLock != null) BlockDBReadLock.Dispose();
|
||||
}
|
||||
|
||||
if (oldest == null) return;
|
||||
foreach (var kvp in oldest) {
|
||||
int index = kvp.Key;
|
||||
|
||||
int x = index % dims.X;
|
||||
int y = (index / dims.X) / dims.Z;
|
||||
int z = (index / dims.X) % dims.Z;
|
||||
output(Place((ushort)x, (ushort)y, (ushort)z, kvp.Value));
|
||||
}
|
||||
}
|
||||
|
||||
DrawOpOutput output;
|
||||
Vec3U16 dims;
|
||||
bool conservative;
|
||||
Dictionary<int, BlockID> oldest;
|
||||
|
||||
void UndoBlock(BlockDBEntry e) {
|
||||
BlockID block = e.OldBlock;
|
||||
@ -86,6 +98,24 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
|
||||
if (x < Min.X || y < Min.Y || z < Min.Z) return;
|
||||
if (x > Max.X || y > Max.Y || z > Max.Z) return;
|
||||
|
||||
if (conservative) {
|
||||
oldest[e.Index] = block;
|
||||
return;
|
||||
}
|
||||
|
||||
const int flags = BlockDBFlags.UndoOther | BlockDBFlags.UndoSelf;
|
||||
if ((e.Flags & flags) != 0) {
|
||||
Player.Message("%WThis undo overlaps with previous undos, " +
|
||||
"so undoing may take longer..");
|
||||
oldest = new Dictionary<int, BlockID>();
|
||||
oldest[e.Index] = block;
|
||||
|
||||
conservative = true;
|
||||
found = true;
|
||||
return;
|
||||
}
|
||||
|
||||
output(Place((ushort)x, (ushort)y, (ushort)z, block));
|
||||
found = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user