From e9ff7b6dc77609727b026430df5890d5eb3a8ef8 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 11:51:53 +1000 Subject: [PATCH 01/11] Add foundations for example script API --- .../skript/examples/CoreExampleScripts.java | 40 +++++++++++++++++++ .../njol/skript/examples/ExampleScript.java | 3 ++ 2 files changed, 43 insertions(+) create mode 100644 src/main/java/ch/njol/skript/examples/CoreExampleScripts.java create mode 100644 src/main/java/ch/njol/skript/examples/ExampleScript.java diff --git a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java new file mode 100644 index 00000000000..7118ade2aa8 --- /dev/null +++ b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java @@ -0,0 +1,40 @@ +package ch.njol.skript.examples; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; + +public final class CoreExampleScripts { + + public static final List EXAMPLES = List.of( + load("chest menus.sk"), + load("commands.sk"), + load("events.sk"), + load("experimental features/for loops.sk"), + load("experimental features/queues.sk"), + load("experimental features/script reflection.sk"), + load("functions.sk"), + load("loops.sk"), + load("options and meta.sk"), + load("text formatting.sk"), + load("timings.sk"), + load("variables.sk") + ); + + private CoreExampleScripts() { + } + + private static ExampleScript load(String name) { + String path = "scripts/-examples/" + name; + try (InputStream in = CoreExampleScripts.class.getClassLoader().getResourceAsStream(path)) { + if (in == null) { + throw new IllegalStateException("Missing example script " + path); + } + String content = new String(in.readAllBytes(), StandardCharsets.UTF_8); + return new ExampleScript(name, content); + } catch (IOException e) { + throw new RuntimeException("Failed to load example script " + path, e); + } + } +} \ No newline at end of file diff --git a/src/main/java/ch/njol/skript/examples/ExampleScript.java b/src/main/java/ch/njol/skript/examples/ExampleScript.java new file mode 100644 index 00000000000..a1364b4f5c2 --- /dev/null +++ b/src/main/java/ch/njol/skript/examples/ExampleScript.java @@ -0,0 +1,3 @@ +package ch.njol.skript.examples; + +public record ExampleScript(String name, String content) {} \ No newline at end of file From 6d7e59cf7070d24650c873a6f9dce3a3e322d36c Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 11:59:51 +1000 Subject: [PATCH 02/11] Add ExampleScriptManager --- .../skript/examples/ExampleScriptManager.java | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/java/ch/njol/skript/examples/ExampleScriptManager.java diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java new file mode 100644 index 00000000000..10b27bafc1e --- /dev/null +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -0,0 +1,72 @@ +package ch.njol.skript.examples; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +public final class ExampleScriptManager { + private static Set installed; + private static File installedFile; + + private ExampleScriptManager() { + } + + private static void loadInstalled(File scriptsDir) { + installedFile = new File(scriptsDir, "examples.installed"); + installed = new HashSet<>(); + if (!installedFile.exists()) { + return; + } + try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(installedFile), StandardCharsets.UTF_8))) { + String line; + while ((line = reader.readLine()) != null) { + installed.add(line); + } + } catch (IOException e) { + throw new RuntimeException("Failed to load installed examples", e); + } + } + + private static void flushInstalled() { + if (installedFile == null) { + return; + } + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installedFile), StandardCharsets.UTF_8))) { + for (String entry : installed) { + writer.write(entry); + writer.newLine(); + } + } catch (IOException e) { + throw new RuntimeException("Failed to save installed examples", e); + } + } + + public static void installExamples(String plugin, Collection scripts, File scriptsDir) { + if (installed == null) { + loadInstalled(scriptsDir); + } + File baseDir = new File(scriptsDir, "-examples/" + plugin); + for (ExampleScript script : scripts) { + String key = plugin + "/" + script.name(); + if (installed.add(key)) { + File file = new File(baseDir, script.name()); + file.getParentFile().mkdirs(); + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { + writer.write(script.content()); + } catch (IOException e) { + throw new RuntimeException("Failed to write example script " + file, e); + } + } + } + flushInstalled(); + } +} \ No newline at end of file From a49bac4a00a5471818e62fdb0b506cd3792b98d7 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:24:14 +1000 Subject: [PATCH 03/11] Next step towards finishing example script API --- src/main/java/ch/njol/skript/Skript.java | 23 +++++++++---------- .../skript/examples/CoreExampleScripts.java | 5 ++++ .../skript/examples/ExampleScriptManager.java | 12 +++++----- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index d44ee843f79..712c00b0148 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -14,6 +14,8 @@ import ch.njol.skript.command.Commands; import ch.njol.skript.doc.Documentation; import ch.njol.skript.events.EvtSkript; +import ch.njol.skript.examples.CoreExampleScripts; +import ch.njol.skript.examples.ExampleScriptManager; import ch.njol.skript.hooks.Hook; import ch.njol.skript.lang.*; import ch.njol.skript.lang.Condition.ConditionType; @@ -184,6 +186,8 @@ public final class Skript extends JavaPlugin implements Listener { private static boolean disabled = false; private static boolean partDisabled = false; + public static @Nullable ExampleScriptManager exampleManager; + public static Skript getInstance() { if (instance == null) throw new IllegalStateException(); @@ -419,11 +423,9 @@ public void onEnable() { if (!scriptsFolder.isDirectory() || !config.exists() || !features.exists() || !lang.exists() || !aliasesFolder.exists()) { ZipFile f = null; try { - boolean populateExamples = false; if (!scriptsFolder.isDirectory()) { if (!scriptsFolder.mkdirs()) throw new IOException("Could not create the directory " + scriptsFolder); - populateExamples = true; } boolean populateLanguageFiles = false; @@ -443,15 +445,9 @@ public void onEnable() { if (e.isDirectory()) continue; File saveTo = null; - if (populateExamples && e.getName().startsWith(SCRIPTSFOLDER + "/")) { - String fileName = e.getName().substring(e.getName().indexOf("/") + 1); - // All example scripts must be disabled for jar security. - if (!fileName.startsWith(ScriptLoader.DISABLED_SCRIPT_PREFIX)) - fileName = ScriptLoader.DISABLED_SCRIPT_PREFIX + fileName; - saveTo = new File(scriptsFolder, fileName); - } else if (populateLanguageFiles - && e.getName().startsWith("lang/") - && !e.getName().endsWith("default.lang")) { + if (populateLanguageFiles + && e.getName().startsWith("lang/") + && !e.getName().endsWith("default.lang")) { String fileName = e.getName().substring(e.getName().lastIndexOf("/") + 1); saveTo = new File(lang, fileName); } else if (e.getName().equals("config.sk")) { @@ -475,7 +471,7 @@ public void onEnable() { } } } - info("Successfully generated the config and the example scripts."); + info("Successfully generated the config."); } catch (ZipException ignored) {} catch (IOException e) { error("Error generating the default files: " + ExceptionUtils.toString(e)); } finally { @@ -487,6 +483,9 @@ public void onEnable() { } } + exampleManager = new ExampleScriptManager(); + exampleManager.installExamples("Skript", CoreExampleScripts.all(), scriptsFolder); + // initialize the modern Skript instance skript = org.skriptlang.skript.Skript.of(getClass(), getName()); unmodifiableSkript = new ModernSkriptBridge.SpecialUnmodifiableSkript(skript); diff --git a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java index 7118ade2aa8..c723cee628c 100644 --- a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java +++ b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.List; public final class CoreExampleScripts { @@ -25,6 +26,10 @@ public final class CoreExampleScripts { private CoreExampleScripts() { } + public static Collection all() { + return EXAMPLES; + } + private static ExampleScript load(String name) { String path = "scripts/-examples/" + name; try (InputStream in = CoreExampleScripts.class.getClassLoader().getResourceAsStream(path)) { diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index 10b27bafc1e..fae88bc141c 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -14,13 +14,13 @@ import java.util.Set; public final class ExampleScriptManager { - private static Set installed; - private static File installedFile; + private Set installed; + private File installedFile; - private ExampleScriptManager() { + public ExampleScriptManager() { } - private static void loadInstalled(File scriptsDir) { + private void loadInstalled(File scriptsDir) { installedFile = new File(scriptsDir, "examples.installed"); installed = new HashSet<>(); if (!installedFile.exists()) { @@ -36,7 +36,7 @@ private static void loadInstalled(File scriptsDir) { } } - private static void flushInstalled() { + private void flushInstalled() { if (installedFile == null) { return; } @@ -50,7 +50,7 @@ private static void flushInstalled() { } } - public static void installExamples(String plugin, Collection scripts, File scriptsDir) { + public void installExamples(String plugin, Collection scripts, File scriptsDir) { if (installed == null) { loadInstalled(scriptsDir); } From d89c320f548b18d151c6802be74003b92472032a Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:26:29 +1000 Subject: [PATCH 04/11] Some small formatting changes --- .../ch/njol/skript/examples/CoreExampleScripts.java | 5 ++--- .../java/ch/njol/skript/examples/ExampleScript.java | 2 +- .../ch/njol/skript/examples/ExampleScriptManager.java | 11 ++++------- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java index c723cee628c..75458ba875b 100644 --- a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java +++ b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java @@ -33,13 +33,12 @@ public static Collection all() { private static ExampleScript load(String name) { String path = "scripts/-examples/" + name; try (InputStream in = CoreExampleScripts.class.getClassLoader().getResourceAsStream(path)) { - if (in == null) { + if (in == null) throw new IllegalStateException("Missing example script " + path); - } String content = new String(in.readAllBytes(), StandardCharsets.UTF_8); return new ExampleScript(name, content); } catch (IOException e) { throw new RuntimeException("Failed to load example script " + path, e); } } -} \ No newline at end of file +} diff --git a/src/main/java/ch/njol/skript/examples/ExampleScript.java b/src/main/java/ch/njol/skript/examples/ExampleScript.java index a1364b4f5c2..14ae116d16a 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScript.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScript.java @@ -1,3 +1,3 @@ package ch.njol.skript.examples; -public record ExampleScript(String name, String content) {} \ No newline at end of file +public record ExampleScript(String name, String content) {} diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index fae88bc141c..a7f36868012 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -23,9 +23,8 @@ public ExampleScriptManager() { private void loadInstalled(File scriptsDir) { installedFile = new File(scriptsDir, "examples.installed"); installed = new HashSet<>(); - if (!installedFile.exists()) { + if (!installedFile.exists()) return; - } try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(installedFile), StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { @@ -37,9 +36,8 @@ private void loadInstalled(File scriptsDir) { } private void flushInstalled() { - if (installedFile == null) { + if (installedFile == null) return; - } try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installedFile), StandardCharsets.UTF_8))) { for (String entry : installed) { writer.write(entry); @@ -51,9 +49,8 @@ private void flushInstalled() { } public void installExamples(String plugin, Collection scripts, File scriptsDir) { - if (installed == null) { + if (installed == null) loadInstalled(scriptsDir); - } File baseDir = new File(scriptsDir, "-examples/" + plugin); for (ExampleScript script : scripts) { String key = plugin + "/" + script.name(); @@ -69,4 +66,4 @@ public void installExamples(String plugin, Collection scripts, Fi } flushInstalled(); } -} \ No newline at end of file +} From ee3c29a93eb746cb90d86daf695f747a3fef2c50 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:49:56 +1000 Subject: [PATCH 05/11] Some final changes to example script API --- src/main/java/ch/njol/skript/SkriptAddon.java | 19 ++++++++++++ .../njol/skript/examples/ExampleScript.java | 31 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/SkriptAddon.java b/src/main/java/ch/njol/skript/SkriptAddon.java index af381ff3049..899c645326c 100644 --- a/src/main/java/ch/njol/skript/SkriptAddon.java +++ b/src/main/java/ch/njol/skript/SkriptAddon.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.function.Supplier; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -11,6 +12,7 @@ import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.Nullable; +import ch.njol.skript.examples.ExampleScript; import ch.njol.skript.util.Utils; import ch.njol.skript.util.Version; import org.jetbrains.annotations.ApiStatus; @@ -93,6 +95,23 @@ public String getLanguageFileDirectory() { return localizer().languageFileDirectory(); } + /** + * Registers example scripts with Skript for this addon. + * + * @param scripts Example scripts to install + * @throws IOException If an I/O error occurs while installing the scripts + */ + public void registerExampleScripts(ExampleScript... scripts) throws IOException { + if (Skript.exampleManager == null) { + throw new IllegalStateException("Example script manager is not initialized"); + } + Skript.exampleManager.installExamples( + plugin.getName(), + Arrays.asList(scripts), + Skript.getInstance().getScriptsFolder() + ); + } + @Nullable private File file; diff --git a/src/main/java/ch/njol/skript/examples/ExampleScript.java b/src/main/java/ch/njol/skript/examples/ExampleScript.java index 14ae116d16a..b5e474f73a3 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScript.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScript.java @@ -1,3 +1,32 @@ package ch.njol.skript.examples; -public record ExampleScript(String name, String content) {} +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import org.bukkit.plugin.java.JavaPlugin; + +/** + * Represents an example script bundled with Skript or an addon. + */ +public record ExampleScript(String name, String content) { + + /** + * Loads an example script from a resource contained within an addon JAR. + * + * @param plugin The plugin providing the resource + * @param resourcePath The path to the resource inside the plugin + * @param outputName The name of the file to install the example as + * @return A new {@link ExampleScript} containing the resource's content + * @throws IOException If the resource cannot be found or read + */ + public static ExampleScript fromResource(JavaPlugin plugin, String resourcePath, String outputName) throws IOException { + try (InputStream in = plugin.getResource(resourcePath)) { + if (in == null) { + throw new IOException("Resource not found: " + resourcePath); + } + String content = new String(in.readAllBytes(), StandardCharsets.UTF_8); + return new ExampleScript(outputName, content); + } + } +} \ No newline at end of file From 87fedee0b9abb2fcf070cf976d236e6e64a05f49 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 12:50:49 +1000 Subject: [PATCH 06/11] Some more small formatting changes --- src/main/java/ch/njol/skript/SkriptAddon.java | 4 ++-- .../java/ch/njol/skript/examples/CoreExampleScripts.java | 3 +-- src/main/java/ch/njol/skript/examples/ExampleScript.java | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/njol/skript/SkriptAddon.java b/src/main/java/ch/njol/skript/SkriptAddon.java index 899c645326c..68ffaf0129a 100644 --- a/src/main/java/ch/njol/skript/SkriptAddon.java +++ b/src/main/java/ch/njol/skript/SkriptAddon.java @@ -102,9 +102,9 @@ public String getLanguageFileDirectory() { * @throws IOException If an I/O error occurs while installing the scripts */ public void registerExampleScripts(ExampleScript... scripts) throws IOException { - if (Skript.exampleManager == null) { + if (Skript.exampleManager == null) throw new IllegalStateException("Example script manager is not initialized"); - } + Skript.exampleManager.installExamples( plugin.getName(), Arrays.asList(scripts), diff --git a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java index 75458ba875b..ca2418ddd5f 100644 --- a/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java +++ b/src/main/java/ch/njol/skript/examples/CoreExampleScripts.java @@ -23,8 +23,7 @@ public final class CoreExampleScripts { load("variables.sk") ); - private CoreExampleScripts() { - } + private CoreExampleScripts() {} public static Collection all() { return EXAMPLES; diff --git a/src/main/java/ch/njol/skript/examples/ExampleScript.java b/src/main/java/ch/njol/skript/examples/ExampleScript.java index b5e474f73a3..2a9ed7e6463 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScript.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScript.java @@ -22,11 +22,10 @@ public record ExampleScript(String name, String content) { */ public static ExampleScript fromResource(JavaPlugin plugin, String resourcePath, String outputName) throws IOException { try (InputStream in = plugin.getResource(resourcePath)) { - if (in == null) { + if (in == null) throw new IOException("Resource not found: " + resourcePath); - } String content = new String(in.readAllBytes(), StandardCharsets.UTF_8); return new ExampleScript(outputName, content); } } -} \ No newline at end of file +} From 4291cd6b7f30a3d0e23aabe0e3b00f0715f192f6 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:20:33 +1000 Subject: [PATCH 07/11] Use .loaded_examples instead of examples.installed --- src/main/java/ch/njol/skript/examples/ExampleScriptManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index a7f36868012..d36e3247ddf 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -21,7 +21,7 @@ public ExampleScriptManager() { } private void loadInstalled(File scriptsDir) { - installedFile = new File(scriptsDir, "examples.installed"); + installedFile = new File(scriptsDir.getParentFile(), ".loaded_examples"); installed = new HashSet<>(); if (!installedFile.exists()) return; From 812bf92c094188ef349092577342736eddef3c2d Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:44:08 +1000 Subject: [PATCH 08/11] Make .loaded_exmaples hidden --- .../java/ch/njol/skript/examples/ExampleScriptManager.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index d36e3247ddf..1f0f8220366 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -9,6 +9,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.Collection; import java.util.HashSet; import java.util.Set; @@ -46,6 +47,11 @@ private void flushInstalled() { } catch (IOException e) { throw new RuntimeException("Failed to save installed examples", e); } + if (System.getProperty("os.name").startsWith("Windows")) { + try { + Files.setAttribute(installedFile.toPath(), "dos:hidden", true); + } catch (Exception ignored) {} + } } public void installExamples(String plugin, Collection scripts, File scriptsDir) { From 7e080d9919138a9cc89aaab1e484238ec79bbfed Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sat, 20 Sep 2025 13:44:19 +1000 Subject: [PATCH 09/11] Add some safeguards to prevent error --- .../ch/njol/skript/examples/ExampleScriptManager.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index 1f0f8220366..c6e8cdbe1d8 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -1,5 +1,7 @@ package ch.njol.skript.examples; +import ch.njol.skript.Skript; + import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -39,13 +41,19 @@ private void loadInstalled(File scriptsDir) { private void flushInstalled() { if (installedFile == null) return; + File parent = installedFile.getParentFile(); + if (parent != null && !parent.exists() && !parent.mkdirs()) { + Skript.warning("Failed to create directory for installed examples at " + parent.getAbsolutePath()); + return; + } try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installedFile), StandardCharsets.UTF_8))) { for (String entry : installed) { writer.write(entry); writer.newLine(); } } catch (IOException e) { - throw new RuntimeException("Failed to save installed examples", e); + Skript.warning("Failed to save installed examples to " + installedFile + ": " + e.getMessage()); + return; } if (System.getProperty("os.name").startsWith("Windows")) { try { From 10d1f166e486124138fcff27ec79ee3e859aa118 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sat, 20 Sep 2025 14:38:40 +1000 Subject: [PATCH 10/11] Try to fix issue with marker file repopulation --- .../skript/examples/ExampleScriptManager.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index c6e8cdbe1d8..aa6c3f42fa6 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -13,7 +13,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.Collection; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; public final class ExampleScriptManager { @@ -24,14 +24,16 @@ public ExampleScriptManager() { } private void loadInstalled(File scriptsDir) { - installedFile = new File(scriptsDir.getParentFile(), ".loaded_examples"); - installed = new HashSet<>(); + File parent = scriptsDir.getParentFile(); + installedFile = new File(parent == null ? scriptsDir : parent, ".loaded_examples"); + installed = new LinkedHashSet<>(); if (!installedFile.exists()) return; try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(installedFile), StandardCharsets.UTF_8))) { String line; while ((line = reader.readLine()) != null) { - installed.add(line); + if (!line.isEmpty()) + installed.add(line); } } catch (IOException e) { throw new RuntimeException("Failed to load installed examples", e); @@ -39,7 +41,7 @@ private void loadInstalled(File scriptsDir) { } private void flushInstalled() { - if (installedFile == null) + if (installedFile == null || installed == null) return; File parent = installedFile.getParentFile(); if (parent != null && !parent.exists() && !parent.mkdirs()) { @@ -63,12 +65,13 @@ private void flushInstalled() { } public void installExamples(String plugin, Collection scripts, File scriptsDir) { - if (installed == null) - loadInstalled(scriptsDir); + loadInstalled(scriptsDir); + boolean dirty = false; File baseDir = new File(scriptsDir, "-examples/" + plugin); for (ExampleScript script : scripts) { String key = plugin + "/" + script.name(); if (installed.add(key)) { + dirty = true; File file = new File(baseDir, script.name()); file.getParentFile().mkdirs(); try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { @@ -78,6 +81,7 @@ public void installExamples(String plugin, Collection scripts, Fi } } } - flushInstalled(); + if (dirty) + flushInstalled(); } } From 9ad7df13072fccad3c13131e05c34845cf063e12 Mon Sep 17 00:00:00 2001 From: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Date: Sat, 20 Sep 2025 15:58:22 +1000 Subject: [PATCH 11/11] Fix issue with marker file repopulation --- .../skript/examples/ExampleScriptManager.java | 33 ++++++++++++++----- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java index aa6c3f42fa6..1586b7eca0c 100644 --- a/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java +++ b/src/main/java/ch/njol/skript/examples/ExampleScriptManager.java @@ -1,6 +1,7 @@ package ch.njol.skript.examples; import ch.njol.skript.Skript; +import org.bukkit.Bukkit; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -12,6 +13,8 @@ import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.DosFileAttributeView; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; @@ -20,8 +23,7 @@ public final class ExampleScriptManager { private Set installed; private File installedFile; - public ExampleScriptManager() { - } + public ExampleScriptManager() {} private void loadInstalled(File scriptsDir) { File parent = scriptsDir.getParentFile(); @@ -44,22 +46,37 @@ private void flushInstalled() { if (installedFile == null || installed == null) return; File parent = installedFile.getParentFile(); - if (parent != null && !parent.exists() && !parent.mkdirs()) { - Skript.warning("Failed to create directory for installed examples at " + parent.getAbsolutePath()); + if (parent != null && !parent.exists() && !parent.mkdirs()) // failed to create directory for installed examples return; + boolean isWindows = System.getProperty("os.name").startsWith("Windows"); + Path installedPath = installedFile.toPath(); + DosFileAttributeView dosView = null; + if (isWindows && Files.exists(installedPath)) { + dosView = Files.getFileAttributeView(installedPath, DosFileAttributeView.class); + if (dosView != null) { + try { + if (dosView.readAttributes().isHidden()) + dosView.setHidden(false); + } catch (IOException ignored) {} + } } + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installedFile), StandardCharsets.UTF_8))) { for (String entry : installed) { writer.write(entry); writer.newLine(); } - } catch (IOException e) { - Skript.warning("Failed to save installed examples to " + installedFile + ": " + e.getMessage()); + } catch (IOException e) { // failed to save installed examples return; } - if (System.getProperty("os.name").startsWith("Windows")) { + + if (isWindows) { try { - Files.setAttribute(installedFile.toPath(), "dos:hidden", true); + if (dosView != null) { + dosView.setHidden(true); + } else { + Files.setAttribute(installedPath, "dos:hidden", true); + } } catch (Exception ignored) {} } }