Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
import ch.njol.skript.command.Commands;
import ch.njol.skript.doc.Documentation;
import ch.njol.skript.events.EvtSkript;
import ch.njol.skript.examples.BukkitExampleScripts;
import ch.njol.skript.examples.CoreExampleScripts;
import ch.njol.skript.examples.ExampleScriptManager;
import ch.njol.skript.expressions.arithmetic.ExprArithmetic;
import ch.njol.skript.hooks.Hook;
import ch.njol.skript.lang.*;
Expand Down Expand Up @@ -163,6 +166,12 @@ public final class Skript extends JavaPlugin implements Listener {
private static boolean disabled = false;
private static boolean partDisabled = false;

static @Nullable ExampleScriptManager exampleManager;

public static @Nullable ExampleScriptManager getExampleManager() {
return exampleManager;
}

public static Skript getInstance() {
if (instance == null)
throw new IllegalStateException();
Expand Down Expand Up @@ -398,11 +407,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;
Expand All @@ -422,15 +429,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")) {
Expand All @@ -454,7 +455,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 {
Expand All @@ -466,6 +467,10 @@ public void onEnable() {
}
}

exampleManager = new ExampleScriptManager();
exampleManager.installExamples("Skript (core)", CoreExampleScripts.provider(), scriptsFolder);
exampleManager.installExamples("Skript (Bukkit)", BukkitExampleScripts.provider(), scriptsFolder);

// initialize the modern Skript instance
skript = org.skriptlang.skript.Skript.of(getClass(), getName());
unmodifiableSkript = new ModernSkriptBridge.SpecialUnmodifiableSkript(skript);
Expand Down
60 changes: 49 additions & 11 deletions src/main/java/ch/njol/skript/SkriptAddon.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
package ch.njol.skript;

import java.io.File;
import java.io.IOException;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;

import ch.njol.skript.examples.ExampleScript;
import ch.njol.skript.examples.ExampleScriptManager;
import ch.njol.skript.examples.ExampleScriptProvider;
import ch.njol.skript.util.Utils;
import ch.njol.skript.util.Version;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.localization.Localizer;
import org.skriptlang.skript.registration.SyntaxRegistry;
import org.skriptlang.skript.util.Registry;

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;

/**
* Utility class for Skript addons. Use {@link Skript#registerAddon(JavaPlugin)} to create a SkriptAddon instance for your plugin.
*/
Expand Down Expand Up @@ -93,6 +94,43 @@ 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 {
ExampleScriptManager manager = Skript.getExampleManager();
if (manager == null)
throw new IllegalStateException("Example script manager is not initialized");

manager.installExamples(
plugin.getName(),
Arrays.asList(scripts),
Skript.getInstance().getScriptsFolder()
);
}

/**
* Registers example scripts with Skript for this addon using a provider.
*
* @param provider Provider that supplies example scripts to install
* @throws IOException If an I/O error occurs while installing the scripts
*/
public void registerExampleScripts(ExampleScriptProvider provider) throws IOException {
ExampleScriptManager manager = Skript.getExampleManager();
if (manager == null)
throw new IllegalStateException("Example script manager is not initialized");

manager.installExamples(
plugin.getName(),
provider,
Skript.getInstance().getScriptsFolder()
);
}


@Nullable
private File file;

Expand Down
45 changes: 45 additions & 0 deletions src/main/java/ch/njol/skript/examples/BukkitExampleScripts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package ch.njol.skript.examples;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;

/**
* Example scripts that rely on Bukkit-specific behaviours or APIs.
*/
public final class BukkitExampleScripts {

public static final List<ExampleScript> EXAMPLES = List.of(
load("chest menus.sk"),
load("commands.sk"),
load("events.sk"),
load("timings.sk")
);

private static final ExampleScriptProvider PROVIDER = () -> EXAMPLES;

private BukkitExampleScripts() {}

public static Collection<ExampleScript> all() {
return EXAMPLES;
}

public static ExampleScriptProvider provider() {
return PROVIDER;
}

private static ExampleScript load(String name) {
String path = "scripts/-examples/" + name;
try (InputStream in = BukkitExampleScripts.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);
}
}

}
46 changes: 46 additions & 0 deletions src/main/java/ch/njol/skript/examples/CoreExampleScripts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ch.njol.skript.examples;

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 {

public static final List<ExampleScript> EXAMPLES = List.of(
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("variables.sk")
);

private static final ExampleScriptProvider PROVIDER = () -> EXAMPLES;

private CoreExampleScripts() {}

public static Collection<ExampleScript> all() {
return EXAMPLES;
}

public static ExampleScriptProvider provider() {
return PROVIDER;
}

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);
}
}

Comment on lines +34 to +45
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some duplicate code here, can we de duplicate it?

}
31 changes: 31 additions & 0 deletions src/main/java/ch/njol/skript/examples/ExampleScript.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package ch.njol.skript.examples;

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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this could be an interface where all the example scripts are registered? this can then be extended by addons and registered with SkriptAddon

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added in an ExampleScriptProvider interface, is that sort of what you were thinking with this?


/**
* 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);
}
}
}
Loading