Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration for custom events #5724

Open
wants to merge 10 commits into
base: dev/feature
Choose a base branch
from
149 changes: 149 additions & 0 deletions src/main/java/ch/njol/skript/CustomEvents.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/**
* This file is part of Skript.
*
* Skript is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Skript is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Skript. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright Peter Güttinger, SkriptLang team and contributors
*/
package ch.njol.skript;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.bukkit.event.Event;

import ch.njol.skript.config.Config;
import ch.njol.skript.config.Node;
import ch.njol.skript.config.OptionSection;
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.lang.util.SimpleEvent;
import ch.njol.skript.log.SkriptLogger;
import ch.njol.skript.util.FileUtils;

public class CustomEvents {

public static final OptionSection events = new OptionSection("events");

private static boolean loaded;

@SuppressWarnings("unchecked")
public static void load(File file) {
if (loaded)
return;
loaded = true;
File eventsFile = new File(Skript.getInstance().getDataFolder(), "custom-events.sk");
Config configuration = null;
if (eventsFile.exists()) {
try {
configuration = new Config(eventsFile, false, false, ":");
} catch (IOException e) {
Skript.exception(e, "Failed to load custom-events.sk");
}
} else {
try (ZipFile zip = new ZipFile(file)) {
File saveTo = null;
ZipEntry entry = zip.getEntry("custom-events.sk");
if (entry != null) {
File destination = new File(Skript.getInstance().getDataFolder(), entry.getName());
if (!destination.exists())
saveTo = destination;
} if (saveTo != null) {
try (InputStream in = zip.getInputStream(entry)) {
FileUtils.save(in, saveTo);
}
}
} catch (IOException e) {
if (Skript.debug())
Skript.exception(e);
} finally {
eventsFile = new File(Skript.getInstance().getDataFolder(), "custom-events.sk");
try {
configuration = new Config(eventsFile, false, false, ":");
} catch (IOException e) {
e.printStackTrace();
}
}
}

if (configuration != null) {
configuration.load(CustomEvents.class);
// When we need to change values in the future of this file, bump the version node.
String version = configuration.get("version");
if (version != null && version.isEmpty() || !version.equalsIgnoreCase("1")) {
Skript.warning("Your custom-events.sk config file is outdated. " +
"Backup any changes you've made, and delete your custom-events.sk in the Skript folder to update it. " +
"After, re-add any nodes you've changed.");
}
SectionNode section = (SectionNode) configuration.getMainNode().get("events");
if (section != null && !section.isEmpty()) {
for (Node node : section) {
if (!(node instanceof SectionNode)) {
Skript.error("Event node '" + node.getKey() + "' was not a section, ignoring.");
continue;
}
SectionNode eventSection = (SectionNode) node;
String name = node.getKey();
if (name.isEmpty()) {
Skript.error("Event node '" + node.getKey() + "' is empty/blank.");
continue;
}
String enabled = eventSection.get("enabled", "true");
if (enabled.equalsIgnoreCase("false"))
continue;
String description = eventSection.get("description", "custom event '" + name + "'");
String pattern = eventSection.getValue("pattern");
if (pattern == null) {
Skript.warning("Event node '" + name + "' did not contain a 'pattern' value.");
continue;
}
if (pattern.contains("%")) {
SkriptLogger.setNode(eventSection.get("pattern"));
Skript.warning("Event node '" + name + "' cannot contain any expressions in the pattern '" + pattern + "'");
continue;
}
String eventClass = eventSection.getValue("class");
if (eventClass == null) {
Skript.warning("Event node '" + name + "' did not contain a 'class' value.");
continue;
}

// Everything below this should be dedicated to the class node.
SkriptLogger.setNode(eventSection.get("class"));
Class<?> event;
try {
event = Class.forName(eventClass);
} catch (Exception e) {
if (Skript.logVeryHigh() || Skript.debug()) {
Skript.exception(e, "Class '" + eventClass + "' for event node '" + name + "' had an exception loading.");
} else {
Skript.error("Failed to find class '" + eventClass + "' for event node '" + name + "'");
}
continue;
}
if (!(Event.class.isAssignableFrom(event))) {
Skript.error("Class '" + eventClass + "' for event node '" + name + "' was not a valid Event class!");
continue;
}
Skript.registerEvent(name, SimpleEvent.class, (Class<? extends Event>) event, pattern)
.requiredPlugins("Custom Skript Event")
.description(description);
}
}
}
}

}
3 changes: 3 additions & 0 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,9 @@ public void onEnable() {
return;
}

// Must load after loadClasses
CustomEvents.load(getFile());

Commands.registerListeners();

if (logNormal())
Expand Down
38 changes: 38 additions & 0 deletions src/main/resources/custom-events.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

# This file allows you to register custom events that aren't already registered under Skript.
# The event classes you want to register must exist in the server class loader. So events from Paper/Spigot.
# If you want to register an event from a plugin API, you must edit the plugin.yml in the jar of Skript to include:
#
# softdepend: [YourPlugin, SQLibrary, Vault, WorldGuard, Residence, PreciousStones, GriefPrevention]
#
# Reminder to maintain any existing defined plugins in this array as this example should not be directly copied.
#! Additions or changes to this file requires a server restart.

#! Internal version of this configuration. Don't modify.
version: 1

# The format must include a section where the section name is the event name.
# The event section must include:
# description - describing the event
TheLimeGlass marked this conversation as resolved.
Show resolved Hide resolved
# class - the class name to search for
# pattern - the syntax pattern of the event
# The optional pattern [on] gets prefixed on every Skript event.
# Pattern cannot have expressions inside currently.
# event-values of subclass events will be automatically applied.
# If you need more info, make an issue report at https://github.com/SkriptLang/Skript/issues

# Examples are placed below. The 'enabled' node is not required, it's just to disable examples.
events:
# [on] beacon effect apply
beacon effect:
enabled: false
description: "Called when entities receive potion effects from a beacon"
class: com.destroystokyo.paper.event.block.BeaconEffectEvent
pattern: beacon effect apply [to player[s]]

# [on] campfire start cooking
campfire cooking:
enabled: false
description: "Called when a campfire starts cooking"
class: org.bukkit.event.block.CampfireStartEvent
pattern: campfire start[ing] cooking
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void checkFiles() {
assertTrue(skript.getScriptsFolder().isDirectory());
assertTrue(new File(dataFolder, "config.sk").exists());
assertTrue(new File(dataFolder, "features.sk").exists());
assertTrue(new File(dataFolder, "custom-events.sk").exists());
File lang = new File(dataFolder, "lang");
assertTrue(lang.exists());
assertTrue(lang.isDirectory());
Expand Down
Loading