From 9c88ce73ad2ea34ced4904459e81dcf7bd6977b2 Mon Sep 17 00:00:00 2001 From: "Alex \"mcmonkey\" Goodwin" Date: Wed, 18 May 2022 15:38:27 -0700 Subject: [PATCH] schematic: error check to deconflict delayed processing --- .../commands/world/SchematicCommand.java | 73 +++++++++++++++---- .../utilities/blocks/CuboidBlockSet.java | 19 +---- 2 files changed, 61 insertions(+), 31 deletions(-) diff --git a/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/world/SchematicCommand.java b/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/world/SchematicCommand.java index e816dc02e8..738b350d05 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/world/SchematicCommand.java +++ b/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/world/SchematicCommand.java @@ -204,9 +204,12 @@ public static void rotateSchem(CuboidBlockSet schematic, int angle, boolean dela } } finally { + if (delayed) { + Bukkit.getScheduler().runTask(Denizen.instance, () -> schematic.isModifying = false); + } if (callback != null) { if (delayed) { - Bukkit.getScheduler().runTask(Denizen.getInstance(), callback); + Bukkit.getScheduler().runTask(Denizen.instance, callback); } else { callback.run(); @@ -215,7 +218,8 @@ public static void rotateSchem(CuboidBlockSet schematic, int angle, boolean dela } }; if (delayed) { - Bukkit.getScheduler().runTaskAsynchronously(Denizen.getInstance(), rotateRunnable); + schematic.isModifying = true; + Bukkit.getScheduler().runTaskAsynchronously(Denizen.instance, rotateRunnable); } else { rotateRunnable.run(); @@ -345,7 +349,7 @@ public void execute(final ScriptEntry scriptEntry) { scriptEntry.setFinished(true); }; if (delayed) { - Bukkit.getScheduler().runTask(Denizen.getInstance(), storeSchem); + Bukkit.getScheduler().runTask(Denizen.instance, storeSchem); } else { storeSchem.run(); @@ -357,7 +361,7 @@ public void execute(final ScriptEntry scriptEntry) { Debug.echoError(scriptEntry, ex); }; if (delayed) { - Bukkit.getScheduler().runTask(Denizen.getInstance(), showError); + Bukkit.getScheduler().runTask(Denizen.instance, showError); } else { showError.run(); @@ -367,7 +371,7 @@ public void execute(final ScriptEntry scriptEntry) { } }; if (delayed) { - Bukkit.getScheduler().runTaskAsynchronously(Denizen.getInstance(), loadRunnable); + Bukkit.getScheduler().runTaskAsynchronously(Denizen.instance, loadRunnable); } else { loadRunnable.run(); @@ -397,6 +401,10 @@ public void execute(final ScriptEntry scriptEntry) { return; } final CuboidBlockSet schematic = schematics.get(name.asString().toUpperCase()); + if (schematic.isModifying || schematic.readingProcesses > 0) { + Debug.echoError("Cannot rotate schematic: schematic is currently processing another instruction."); + return; + } rotateSchem(schematic, angle.asInt(), delayed, () -> scriptEntry.setFinished(true)); break; } @@ -406,7 +414,12 @@ public void execute(final ScriptEntry scriptEntry) { scriptEntry.setFinished(true); return; } - schematics.get(name.asString().toUpperCase()).flipX(); + final CuboidBlockSet schematic = schematics.get(name.asString().toUpperCase()); + if (schematic.isModifying || schematic.readingProcesses > 0) { + Debug.echoError("Cannot flip schematic: schematic is currently processing another instruction."); + return; + } + schematic.flipX(); scriptEntry.setFinished(true); break; } @@ -416,7 +429,12 @@ public void execute(final ScriptEntry scriptEntry) { scriptEntry.setFinished(true); return; } - schematics.get(name.asString().toUpperCase()).flipY(); + final CuboidBlockSet schematic = schematics.get(name.asString().toUpperCase()); + if (schematic.isModifying || schematic.readingProcesses > 0) { + Debug.echoError("Cannot flip schematic: schematic is currently processing another instruction."); + return; + } + schematic.flipY(); scriptEntry.setFinished(true); break; } @@ -426,7 +444,12 @@ public void execute(final ScriptEntry scriptEntry) { scriptEntry.setFinished(true); return; } - schematics.get(name.asString().toUpperCase()).flipZ(); + final CuboidBlockSet schematic = schematics.get(name.asString().toUpperCase()); + if (schematic.isModifying || schematic.readingProcesses > 0) { + Debug.echoError("Cannot flip schematic: schematic is currently processing another instruction."); + return; + } + schematic.flipZ(); scriptEntry.setFinished(true); break; } @@ -472,13 +495,25 @@ public void execute(final ScriptEntry scriptEntry) { } } set = schematics.get(name.asString().toUpperCase()); + if (set.isModifying) { + Debug.echoError("Cannot paste schematic: schematic is currently processing another instruction."); + return; + } Consumer pasteRunnable = (schematic) -> { if (delayed) { + schematic.readingProcesses++; schematic.setBlocksDelayed(() -> { - if (copyEntities) { - schematic.pasteEntities(location); + try { + if (copyEntities) { + schematic.pasteEntities(location); + } + } + finally { + Bukkit.getScheduler().runTask(Denizen.instance, () -> { + scriptEntry.setFinished(true); + schematic.readingProcesses--; + }); } - scriptEntry.setFinished(true); }, input, maxDelayMs.asLong()); } else { @@ -511,6 +546,10 @@ public void execute(final ScriptEntry scriptEntry) { return; } set = schematics.get(name.asString().toUpperCase()); + if (set.isModifying) { + Debug.echoError("Cannot save schematic: schematic is currently processing another instruction."); + return; + } String directory = URLDecoder.decode(System.getProperty("user.dir")); String extension = ".schem"; File f = new File(directory + "/plugins/Denizen/schematics/" + fname + extension); @@ -526,19 +565,21 @@ public void execute(final ScriptEntry scriptEntry) { SpongeSchematicHelper.saveToSpongeStream(set, fs); fs.flush(); fs.close(); - Bukkit.getScheduler().runTask(Denizen.getInstance(), () -> scriptEntry.setFinished(true)); } catch (Exception ex) { - Bukkit.getScheduler().runTask(Denizen.getInstance(), () -> { + Bukkit.getScheduler().runTask(Denizen.instance, () -> { Debug.echoError(scriptEntry, "Error saving schematic file " + fname + "."); Debug.echoError(scriptEntry, ex); }); - scriptEntry.setFinished(true); - return; } + Bukkit.getScheduler().runTask(Denizen.instance, () -> { + set.readingProcesses--; + scriptEntry.setFinished(true); + }); }; if (delayed) { - Bukkit.getScheduler().runTaskAsynchronously(Denizen.getInstance(), saveRunnable); + set.readingProcesses++; + Bukkit.getScheduler().runTaskAsynchronously(Denizen.instance, saveRunnable); } else { scriptEntry.setFinished(true); diff --git a/plugin/src/main/java/com/denizenscript/denizen/utilities/blocks/CuboidBlockSet.java b/plugin/src/main/java/com/denizenscript/denizen/utilities/blocks/CuboidBlockSet.java index ba5d2dd8fe..3f52bf0b7c 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/utilities/blocks/CuboidBlockSet.java +++ b/plugin/src/main/java/com/denizenscript/denizen/utilities/blocks/CuboidBlockSet.java @@ -134,6 +134,10 @@ public void run() { public ListTag entities = null; + public boolean isModifying = false; + + public int readingProcesses = 0; + public CuboidBlockSet duplicate() { CuboidBlockSet result = new CuboidBlockSet(); result.blocks = blocks.clone(); @@ -398,20 +402,5 @@ public void flipZ() { public FullBlockData blockAt(double X, double Y, double Z) { return blocks[(int) (Z + Y * z_height + X * z_height * y_length)]; - // This calculation should produce the same result as the below nonsense: - /* - int index = 0; - for (int x = 0; x < x_width; x++) { - for (int y = 0; y < y_length; y++) { - for (int z = 0; z < z_height; z++) { - if (x == X && y == Y && z == Z) { - return blocks.get(index); - } - index++; - } - } - } - return null; - */ } }