From a18874b1906112b0c67ef724160cde9e6e7aa882 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Tue, 8 Aug 2023 19:27:30 -0700 Subject: [PATCH 1/4] Adds ability to listen to cancelled events Also cleans up SkriptEventHandler#check() a bit more. --- src/main/java/ch/njol/skript/Skript.java | 2 +- .../ch/njol/skript/SkriptEventHandler.java | 42 +++++++++---------- .../java/ch/njol/skript/lang/SkriptEvent.java | 14 ++++++- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index dab73c2b5a6..83b2325094e 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -1471,7 +1471,7 @@ public static SkriptEventInfo registerEvent(String na String[] transformedPatterns = new String[patterns.length]; for (int i = 0; i < patterns.length; i++) - transformedPatterns[i] = "[on] " + SkriptEvent.fixPattern(patterns[i]) + SkriptEventInfo.EVENT_PRIORITY_SYNTAX; + transformedPatterns[i] = "[on] [all] " + SkriptEvent.fixPattern(patterns[i]) + SkriptEventInfo.EVENT_PRIORITY_SYNTAX; SkriptEventInfo r = new SkriptEventInfo<>(name, transformedPatterns, c, originClassPath, events); structures.add(r); diff --git a/src/main/java/ch/njol/skript/SkriptEventHandler.java b/src/main/java/ch/njol/skript/SkriptEventHandler.java index 144eca18721..1620e9d3fff 100644 --- a/src/main/java/ch/njol/skript/SkriptEventHandler.java +++ b/src/main/java/ch/njol/skript/SkriptEventHandler.java @@ -109,35 +109,33 @@ private static List getTriggers(Class event) { * @param priority The priority of the Event. */ private static void check(Event event, EventPriority priority) { + // Get all triggers for this event, return if there are none List triggers = getTriggers(event.getClass()); + if (triggers.isEmpty()) + return; - if (Skript.logVeryHigh()) { - boolean hasTrigger = false; - for (Trigger trigger : triggers) { - SkriptEvent triggerEvent = trigger.getEvent(); - if (triggerEvent.getEventPriority() == priority && triggerEvent.check(event)) { - hasTrigger = true; - break; - } - } - if (!hasTrigger) - return; + // This handles cancelled left/right clicks on air. Left/right clicks on air are called as cancelled, making isCancelled() unreliable. + // Checking useItemInHand() is a reliable method, as it will be DENY if the event was specifically cancelled. + // Note that right clicks on air with nothing in hand aren't ever sent to the server. + boolean isResultDeny = !(event instanceof PlayerInteractEvent && + (((PlayerInteractEvent) event).getAction() == Action.LEFT_CLICK_AIR || ((PlayerInteractEvent) event).getAction() == Action.RIGHT_CLICK_AIR) && + ((PlayerInteractEvent) event).useItemInHand() != Result.DENY); - logEventStart(event); - } - - boolean isCancelled = event instanceof Cancellable && ((Cancellable) event).isCancelled() && !listenCancelled.contains(event.getClass()); - boolean isResultDeny = !(event instanceof PlayerInteractEvent && (((PlayerInteractEvent) event).getAction() == Action.LEFT_CLICK_AIR || ((PlayerInteractEvent) event).getAction() == Action.RIGHT_CLICK_AIR) && ((PlayerInteractEvent) event).useItemInHand() != Result.DENY); + // Check if this event should be treated as cancelled + boolean isCancelled = event instanceof Cancellable && + (((Cancellable) event).isCancelled() && isResultDeny) && + !listenCancelled.contains(event.getClass()); - if (isCancelled && isResultDeny) { - if (Skript.logVeryHigh()) - Skript.info(" -x- was cancelled"); - return; - } + // This now logs events even if there isn't a trigger that's going to run at that priority. + // However, there should only be a priority listener IF there's a trigger at that priority. + // So the only change is that the time will be logged even if no triggers pass check(), + // which is still useful information. + logEventStart(event); for (Trigger trigger : triggers) { SkriptEvent triggerEvent = trigger.getEvent(); - if (triggerEvent.getEventPriority() != priority || !triggerEvent.check(event)) + // Check if the trigger should be executed (matches priority, should be called if cancelled, and passes event.check()) + if (triggerEvent.getEventPriority() != priority || (isCancelled && triggerEvent.shouldIgnoreCancelled()) || !triggerEvent.check(event)) continue; logTriggerStart(trigger); diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index e150e8699d8..f66f023c37a 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -56,6 +56,7 @@ public abstract class SkriptEvent extends Structure { @Nullable protected EventPriority eventPriority; private SkriptEventInfo skriptEventInfo; + protected boolean ignoreCancelled = true; /** * The Trigger containing this SkriptEvent's code. @@ -65,8 +66,12 @@ public abstract class SkriptEvent extends Structure { @Override public final boolean init(Literal[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) { String expr = parseResult.expr; - if (StringUtils.startsWithIgnoreCase(expr, "on ")) + if (StringUtils.startsWithIgnoreCase(expr, "on all ")) { + expr = expr.substring("on all ".length()); + ignoreCancelled = false; + } else if (StringUtils.startsWithIgnoreCase(expr, "on ")) { expr = expr.substring("on ".length()); + } String[] split = expr.split(" with priority "); if (split.length != 1) { @@ -216,6 +221,13 @@ public boolean isEventPrioritySupported() { return true; } + /** + * @return whether this SkriptEvent will ignore cancelled events + */ + public boolean shouldIgnoreCancelled() { + return ignoreCancelled; + } + /** * Fixes patterns in event by modifying every {@link ch.njol.skript.patterns.TypePatternElement} * to be nullable. From 2dadc958378df32af311113a68d25c00da65b08b Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Tue, 8 Aug 2023 23:34:27 -0700 Subject: [PATCH 2/4] switch to regex for parsing event expr --- .../java/ch/njol/skript/lang/SkriptEvent.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index f66f023c37a..b72fd633384 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -25,17 +25,18 @@ import ch.njol.skript.config.SectionNode; import ch.njol.skript.events.EvtClick; import ch.njol.skript.lang.SkriptParser.ParseResult; -import org.skriptlang.skript.lang.script.Script; -import org.skriptlang.skript.lang.entry.EntryContainer; -import org.skriptlang.skript.lang.structure.Structure; -import ch.njol.util.StringUtils; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; import org.eclipse.jdt.annotation.Nullable; +import org.skriptlang.skript.lang.entry.EntryContainer; +import org.skriptlang.skript.lang.script.Script; +import org.skriptlang.skript.lang.structure.Structure; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A SkriptEvent is like a condition. It is called when any of the registered events occurs. @@ -51,6 +52,7 @@ public abstract class SkriptEvent extends Structure { public static final Priority PRIORITY = new Priority(600); + private static final Pattern EVENT_PATTERN = Pattern.compile("(?:on\\s+)?(all\\s+)?(.+)", Pattern.CASE_INSENSITIVE); private String expr; @Nullable @@ -66,12 +68,14 @@ public abstract class SkriptEvent extends Structure { @Override public final boolean init(Literal[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) { String expr = parseResult.expr; - if (StringUtils.startsWithIgnoreCase(expr, "on all ")) { - expr = expr.substring("on all ".length()); + Matcher matcher = EVENT_PATTERN.matcher(expr); + if (!matcher.matches()) + return false; + + if (matcher.group(1) != null) { ignoreCancelled = false; - } else if (StringUtils.startsWithIgnoreCase(expr, "on ")) { - expr = expr.substring("on ".length()); } + expr = matcher.group(2); String[] split = expr.split(" with priority "); if (split.length != 1) { From 3652fcb51e8709acd4457e735b366395d2440736 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Wed, 9 Aug 2023 09:50:21 -0700 Subject: [PATCH 3/4] actually regex is overrated --- src/main/java/ch/njol/skript/Skript.java | 2 +- .../java/ch/njol/skript/lang/SkriptEvent.java | 38 ++++++------------- .../ch/njol/skript/lang/SkriptEventInfo.java | 9 ++--- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index be0501b0bac..6536a6f63ba 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -1470,7 +1470,7 @@ public static SkriptEventInfo registerEvent(String na String[] transformedPatterns = new String[patterns.length]; for (int i = 0; i < patterns.length; i++) - transformedPatterns[i] = "[on] [all] " + SkriptEvent.fixPattern(patterns[i]) + SkriptEventInfo.EVENT_PRIORITY_SYNTAX; + transformedPatterns[i] = "[on] [:all] " + SkriptEvent.fixPattern(patterns[i]) + SkriptEventInfo.EVENT_PRIORITY_SYNTAX; SkriptEventInfo r = new SkriptEventInfo<>(name, transformedPatterns, c, originClassPath, events); structures.add(r); diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index b72fd633384..4da1ed927f4 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -25,6 +25,7 @@ import ch.njol.skript.config.SectionNode; import ch.njol.skript.events.EvtClick; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.StringUtils; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; import org.eclipse.jdt.annotation.Nullable; @@ -32,11 +33,8 @@ import org.skriptlang.skript.lang.script.Script; import org.skriptlang.skript.lang.structure.Structure; -import java.util.Arrays; import java.util.List; import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * A SkriptEvent is like a condition. It is called when any of the registered events occurs. @@ -52,7 +50,6 @@ public abstract class SkriptEvent extends Structure { public static final Priority PRIORITY = new Priority(600); - private static final Pattern EVENT_PATTERN = Pattern.compile("(?:on\\s+)?(all\\s+)?(.+)", Pattern.CASE_INSENSITIVE); private String expr; @Nullable @@ -67,37 +64,26 @@ public abstract class SkriptEvent extends Structure { @Override public final boolean init(Literal[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) { - String expr = parseResult.expr; - Matcher matcher = EVENT_PATTERN.matcher(expr); - if (!matcher.matches()) - return false; - - if (matcher.group(1) != null) { - ignoreCancelled = false; - } - expr = matcher.group(2); + int priority = parseResult.mark; + ignoreCancelled = !parseResult.hasTag("all"); - String[] split = expr.split(" with priority "); - if (split.length != 1) { + eventPriority = null; + if (priority > 0) { if (!isEventPrioritySupported()) { Skript.error("This event doesn't support event priority"); return false; } + // parse marks go from 1 to 6, event priorities from 0 to 5 + eventPriority = EventPriority.values()[priority - 1]; + } - expr = String.join(" with priority ", Arrays.copyOfRange(split, 0, split.length - 1)); + this.expr = parseResult.expr; - String priorityString = split[split.length - 1]; - try { - eventPriority = EventPriority.valueOf(priorityString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalStateException(e); - } - } else { - eventPriority = null; + // remove "on " from the beginning of the expression for better readability in logs + if (StringUtils.startsWithIgnoreCase(expr, "on ")) { + expr = expr.substring("on ".length()); } - this.expr = parseResult.expr = expr; - SyntaxElementInfo syntaxElementInfo = getParser().getData(StructureData.class).getStructureInfo(); if (!(syntaxElementInfo instanceof SkriptEventInfo)) throw new IllegalStateException(); diff --git a/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java b/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java index 3581e655d70..b10c1cd3feb 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java @@ -18,18 +18,17 @@ */ package ch.njol.skript.lang; -import java.util.Locale; - -import org.skriptlang.skript.lang.structure.StructureInfo; +import ch.njol.skript.SkriptAPIException; import org.bukkit.event.Event; import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.eclipse.jdt.annotation.Nullable; +import org.skriptlang.skript.lang.structure.StructureInfo; -import ch.njol.skript.SkriptAPIException; +import java.util.Locale; public final class SkriptEventInfo extends StructureInfo { - public static final String EVENT_PRIORITY_SYNTAX = " [with priority (lowest|low|normal|high|highest|monitor)]"; + public static final String EVENT_PRIORITY_SYNTAX = " [with priority (1:lowest|2:low|3:normal|4:high|5:highest|6:monitor)]"; public Class[] events; public final String name; From ca13ea41b044677f4d07480a5ad64c5baf13eeb5 Mon Sep 17 00:00:00 2001 From: sovdee <10354869+sovdeeth@users.noreply.github.com> Date: Wed, 9 Aug 2023 10:44:30 -0700 Subject: [PATCH 4/4] parse marks are overrated + priority in logs --- .../java/ch/njol/skript/SkriptEventHandler.java | 15 ++++++++++++++- .../java/ch/njol/skript/lang/SkriptEvent.java | 15 ++++++++++----- .../java/ch/njol/skript/lang/SkriptEventInfo.java | 2 +- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/njol/skript/SkriptEventHandler.java b/src/main/java/ch/njol/skript/SkriptEventHandler.java index 1620e9d3fff..d6d7c258fd8 100644 --- a/src/main/java/ch/njol/skript/SkriptEventHandler.java +++ b/src/main/java/ch/njol/skript/SkriptEventHandler.java @@ -130,7 +130,7 @@ private static void check(Event event, EventPriority priority) { // However, there should only be a priority listener IF there's a trigger at that priority. // So the only change is that the time will be logged even if no triggers pass check(), // which is still useful information. - logEventStart(event); + logEventStart(event, priority); for (Trigger trigger : triggers) { SkriptEvent triggerEvent = trigger.getEvent(); @@ -165,6 +165,19 @@ public static void logEventStart(Event event) { Skript.info("== " + event.getClass().getName() + " =="); } + /** + * Logs that the provided Event has started with a priority. + * Requires {@link Skript#logVeryHigh()} to be true to log anything. + * @param event The Event that started. + */ + public static void logEventStart(Event event, EventPriority priority) { + startEvent = System.nanoTime(); + if (!Skript.logVeryHigh()) + return; + Skript.info(""); + Skript.info("== " + event.getClass().getName() + " with priority " + priority + " =="); + } + /** * Logs that the last logged Event start has ended. * Includes the number of milliseconds execution took. diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index 4da1ed927f4..80903f76ce9 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -64,17 +64,22 @@ public abstract class SkriptEvent extends Structure { @Override public final boolean init(Literal[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) { - int priority = parseResult.mark; ignoreCancelled = !parseResult.hasTag("all"); - eventPriority = null; - if (priority > 0) { + if (parseResult.hasTag("priority")) { if (!isEventPrioritySupported()) { Skript.error("This event doesn't support event priority"); return false; } - // parse marks go from 1 to 6, event priorities from 0 to 5 - eventPriority = EventPriority.values()[priority - 1]; + + try { + String priorityString = parseResult.tags.get(parseResult.tags.size() - 1); + eventPriority = EventPriority.valueOf(priorityString.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new IllegalStateException(e); + } + } else { + eventPriority = null; } this.expr = parseResult.expr; diff --git a/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java b/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java index b10c1cd3feb..771537da0c8 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java @@ -28,7 +28,7 @@ public final class SkriptEventInfo extends StructureInfo { - public static final String EVENT_PRIORITY_SYNTAX = " [with priority (1:lowest|2:low|3:normal|4:high|5:highest|6:monitor)]"; + public static final String EVENT_PRIORITY_SYNTAX = " [priority:with priority (:lowest|:low|:normal|:high|:highest|:monitor)]"; public Class[] events; public final String name;