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

Adds ability to listen to cancelled events #6207

Merged
merged 18 commits into from
Apr 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 1 addition & 3 deletions src/main/java/ch/njol/skript/SkriptEventHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,6 @@ private static void check(Event event, EventPriority priority) {
if (triggers.isEmpty())
return;



// Check if this event should be treated as cancelled
boolean isCancelled = isCancelled(event);

Expand All @@ -133,7 +131,7 @@ private static void check(Event event, EventPriority priority) {
continue;

// check if the cancel state of the event is correct
if (triggerEvent.isListeningBehaviorSupported() && !triggerEvent.matchesListeningBehavior(isCancelled))
if (!triggerEvent.getListeningBehavior().matches(isCancelled))
continue;

// these methods need to be run on whatever thread the trigger is
Expand Down
60 changes: 0 additions & 60 deletions src/main/java/ch/njol/skript/events/EvtResurrect.java

This file was deleted.

12 changes: 12 additions & 0 deletions src/main/java/ch/njol/skript/events/SimpleEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package ch.njol.skript.events;

import ch.njol.skript.Skript;
import ch.njol.skript.lang.SkriptEvent.ListeningBehavior;
import ch.njol.skript.lang.util.SimpleEvent;
import com.destroystokyo.paper.event.block.AnvilDamagedEvent;
import com.destroystokyo.paper.event.entity.EntityJumpEvent;
Expand Down Expand Up @@ -52,6 +53,7 @@
import org.bukkit.event.entity.EntityPortalEnterEvent;
import org.bukkit.event.entity.EntityPortalEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.EntityResurrectEvent;
import org.bukkit.event.entity.EntityTameEvent;
import org.bukkit.event.entity.EntityToggleGlideEvent;
import org.bukkit.event.entity.EntityToggleSwimEvent;
Expand Down Expand Up @@ -469,6 +471,16 @@ public class SimpleEvents {
.description("Called when a slime splits. Usually this happens when a big slime dies.")
.examples("on slime split:")
.since("2.2-dev26");
Skript.registerEvent("Resurrect Attempt", SimpleEvent.class, EntityResurrectEvent.class, "[entity] resurrect[ion] [attempt]")
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
.description("Called when an entity dies, always. If they are not holding a totem, this is cancelled - you can, however, uncancel it.")
.examples(
"on resurrect attempt:",
"\tentity is player",
"\tentity has permission \"admin.undying\"",
"\tuncancel the event"
)
.since("2.2-dev28")
.listeningBehavior(ListeningBehavior.ANY);
Skript.registerEvent("Player World Change", SimpleEvent.class, PlayerChangedWorldEvent.class, "[player] world chang(ing|e[d])")
.description("Called when a player enters a world. Does not work with other entities!")
.examples("on player world change:",
Expand Down
36 changes: 23 additions & 13 deletions src/main/java/ch/njol/skript/lang/SkriptEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,11 @@ public boolean isEventPrioritySupported() {
}

/**
* @return the {@link ListeningBehavior} to be used for this event. If not set, the {@link ListeningBehavior#UNCANCELLED} is used.
* @return the {@link ListeningBehavior} to be used for this event. Defaults to the default listening behavior
* of the SkriptEventInfo for this SkriptEvent.
*/
public ListeningBehavior getListeningBehavior() {
return listeningBehavior != null ? listeningBehavior : ListeningBehavior.UNCANCELLED;
return listeningBehavior != null ? listeningBehavior : skriptEventInfo.getListeningBehavior();
}

/**
Expand All @@ -241,16 +242,6 @@ public boolean isListeningBehaviorSupported() {
return supportsListeningBehavior;
}

/**
* @return whether this SkriptEvent should be run for the given cancelled state.
*/
public boolean matchesListeningBehavior(boolean isCancelled) {
ListeningBehavior listeningBehavior = getListeningBehavior();
return listeningBehavior == ListeningBehavior.ANY
|| (listeningBehavior == ListeningBehavior.UNCANCELLED && !isCancelled)
|| (listeningBehavior == ListeningBehavior.CANCELLED && isCancelled);
}

/**
* Override this method to allow Skript to not force synchronization.
*/
Expand Down Expand Up @@ -308,7 +299,26 @@ public enum ListeningBehavior {
/**
* This Skript event should be run for any event, cancelled or uncancelled.
*/
ANY
ANY;

/**
* Checks whether this listening behavior matches the given cancelled state.
* @param cancelled Whether the event is cancelled.
* @return Whether an event with the given cancelled state should be run for this listening behavior.
*/
public boolean matches(final boolean cancelled) {
switch (this) {
case CANCELLED:
return cancelled;
case UNCANCELLED:
return !cancelled;
case ANY:
return true;
default:
assert false;
return false;
}
}
}

}
68 changes: 44 additions & 24 deletions src/main/java/ch/njol/skript/lang/SkriptEventInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@
*/
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.lang.SkriptEvent.ListeningBehavior;

import ch.njol.skript.SkriptAPIException;
import java.util.Locale;

public final class SkriptEventInfo<E extends SkriptEvent> extends StructureInfo<E> {

public Class<? extends Event>[] events;
public final String name;

private final String id;

private ListeningBehavior listeningBehavior;

@Nullable
private String[] description;
Expand All @@ -49,16 +51,16 @@ public final class SkriptEventInfo<E extends SkriptEvent> extends StructureInfo<

/**
* @param name Capitalised name of the event without leading "On" which is added automatically (Start the name with an asterisk to prevent this).
* @param patterns
* @param c The SkriptEvent's class
* @param patterns the skript patterns for this event
* @param skriptEventClass The SkriptEvent's class
* @param originClassPath The class path for the origin of this event.
* @param events The Bukkit-Events this SkriptEvent listens to
*/
public SkriptEventInfo(String name, final String[] patterns, final Class<E> c, final String originClassPath, final Class<? extends Event>[] events) {
super(patterns, c, originClassPath);
public SkriptEventInfo(String name, String[] patterns, Class<E> skriptEventClass, String originClassPath, final Class<? extends Event>[] events) {
super(patterns, skriptEventClass, originClassPath);
assert name != null;
assert patterns != null && patterns.length > 0;
assert c != null;
assert skriptEventClass != null;
assert originClassPath != null;
assert events != null && events.length > 0;

Expand All @@ -69,7 +71,7 @@ public SkriptEventInfo(String name, final String[] patterns, final Class<E> c, f
|| events[j].equals(PlayerInteractAtEntityEvent.class))
continue; // Spigot seems to have an exception for those two events...

throw new SkriptAPIException("The event " + name + " (" + c.getName() + ") registers with super/subclasses " + events[i].getName() + " and " + events[j].getName());
throw new SkriptAPIException("The event " + name + " (" + skriptEventClass.getName() + ") registers with super/subclasses " + events[i].getName() + " and " + events[j].getName());
}
}
}
Expand All @@ -84,8 +86,22 @@ public SkriptEventInfo(String name, final String[] patterns, final Class<E> c, f

// uses the name without 'on ' or '*'
this.id = "" + name.toLowerCase(Locale.ENGLISH).replaceAll("[#'\"<>/&]", "").replaceAll("\\s+", "_");

// default listening behavior should be to listen to uncancelled events
this.listeningBehavior = ListeningBehavior.UNCANCELLED;
}


/**
* Sets the default listening behavior for this SkriptEvent. If omitted, the default behavior is to listen to uncancelled events.
*
* @param listeningBehavior The listening behavior of this SkriptEvent.
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> listeningBehavior(ListeningBehavior listeningBehavior) {
this.listeningBehavior = listeningBehavior;
return this;
}

/**
* Use this as {@link #description(String...)} to prevent warnings about missing documentation.
*/
Expand All @@ -94,10 +110,10 @@ public SkriptEventInfo(String name, final String[] patterns, final Class<E> c, f
/**
* Only used for Skript's documentation.
*
* @param description
* @param description The description of this SkriptEvent for Skript's documentation.
sovdeeth marked this conversation as resolved.
Show resolved Hide resolved
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> description(final String... description) {
public SkriptEventInfo<E> description(String... description) {
assert this.description == null;
this.description = description;
return this;
Expand All @@ -106,10 +122,10 @@ public SkriptEventInfo<E> description(final String... description) {
/**
* Only used for Skript's documentation.
*
* @param examples
* @param examples The examples of this SkriptEvent for Skript's documentation.
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> examples(final String... examples) {
public SkriptEventInfo<E> examples(String... examples) {
assert this.examples == null;
this.examples = examples;
return this;
Expand All @@ -118,10 +134,10 @@ public SkriptEventInfo<E> examples(final String... examples) {
/**
* Only used for Skript's documentation.
*
* @param keywords
* @param keywords The keywords of this SkriptEvent for searching in Skript's documentation.
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> keywords(final String... keywords) {
public SkriptEventInfo<E> keywords(String... keywords) {
assert this.keywords == null;
this.keywords = keywords;
return this;
Expand All @@ -130,10 +146,10 @@ public SkriptEventInfo<E> keywords(final String... keywords) {
/**
* Only used for Skript's documentation.
*
* @param since
* @param since The version of Skript this SkriptEvent was added.
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> since(final String since) {
public SkriptEventInfo<E> since(String since) {
assert this.since == null;
this.since = since;
return this;
Expand All @@ -144,10 +160,10 @@ public SkriptEventInfo<E> since(final String since) {
*
* Only used for Skript's documentation.
*
* @param id
* @param id The ID to use for this SkriptEvent within documentation.
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> documentationID(final String id) {
public SkriptEventInfo<E> documentationID(String id) {
assert this.documentationID == null;
this.documentationID = id;
return this;
Expand All @@ -158,23 +174,27 @@ public SkriptEventInfo<E> documentationID(final String id) {
*
* Only used for Skript's documentation.
*
* @param pluginNames
* @param pluginNames The names of the plugins this SkriptEvent depends on.
* @return This SkriptEventInfo object
*/
public SkriptEventInfo<E> requiredPlugins(final String... pluginNames) {
public SkriptEventInfo<E> requiredPlugins(String... pluginNames) {
assert this.requiredPlugins == null;
this.requiredPlugins = pluginNames;
return this;
}


public String getId() {
return id;
}

public String getName() {
return name;
}

public ListeningBehavior getListeningBehavior() {
return listeningBehavior;
}

@Nullable
public String[] getDescription() {
Expand Down