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

Supported events #7281

Open
wants to merge 13 commits into
base: dev/feature
Choose a base branch
from
16 changes: 10 additions & 6 deletions src/main/java/ch/njol/skript/expressions/ExprArgument.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.List;
import java.util.regex.MatchResult;

import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
Expand Down Expand Up @@ -43,7 +45,7 @@
"heal the last argument"
})
@Since("1.0, 2.7 (support for command events)")
public class ExprArgument extends SimpleExpression<Object> {
public class ExprArgument extends SimpleExpression<Object> implements EventRestrictedSyntax {

static {
Skript.registerExpression(ExprArgument.class, Object.class, ExpressionType.SIMPLE,
Expand All @@ -68,10 +70,6 @@ public class ExprArgument extends SimpleExpression<Object> {
@SuppressWarnings("unchecked")
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
boolean scriptCommand = getParser().isCurrentEvent(ScriptCommandEvent.class);
if (!scriptCommand && !getParser().isCurrentEvent(PlayerCommandPreprocessEvent.class, ServerCommandEvent.class)) {
Skript.error("The 'argument' expression can only be used in a script command or command event");
return false;
}

switch (matchedPattern) {
case 0:
Expand Down Expand Up @@ -192,7 +190,13 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye

return true;
}


@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(ScriptCommandEvent.class, PlayerCommandPreprocessEvent.class,
ServerCommandEvent.class);
}

@Override
@Nullable
protected Object[] get(final Event e) {
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/ch/njol/skript/expressions/ExprAttacked.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.lang.reflect.Array;

import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import org.bukkit.event.entity.EntityDamageEvent;
Expand Down Expand Up @@ -36,7 +38,7 @@
"\tdamage the attacked by 1 heart"})
@Since("1.3, 2.6.1 (projectile hit event)")
@Events({"damage", "death", "projectile hit"})
public class ExprAttacked extends SimpleExpression<Entity> {
public class ExprAttacked extends SimpleExpression<Entity> implements EventRestrictedSyntax {

private static final boolean SUPPORT_PROJECTILE_HIT = Skript.methodExists(ProjectileHitEvent.class, "getHitEntity");

Expand All @@ -49,11 +51,6 @@ public class ExprAttacked extends SimpleExpression<Entity> {

@Override
public boolean init(Expression<?>[] vars, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
if (!getParser().isCurrentEvent(EntityDamageEvent.class, EntityDeathEvent.class, VehicleDamageEvent.class, VehicleDestroyEvent.class, ProjectileHitEvent.class)
|| !SUPPORT_PROJECTILE_HIT && getParser().isCurrentEvent(ProjectileHitEvent.class)) {
Skript.error("The expression 'victim' can only be used in a damage" + (SUPPORT_PROJECTILE_HIT ? ", death, or projectile hit" : " or death") + " event");
return false;
}
String type = parser.regexes.size() == 0 ? null : parser.regexes.get(0).group();
if (type == null) {
this.type = EntityData.fromClass(Entity.class);
Expand All @@ -68,6 +65,12 @@ public boolean init(Expression<?>[] vars, int matchedPattern, Kleenean isDelayed
return true;
}

@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(EntityDamageEvent.class, EntityDeathEvent.class,
VehicleDamageEvent.class, VehicleDestroyEvent.class, ProjectileHitEvent.class);
}

@Override
@Nullable
protected Entity[] get(Event e) {
Expand Down
16 changes: 10 additions & 6 deletions src/main/java/ch/njol/skript/expressions/ExprAttacker.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package ch.njol.skript.expressions;

import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Event;
Expand Down Expand Up @@ -36,21 +38,23 @@
" damage victim by 1 heart"})
@Since("1.3")
@Events({"damage", "death", "destroy"})
public class ExprAttacker extends SimpleExpression<Entity> {
public class ExprAttacker extends SimpleExpression<Entity> implements EventRestrictedSyntax {

static {
Skript.registerExpression(ExprAttacker.class, Entity.class, ExpressionType.SIMPLE, "[the] (attacker|damager)");
}

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parser) {
if (!getParser().isCurrentEvent(EntityDamageEvent.class, EntityDeathEvent.class, VehicleDamageEvent.class, VehicleDestroyEvent.class)) {
Skript.error("Cannot use 'attacker' outside of a damage/death/destroy event", ErrorQuality.SEMANTIC_ERROR);
return false;
}
return true;
}


@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(EntityDamageEvent.class, EntityDeathEvent.class,
VehicleDamageEvent.class, VehicleDestroyEvent.class);
}

@Override
protected Entity[] get(Event e) {
return new Entity[] {getAttacker(e)};
Expand Down
15 changes: 9 additions & 6 deletions src/main/java/ch/njol/skript/expressions/ExprCommand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package ch.njol.skript.expressions;

import ch.njol.skript.command.ScriptCommandEvent;
import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.event.Event;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
Expand Down Expand Up @@ -31,7 +33,7 @@
"\t\t\tcancel the event"})
@Since("2.0, 2.7 (support for script commands)")
@Events("command")
public class ExprCommand extends SimpleExpression<String> {
public class ExprCommand extends SimpleExpression<String> implements EventRestrictedSyntax {

static {
Skript.registerExpression(ExprCommand.class, String.class, ExpressionType.SIMPLE,
Expand All @@ -44,13 +46,14 @@ public class ExprCommand extends SimpleExpression<String> {

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(PlayerCommandPreprocessEvent.class, ServerCommandEvent.class, ScriptCommandEvent.class)) {
Skript.error("The 'command' expression can only be used in a script command or command event");
return false;
}
fullCommand = matchedPattern == 0;
return true;
}

@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(PlayerCommandPreprocessEvent.class, ServerCommandEvent.class, ScriptCommandEvent.class);
}

@Override
@Nullable
Expand Down Expand Up @@ -88,5 +91,5 @@ public Class<? extends String> getReturnType() {
public String toString(@Nullable Event e, boolean debug) {
return fullCommand ? "the full command" : "the command";
}

}
12 changes: 7 additions & 5 deletions src/main/java/ch/njol/skript/expressions/ExprDrops.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser.ParseResult;
Expand Down Expand Up @@ -38,7 +39,7 @@
"remove 4 planks from the drops"})
@Since("1.0")
@Events("death")
public class ExprDrops extends SimpleExpression<ItemType> {
public class ExprDrops extends SimpleExpression<ItemType> implements EventRestrictedSyntax {

static {
Skript.registerExpression(ExprDrops.class, ItemType.class, ExpressionType.SIMPLE, "[the] drops");
Expand All @@ -48,15 +49,16 @@ public class ExprDrops extends SimpleExpression<ItemType> {

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(EntityDeathEvent.class, BlockDropItemEvent.class)) {
Skript.error("The expression 'drops' can only be used in death events and block drop events");
return false;
}
if (getParser().isCurrentEvent(EntityDeathEvent.class))
isDeathEvent = true;
return true;
}

@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(EntityDeathEvent.class, BlockDropItemEvent.class);
}

@Override
protected ItemType @Nullable [] get(Event event) {
if (event instanceof EntityDeathEvent entityDeathEvent) {
Expand Down
16 changes: 9 additions & 7 deletions src/main/java/ch/njol/skript/expressions/ExprExplodedBlocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;

import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
Expand Down Expand Up @@ -43,21 +44,22 @@
"\tadd blocks above event-entity to exploded blocks"})
@Events("explode")
@Since("2.5, 2.8.6 (modify blocks)")
public class ExprExplodedBlocks extends SimpleExpression<Block> {
public class ExprExplodedBlocks extends SimpleExpression<Block> implements EventRestrictedSyntax {

static {
Skript.registerExpression(ExprExplodedBlocks.class, Block.class, ExpressionType.COMBINED, "[the] exploded blocks");
}

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) {
if (!getParser().isCurrentEvent(EntityExplodeEvent.class)) {
Skript.error("Exploded blocks can only be retrieved from an explode event.");
return false;
}
return true;
}


@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(EntityExplodeEvent.class);
}

@Nullable
@Override
protected Block[] get(Event e) {
Expand Down
15 changes: 8 additions & 7 deletions src/main/java/ch/njol/skript/expressions/ExprPushedBlocks.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ch.njol.skript.expressions;

import ch.njol.skript.lang.EventRestrictedSyntax;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.block.Block;
import org.bukkit.event.Event;
Expand All @@ -23,22 +24,22 @@
@Description("Blocks which are moved in a piston event. Cannot be used outside of piston events.")
@Examples("the moved blocks")
@Since("2.2-dev27")
public class ExprPushedBlocks extends SimpleExpression<Block> {
public class ExprPushedBlocks extends SimpleExpression<Block> implements EventRestrictedSyntax {

static {
Skript.registerExpression(ExprPushedBlocks.class, Block.class, ExpressionType.SIMPLE, "[the] moved blocks");
}

@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!getParser().isCurrentEvent(BlockPistonExtendEvent.class, BlockPistonRetractEvent.class)) {
Skript.error("The moved blocks are only usable in piston extend and retract events", ErrorQuality.SEMANTIC_ERROR);
return false;
}

return true;
}


@Override
public Class<? extends Event>[] supportedEvents() {
return CollectionUtils.array(BlockPistonExtendEvent.class, BlockPistonRetractEvent.class);
}

@Override
@Nullable
protected Block[] get(Event e) {
Expand Down
25 changes: 25 additions & 0 deletions src/main/java/ch/njol/skript/lang/EventRestrictedSyntax.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.njol.skript.lang;

import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.event.Event;

/**
* A syntax element that restricts the events it can be used in.
*/
public interface EventRestrictedSyntax {

/**
* Returns all supported events for this syntax element.
* <p>
* Before {@link SyntaxElement#init(Expression[], int, Kleenean, SkriptParser.ParseResult)} is called, checks
* to see if the current event is supported by this syntax element.
* If it is not, an error will be printed and the syntax element will not be initialised.
* </p>
*
* @return All supported event classes.
* @see CollectionUtils#array(Object[])
*/
Class<? extends Event>[] supportedEvents();

}
30 changes: 22 additions & 8 deletions src/main/java/ch/njol/skript/lang/SkriptParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,14 @@
import ch.njol.util.StringUtils;
import ch.njol.util.coll.CollectionUtils;
import com.google.common.primitives.Booleans;
import org.bukkit.event.Event;
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.script.Script;
import org.skriptlang.skript.lang.script.ScriptWarning;

import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
Expand Down Expand Up @@ -225,7 +220,26 @@ public boolean hasTag(String tag) {
}
}
T element = info.getElementClass().newInstance();
if (element.init(parseResult.exprs, patternIndex, getParser().getHasDelayBefore(), parseResult)) {

if (element instanceof EventRestrictedSyntax eventRestrictedSyntax) {
Class<? extends Event>[] supportedEvents = eventRestrictedSyntax.supportedEvents();
if (!getParser().isCurrentEvent(supportedEvents)) {
Iterator<String> iterator = Arrays.stream(supportedEvents)
.map(it -> "the " + it.getSimpleName()
.replaceAll("([A-Z])", " $1")
.toLowerCase()
.trim())
.iterator();

String events = StringUtils.join(iterator, ", ", " or ");

Skript.error("'" + parseResult.expr + "' can only be used in " + events);
continue;
}
}

boolean success = element.init(parseResult.exprs, patternIndex, getParser().getHasDelayBefore(), parseResult);
if (success) {
log.printLog();
return element;
}
Expand Down
5 changes: 5 additions & 0 deletions src/test/skript/tests/misc/supported events.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
test "supported events":
parse:
set {_x} to the exploded blocks

assert last parse logs contain "'the exploded blocks' can only be used in the entity explode event" with "supported events message did not get sent correctly"
Loading