diff --git a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java index 8f615650611..2bb5313bcd6 100644 --- a/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java +++ b/src/main/java/ch/njol/skript/classes/data/BukkitEventValues.java @@ -358,21 +358,6 @@ public PotionEffectType convert(AreaEffectCloudApplyEvent event) { .build()); // PlayerItemBreakEvent registry.register(EventValue.simple(PlayerItemBreakEvent.class, ItemStack.class, PlayerItemBreakEvent::getBrokenItem)); - // PlayerInteractEntityEvent - registry.register(EventValue.simple(PlayerInteractEntityEvent.class, Entity.class, PlayerInteractEntityEvent::getRightClicked)); - registry.register(EventValue.simple(PlayerInteractEntityEvent.class, ItemStack.class, event -> { - EquipmentSlot hand = event.getHand(); - if (hand == EquipmentSlot.HAND) - return event.getPlayer().getInventory().getItemInMainHand(); - else if (hand == EquipmentSlot.OFF_HAND) - return event.getPlayer().getInventory().getItemInOffHand(); - else - return null; - })); - // PlayerInteractEvent - registry.register(EventValue.simple(PlayerInteractEvent.class, ItemStack.class, PlayerInteractEvent::getItem)); - registry.register(EventValue.simple(PlayerInteractEvent.class, Block.class, PlayerInteractEvent::getClickedBlock)); - registry.register(EventValue.simple(PlayerInteractEvent.class, Direction.class, event -> new Direction(new double[]{event.getBlockFace().getModX(), event.getBlockFace().getModY(), event.getBlockFace().getModZ()}))); // PlayerShearEntityEvent registry.register(EventValue.simple(PlayerShearEntityEvent.class, Entity.class, PlayerShearEntityEvent::getEntity)); // PlayerMoveEvent @@ -562,26 +547,7 @@ else if (hand == EquipmentSlot.OFF_HAND) if (Skript.methodExists(PortalCreateEvent.class, "getEntity")) { // Minecraft 1.14+ registry.register(EventValue.simple(PortalCreateEvent.class, Entity.class, PortalCreateEvent::getEntity)); } - //PlayerEditBookEvent - registry.register(EventValue.builder(PlayerEditBookEvent.class, ItemStack.class) - .getter(event -> { - ItemStack book = new ItemStack(Material.WRITABLE_BOOK); - book.setItemMeta(event.getPreviousBookMeta()); - return book; - }) - .time(Time.PAST) - .build()); - registry.register(EventValue.simple(PlayerEditBookEvent.class, ItemStack.class, event -> { - ItemStack book = new ItemStack(Material.WRITABLE_BOOK); - book.setItemMeta(event.getNewBookMeta()); - return book; - })); - registry.register(EventValue.builder(PlayerEditBookEvent.class, Component[].class) - .getter(event -> ExprBookPages.getPages(event.getPreviousBookMeta()).toArray(new Component[0])) - .time(Time.PAST) - .build()); - registry.register(EventValue.simple(PlayerEditBookEvent.class, Component[].class, event -> - ExprBookPages.getPages(event.getNewBookMeta()).toArray(new Component[0]))); + //ItemDespawnEvent registry.register(EventValue.simple(ItemDespawnEvent.class, Item.class, ItemDespawnEvent::getEntity)); registry.register(EventValue.simple(ItemDespawnEvent.class, ItemStack.class, event -> event.getEntity().getItemStack())); diff --git a/src/main/java/ch/njol/skript/effects/EffCancelEvent.java b/src/main/java/ch/njol/skript/effects/EffCancelEvent.java index 10645107870..0d29a14a91a 100644 --- a/src/main/java/ch/njol/skript/effects/EffCancelEvent.java +++ b/src/main/java/ch/njol/skript/effects/EffCancelEvent.java @@ -6,7 +6,6 @@ import ch.njol.skript.doc.Example; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; -import ch.njol.skript.events.EvtClick; import ch.njol.skript.lang.Effect; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -24,6 +23,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerLoginEvent; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.entity.player.elements.events.EvtClick; @Name("Cancel Event") @Description("Cancels the event (e.g. prevent blocks from being placed, or damage being taken).") diff --git a/src/main/java/ch/njol/skript/events/EvtAttemptAttack.java b/src/main/java/ch/njol/skript/events/EvtAttemptAttack.java deleted file mode 100644 index 08a556782d9..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtAttemptAttack.java +++ /dev/null @@ -1,87 +0,0 @@ -package ch.njol.skript.events; - -import ch.njol.skript.util.StringMode; -import org.bukkit.entity.Entity; -import org.bukkit.event.Event; -import org.jetbrains.annotations.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.entity.EntityData; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.skript.lang.SyntaxStringBuilder; -import ch.njol.skript.registrations.Classes; -import io.papermc.paper.event.player.PrePlayerAttackEntityEvent; - -public class EvtAttemptAttack extends SkriptEvent { - - static { - Skript.registerEvent("Attempt Attack", EvtAttemptAttack.class, PrePlayerAttackEntityEvent.class, "attack attempt", "attempt[ing] to attack %entitydatas%") - .description(""" - Called when a player attempts to attack an entity. - The event will be cancelled as soon as it is fired for non-living entities. - Cancelling this event will prevent the attack and any sounds from being played when attacking. - Any damage events will not be called if this is cancelled. - """) - .examples(""" - on attack attempt: - if event is cancelled: - broadcast "%attacker% failed to attack %victim%!" - else: - broadcast "%attacker% damaged %victim%!" - """, - """ - on attempt to attack an animal: - cancel event - """, - """ - on attempting to attack an entity: - if victim is a creeper: - cancel event - """, - """ - on attempt to attack a zombie or creeper: - attacker isn't holding a diamond sword - cancel event - """) - .since("2.15"); - } - - private EntityData @Nullable [] types; - - @Override - public boolean init(Literal[] args, int matchedPattern, ParseResult parser) { - //noinspection unchecked - types = args.length == 0 ? null : ((Literal>) args[0]).getAll(); - return true; - } - - @Override - public boolean check(Event event) { - if (types == null) - return true; - - if (!(event instanceof PrePlayerAttackEntityEvent preEvent)) - return false; - Entity entity = preEvent.getAttacked(); - - for (final EntityData data : types) { - if (data.isInstance(entity)) - return true; - } - return false; - } - - @Override - public String toString(@Nullable Event event, boolean debug) { - SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); - if (types == null) { - builder.append("attack attempt"); - } else { - builder.append("attempting to attack", Classes.toString(types, debug ? StringMode.DEBUG : StringMode.MESSAGE)); - } - return builder.toString(); - } - -} diff --git a/src/main/java/ch/njol/skript/events/EvtBookEdit.java b/src/main/java/ch/njol/skript/events/EvtBookEdit.java deleted file mode 100644 index 17d67baa28e..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtBookEdit.java +++ /dev/null @@ -1,37 +0,0 @@ -package ch.njol.skript.events; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser; -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerEditBookEvent; -import org.jetbrains.annotations.Nullable; - -public class EvtBookEdit extends SkriptEvent{ - - static { - Skript.registerEvent("Book Edit", EvtBookEdit.class, PlayerEditBookEvent.class, "book (edit|change|write)") - .description("Called when a player edits a book.") - .examples("on book edit:") - .since("2.2-dev31"); - } - - @Override - public boolean init(Literal[] args, int matchedPattern, SkriptParser.ParseResult parseResult) { - return true; - } - - @Override - public boolean check(Event e) { - if (!(e instanceof PlayerEditBookEvent)){ - return false; - } - return !((PlayerEditBookEvent) e).isSigning(); - } - - @Override - public String toString(@Nullable Event e, boolean debug) { - return "book edit"; - } -} diff --git a/src/main/java/ch/njol/skript/events/EvtBookSign.java b/src/main/java/ch/njol/skript/events/EvtBookSign.java deleted file mode 100644 index 58c2cd61444..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtBookSign.java +++ /dev/null @@ -1,37 +0,0 @@ -package ch.njol.skript.events; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser; -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerEditBookEvent; -import org.jetbrains.annotations.Nullable; - -public class EvtBookSign extends SkriptEvent{ - - static { - Skript.registerEvent("Book Sign", EvtBookSign.class, PlayerEditBookEvent.class, "book sign[ing]") - .description("Called when a player signs a book.") - .examples("on book sign:") - .since("2.2-dev31"); - } - - @Override - public boolean init(Literal[] args, int matchedPattern, SkriptParser.ParseResult parseResult) { - return true; - } - - @Override - public boolean check(Event e) { - if (!(e instanceof PlayerEditBookEvent)){ - return false; - } - return ((PlayerEditBookEvent) e).isSigning(); - } - - @Override - public String toString(@Nullable Event e, boolean debug) { - return "book sign"; - } -} diff --git a/src/main/java/ch/njol/skript/events/EvtCommand.java b/src/main/java/ch/njol/skript/events/EvtCommand.java deleted file mode 100644 index f1bfb14592c..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtCommand.java +++ /dev/null @@ -1,74 +0,0 @@ -package ch.njol.skript.events; - -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.server.ServerCommandEvent; -import org.jetbrains.annotations.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.util.StringUtils; -import ch.njol.util.coll.CollectionUtils; - -import java.util.Arrays; - -public class EvtCommand extends SkriptEvent { // TODO condition to check whether a given command exists, & a conditon to check whether it's a custom skript command - static { - Skript.registerEvent("Command", EvtCommand.class, CollectionUtils.array(PlayerCommandPreprocessEvent.class, ServerCommandEvent.class), "command [%-strings%]") - .description("Called when a player enters a command (not necessarily a Skript command) but you can check if command is a skript command, see Is a Skript command condition.") - .examples("on command:", "on command \"/stop\":", "on command \"pm Njol \":") - .since("2.0"); - } - - private String @Nullable [] commands = null; - private Literal commandsLit; - - @Override - @SuppressWarnings("null") - public boolean init(final Literal[] args, final int matchedPattern, final ParseResult parser) { - if (args[0] != null) { - //noinspection unchecked - commandsLit = ((Literal) args[0]); - commands = commandsLit.getAll(); - for (int i = 0; i < commands.length; i++) { - if (commands[i].startsWith("/")) - commands[i] = commands[i].substring(1); - } - } - return true; - } - - @Override - @SuppressWarnings("null") - public boolean check(Event event) { - if (event instanceof ServerCommandEvent serverCommandEvent && serverCommandEvent.getCommand().isEmpty()) - return false; - - if (commands == null) - return true; - - String message; - if (event instanceof PlayerCommandPreprocessEvent playerCommandPreprocessEvent) { - assert playerCommandPreprocessEvent.getMessage().startsWith("/"); - message = playerCommandPreprocessEvent.getMessage().substring(1); - } else { - assert event instanceof ServerCommandEvent; - message = ((ServerCommandEvent) event).getCommand(); - } - - return Arrays.stream(commands).anyMatch(candidateCommand -> - StringUtils.startsWithIgnoreCase(message, candidateCommand) // matches the command label - && (candidateCommand.contains(" ") // if candidate contains arguments, then any command that starts with the candidate is a match - || message.length() == candidateCommand.length() // exact match - || Character.isWhitespace(message.charAt(candidateCommand.length()) // matches label with space after - ))); - } - - @Override - public String toString(@Nullable Event event, boolean debug) { - return "command" + (commandsLit != null ? " " + commandsLit.toString(event, debug) : ""); - } - -} diff --git a/src/main/java/ch/njol/skript/events/EvtFirstJoin.java b/src/main/java/ch/njol/skript/events/EvtFirstJoin.java deleted file mode 100644 index ef5e6e68c15..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtFirstJoin.java +++ /dev/null @@ -1,39 +0,0 @@ -package ch.njol.skript.events; - -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerJoinEvent; -import org.jetbrains.annotations.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; - -/** - * @author Peter Güttinger - */ -public class EvtFirstJoin extends SkriptEvent { - static { - Skript.registerEvent("First Join", EvtFirstJoin.class, PlayerJoinEvent.class, "first (join|login)") - .description("Called when a player joins the server for the first time.") - .examples("on first join:", - "\tbroadcast \"Welcome %player% to the server!\"") - .since("1.3.7"); - } - - @Override - public boolean init(final Literal[] args, final int matchedPattern, final ParseResult parser) { - return true; - } - - @Override - public boolean check(final Event e) { - return !((PlayerJoinEvent) e).getPlayer().hasPlayedBefore(); - } - - @Override - public String toString(final @Nullable Event e, final boolean debug) { - return "first join"; - } - -} diff --git a/src/main/java/ch/njol/skript/events/EvtLevel.java b/src/main/java/ch/njol/skript/events/EvtLevel.java deleted file mode 100644 index ac822ebec09..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtLevel.java +++ /dev/null @@ -1,46 +0,0 @@ -package ch.njol.skript.events; - -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerLevelChangeEvent; -import org.jetbrains.annotations.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import ch.njol.util.Kleenean; - -public class EvtLevel extends SkriptEvent { - - static { - Skript.registerEvent("Level Change", EvtLevel.class, PlayerLevelChangeEvent.class, "[player] level (change|1¦up|-1¦down)") - .description("Called when a player's level changes, e.g. by gathering experience or by enchanting something.") - .examples("on level change:") - .since("1.0, 2.4 (level up/down)"); - } - - @SuppressWarnings("null") - private Kleenean leveling; - - @Override - public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { - leveling = Kleenean.get(parseResult.mark); - return true; - } - - @Override - public boolean check(Event e) { - PlayerLevelChangeEvent event = (PlayerLevelChangeEvent) e; - if (leveling.isTrue()) - return event.getNewLevel() > event.getOldLevel(); - else if (leveling.isFalse()) - return event.getNewLevel() < event.getOldLevel(); - else - return true; - } - - @Override - public String toString(@Nullable Event e, boolean debug) { - return "level " + (leveling.isTrue() ? "up" : leveling.isFalse() ? "down" : "change"); - } -} diff --git a/src/main/java/ch/njol/skript/events/EvtMoveOn.java b/src/main/java/ch/njol/skript/events/EvtMoveOn.java index 49304a4da0b..a971ae492fd 100644 --- a/src/main/java/ch/njol/skript/events/EvtMoveOn.java +++ b/src/main/java/ch/njol/skript/events/EvtMoveOn.java @@ -3,7 +3,6 @@ import ch.njol.skript.Skript; import ch.njol.skript.SkriptConfig; import ch.njol.skript.SkriptEventHandler; -import ch.njol.skript.aliases.Aliases; import ch.njol.skript.aliases.ItemData; import ch.njol.skript.aliases.ItemType; import ch.njol.skript.bukkitutil.ItemUtils; @@ -15,13 +14,13 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.event.Event; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.plugin.EventExecutor; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.entity.elements.EvtPressurePlate; import java.util.ArrayList; import java.util.HashSet; diff --git a/src/main/java/ch/njol/skript/events/EvtPlayerChunkEnter.java b/src/main/java/ch/njol/skript/events/EvtPlayerChunkEnter.java deleted file mode 100644 index 13c6f53b164..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtPlayerChunkEnter.java +++ /dev/null @@ -1,38 +0,0 @@ -package ch.njol.skript.events; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerMoveEvent; -import org.jetbrains.annotations.Nullable; - -public class EvtPlayerChunkEnter extends SkriptEvent { - - static { - Skript.registerEvent("Player Chunk Enter", EvtPlayerChunkEnter.class, PlayerMoveEvent.class, "[player] (enter[s] [a] chunk|chunk enter[ing])") - .description("Called when a player enters a chunk. Note that this event is based on 'player move' event, and may be called frequent internally.") - .examples( - "on player enters a chunk:", - "\tsend \"You entered a chunk: %past event-chunk% -> %event-chunk%!\" to player" - ).since("2.7"); - } - - @Override - public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { - return true; - } - - @Override - public boolean check(Event event) { - PlayerMoveEvent moveEvent = ((PlayerMoveEvent) event); - return !moveEvent.getFrom().getChunk().equals(moveEvent.getTo().getChunk()); - } - - @Override - public String toString(@Nullable Event event, boolean debug) { - return "player enter chunk"; - } - -} diff --git a/src/main/java/ch/njol/skript/events/EvtPlayerCommandSend.java b/src/main/java/ch/njol/skript/events/EvtPlayerCommandSend.java deleted file mode 100644 index ada659ee21a..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtPlayerCommandSend.java +++ /dev/null @@ -1,57 +0,0 @@ -package ch.njol.skript.events; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; -import com.google.common.collect.ImmutableCollection; -import com.google.common.collect.ImmutableList; -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerCommandSendEvent; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Collection; - -public class EvtPlayerCommandSend extends SkriptEvent { - - static { - Skript.registerEvent("Send Command List", EvtPlayerCommandSend.class, PlayerCommandSendEvent.class, "send[ing] [of [the]] [server] command[s] list", "[server] command list send") - .description( - "Called when the server sends a list of commands to the player. This usually happens on join. The sent commands " + - "can be modified via the sent commands expression.", - "Modifications will affect what commands show up for the player to tab complete. They will not affect what commands the player can actually run.", - "Adding new commands to the list is illegal behavior and will be ignored." - ) - .examples( - "on send command list:", - "\tset command list to command list where [input does not contain \":\"]", - "\tremove \"help\" from command list" - ) - .since("2.8.0"); - } - - private final Collection originalCommands = new ArrayList<>(); - - @Override - public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { - return true; - } - - @Override - public boolean check(Event event) { - originalCommands.clear(); - originalCommands.addAll(((PlayerCommandSendEvent) event).getCommands()); - return true; - } - - public ImmutableCollection getOriginalCommands() { - return ImmutableList.copyOf(originalCommands); - } - - @Override - public String toString(@Nullable Event event, boolean debug) { - return "sending of the server command list"; - } - -} diff --git a/src/main/java/ch/njol/skript/events/EvtPressurePlate.java b/src/main/java/ch/njol/skript/events/EvtPressurePlate.java deleted file mode 100644 index 4ee7f69b136..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtPressurePlate.java +++ /dev/null @@ -1,60 +0,0 @@ -package ch.njol.skript.events; - -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.block.Block; -import org.bukkit.event.Event; -import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerInteractEvent; -import org.jetbrains.annotations.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.aliases.Aliases; -import ch.njol.skript.aliases.ItemType; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; - -/** - * @author Peter Güttinger - */ -public class EvtPressurePlate extends SkriptEvent { - - static { - // TODO is EntityInteractEvent similar for entities? - Skript.registerEvent("Pressure Plate / Trip", EvtPressurePlate.class, PlayerInteractEvent.class, - "[step[ping] on] [a] [pressure] plate", - "(trip|[step[ping] on] [a] tripwire)") - .description("Called when a player steps on a pressure plate or tripwire respectively.") - .examples("on step on pressure plate:") - .since("1.0 (pressure plate), 1.4.4 (tripwire)"); - } - - private boolean tripwire; - - @Override - public boolean init(final Literal[] args, final int matchedPattern, final ParseResult parser) { - tripwire = matchedPattern == 1; - return true; - } - - @Override - public boolean check(Event event) { - PlayerInteractEvent interactEvent = (PlayerInteractEvent) event; - Block clickedBlock = interactEvent.getClickedBlock(); - Material type = clickedBlock == null ? null : clickedBlock.getType(); - if (type == null || interactEvent.getAction() != Action.PHYSICAL) - return false; - - if (tripwire) - return(type == Material.TRIPWIRE || type == Material.TRIPWIRE_HOOK); - - return Tag.PRESSURE_PLATES.isTagged(type); - } - - @Override - public String toString(final @Nullable Event e, final boolean debug) { - return tripwire ? "trip" : "stepping on a pressure plate"; - } - -} diff --git a/src/main/java/ch/njol/skript/events/EvtResourcePackResponse.java b/src/main/java/ch/njol/skript/events/EvtResourcePackResponse.java deleted file mode 100644 index f466c0539fd..00000000000 --- a/src/main/java/ch/njol/skript/events/EvtResourcePackResponse.java +++ /dev/null @@ -1,60 +0,0 @@ -package ch.njol.skript.events; - -import org.bukkit.event.Event; -import org.bukkit.event.player.PlayerResourcePackStatusEvent; -import org.bukkit.event.player.PlayerResourcePackStatusEvent.Status; -import org.jetbrains.annotations.Nullable; - -import ch.njol.skript.Skript; -import ch.njol.skript.lang.Literal; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.SkriptParser.ParseResult; - -public class EvtResourcePackResponse extends SkriptEvent { - - static { - Skript.registerEvent("Resource Pack Request Response", EvtResourcePackResponse.class, PlayerResourcePackStatusEvent.class, - "resource pack [request] response", - "resource pack [request] %resourcepackstates%") - .description("Called when a player takes action on a resource pack request sent via the ", - "send resource pack effect. ", - "The resource pack condition can be used ", - "to check the resource pack state.", - "", - "This event will be triggered once when the player accepts or declines the resource pack request, ", - "and once when the resource pack is successfully installed or failed to download.") - .examples("on resource pack request response:", - " if the resource pack was declined or failed to download:", - "", - "on resource pack deny:", - " kick the player due to \"You have to install the resource pack to play in this server!\"") - .since("2.4"); - } - - @Nullable - private Literal states; - - @SuppressWarnings("unchecked") - @Override - public boolean init(final Literal[] args, final int matchedPattern, final ParseResult parser) { - if (matchedPattern == 1) - states = (Literal) args[0]; - return true; - } - - @Override - @SuppressWarnings("null") - public boolean check(final Event e) { - if (states != null) { - Status state = ((PlayerResourcePackStatusEvent) e).getStatus(); - return states.check(e, state::equals); - } - return true; - } - - @Override - public String toString(final @Nullable Event e, final boolean debug) { - return states != null ? "resource pack " + states.toString(e, debug) : "resource pack request response"; - } - -} diff --git a/src/main/java/ch/njol/skript/expressions/ExprSentCommands.java b/src/main/java/ch/njol/skript/expressions/ExprSentCommands.java index 5231767c200..df01cc4b50d 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprSentCommands.java +++ b/src/main/java/ch/njol/skript/expressions/ExprSentCommands.java @@ -7,7 +7,6 @@ import ch.njol.skript.doc.Example; import ch.njol.skript.doc.Name; import ch.njol.skript.doc.Since; -import ch.njol.skript.events.EvtPlayerCommandSend; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -17,6 +16,7 @@ import org.bukkit.event.Event; import org.bukkit.event.player.PlayerCommandSendEvent; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.entity.player.elements.events.EvtPlayerCommandSend; import org.skriptlang.skript.lang.structure.Structure; import java.util.ArrayList; diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index 78280a6a8c7..9f187ac6dc8 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -5,7 +5,6 @@ import ch.njol.skript.SkriptConfig; import ch.njol.skript.SkriptEventHandler; import ch.njol.skript.config.SectionNode; -import ch.njol.skript.events.EvtClick; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.parser.ParserInstance; import ch.njol.skript.log.ParseLogHandler; @@ -21,6 +20,7 @@ import org.skriptlang.skript.lang.entry.EntryContainer; import org.skriptlang.skript.lang.script.Script; import org.skriptlang.skript.lang.structure.Structure; +import org.skriptlang.skript.bukkit.entity.player.elements.events.EvtClick; import java.util.List; import java.util.Locale; diff --git a/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java b/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java index ffa8d4bab03..06e4845f1d9 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/BukkitModule.java @@ -16,6 +16,7 @@ import org.skriptlang.skript.bukkit.input.InputModule; import org.skriptlang.skript.bukkit.item.ItemModule; import org.skriptlang.skript.bukkit.itemcomponents.ItemComponentModule; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry; import org.skriptlang.skript.bukkit.loottables.LootTableModule; import org.skriptlang.skript.bukkit.misc.MiscModule; import org.skriptlang.skript.bukkit.particles.ParticleModule; @@ -25,6 +26,7 @@ import org.skriptlang.skript.bukkit.text.TextModule; import org.skriptlang.skript.bukkit.types.*; import org.skriptlang.skript.bukkit.worldborder.elements.WorldBorderModule; +import org.skriptlang.skript.registration.SyntaxRegistry; import java.util.List; @@ -80,6 +82,26 @@ protected void loadSelf(SkriptAddon addon) { // nothing to do } + // TODO: Remove this once the pr for it is merged (https://github.com/SkriptLang/Skript/pull/8741) + /** + * Helper method that calls the given methods with a {@link SyntaxRegistry} and {@link EventValueRegistry} + * @param syntaxRegistry The syntax registry to register with. + * @param eventValueRegistry The event value registry to register with. + * @param functions A series of consumers to call the register syntax. + */ + public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry eventValueRegistry, EventRegistrar... functions) { + for (EventRegistrar value : functions) + value.register(syntaxRegistry, eventValueRegistry); + } + + /** + * A method of registration via a {@link SyntaxRegistry} and {@link EventValueRegistry} + */ + @FunctionalInterface + public interface EventRegistrar { + void register(SyntaxRegistry syntaxRegistry, EventValueRegistry eventValueRegistry); + } + @Override public String name() { return "bukkit"; diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java b/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java index bdd2f43c897..81e64d2d6b1 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java @@ -4,7 +4,6 @@ import ch.njol.skript.entity.SimpleEntityData; import ch.njol.skript.lang.util.SimpleEvent; import com.destroystokyo.paper.event.entity.EntityPathfindEvent; -import io.papermc.paper.event.player.AsyncChatEvent; import org.bukkit.Location; import ch.njol.skript.registrations.Classes; import org.bukkit.entity.AbstractNautilus; @@ -13,6 +12,7 @@ import org.skriptlang.skript.addon.HierarchicalAddonModule; import org.skriptlang.skript.addon.SkriptAddon; import org.skriptlang.skript.bukkit.entity.displays.DisplayModule; +import org.skriptlang.skript.bukkit.entity.elements.EvtPressurePlate; import org.skriptlang.skript.bukkit.entity.elements.expressions.ExprPathfindingLocation; import org.skriptlang.skript.bukkit.entity.elements.expressions.ExprPathfindingTarget; import org.skriptlang.skript.bukkit.entity.elements.effects.EffTeleport; @@ -83,6 +83,7 @@ protected void loadSelf(SkriptAddon addon) { .build()); register(addon, + EvtPressurePlate::register, ExprDeathMessage::register, ExprPathfindingLocation::register, ExprPathfindingTarget::register, diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/elements/EvtPressurePlate.java b/src/main/java/org/skriptlang/skript/bukkit/entity/elements/EvtPressurePlate.java new file mode 100644 index 00000000000..67714ed8e52 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/elements/EvtPressurePlate.java @@ -0,0 +1,69 @@ +package org.skriptlang.skript.bukkit.entity.elements; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import org.bukkit.Material; +import org.bukkit.Tag; +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +// TODO: Make this use EntityInteractEvent instead +public class EvtPressurePlate extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPressurePlate.class, "Step on Pressure Plate / Tripwire") + .supplier(EvtPressurePlate::new) + .addEvent(PlayerInteractEvent.class) + .addPatterns( + "[step[ping] on] [a] [pressure] plate", + "(trip|[step[ping] on] [a] tripwire)" + ) + .addDescription("Called when a player steps on a pressure plate or tripwire respectively.") + .addExample(""" + on step on pressure plate: + chance of 25%: + spawn primed tnt above block at player + send "Run!" to player + """) + .addSince("1.0 (pressure plate)") + .addSince("1.4.4 (tripwire)") + .build()); + + // event values for this are handled in #EvtClick + } + + private boolean tripwire; + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + tripwire = matchedPattern == 1; + return true; + } + + @Override + public boolean check(Event event) { + PlayerInteractEvent playerEvent = (PlayerInteractEvent) event; + Block clickedBlock = playerEvent.getClickedBlock(); + Material type = clickedBlock == null ? null : clickedBlock.getType(); + + if (type == null || playerEvent.getAction() != Action.PHYSICAL) + return false; + + if (tripwire) + return type == Material.TRIPWIRE || type == Material.TRIPWIRE_HOOK; + + return Tag.PRESSURE_PLATES.isTagged(type); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return tripwire ? "stepping on a tripwire" : "stepping on a pressure plate"; + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/PlayerModule.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/PlayerModule.java index 10704eda253..6f66276acc7 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/entity/player/PlayerModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/PlayerModule.java @@ -6,6 +6,7 @@ import org.skriptlang.skript.addon.AddonModule; import org.skriptlang.skript.addon.HierarchicalAddonModule; import org.skriptlang.skript.addon.SkriptAddon; +import org.skriptlang.skript.bukkit.BukkitModule; import org.skriptlang.skript.bukkit.entity.player.elements.effects.*; import org.skriptlang.skript.bukkit.entity.player.elements.events.*; import org.skriptlang.skript.bukkit.entity.player.elements.expressions.*; @@ -26,7 +27,14 @@ protected void loadSelf(SkriptAddon addon) { register(addon, EffBan::register, EffKick::register, - syntaxRegistry -> EvtPlayerGameModeChange.register(syntaxRegistry, eventValueRegistry), + EvtAttemptAttack::register, + EvtCommand::register, + EvtPlayerCommandSend::register, + EvtPlayerEnterChunk::register, + EvtPlayerFirstJoin::register, + EvtPlayerLevelChange::register, + EvtPlayerSignBook::register, + EvtResourcePackResponse::register, ExprChatFormat::register, ExprChatMessage::register, ExprChatRecipients::register, @@ -39,9 +47,16 @@ protected void loadSelf(SkriptAddon addon) { ExprPlayerListPriority::register, ExprQuitMessage::register ); + + BukkitModule.register(moduleRegistry(addon), eventValueRegistry, + EvtClick::register, + EvtPlayerEditBook::register, + EvtPlayerGameModeChange::register + ); + if (Skript.classExists("io.papermc.paper.event.player.PlayerPickBlockEvent")) { register(addon, - EvtPlayerPickItem::register, + syntaxRegistry -> EvtPlayerPickItem.register(syntaxRegistry, eventValueRegistry), ExprPickedItem::register ); } diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtAttemptAttack.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtAttemptAttack.java new file mode 100644 index 00000000000..dfe982cac94 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtAttemptAttack.java @@ -0,0 +1,75 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.entity.EntityData; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.LiteralList; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import io.papermc.paper.event.player.PrePlayerAttackEntityEvent; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtAttemptAttack extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtAttemptAttack.class, "Attempt Attack") + .supplier(EvtAttemptAttack::new) + .addEvent(PrePlayerAttackEntityEvent.class) + .addPatterns("attack attempt", "attempt[ing] to attack %entitydatas%") + .addDescription(""" + Called when a player attempts to attack an entity. + The event will be cancelled as soon as it is fired for non-living entities. + Cancelling this event will prevent the attack and any sounds from being played when attacking. + Any damage events will not be called if this is cancelled. + """) + .addExample(""" + on attack attempt: + if event is cancelled: + broadcast "%attacker% failed to attack %victim%!" + else: + broadcast "%attacker% damaged %victim%!" + """) + .addExample(""" + on attempt to attack an animal: + cancel event + """) + .addExample(""" + on attempt to attack a zombie or creeper: + attacker isn't holding a diamond sword + cancel event + """) + .addSince("2.15") + .build()); + } + + private @Nullable Literal> entityData; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + if (matchedPattern == 1) { + entityData = (Literal>) args[0]; + if (entityData.getAnd() && entityData instanceof LiteralList> list) + list.invertAnd(); + } + return true; + } + + @Override + public boolean check(Event event) { + if (entityData == null) + return true; + + PrePlayerAttackEntityEvent playerEvent = (PrePlayerAttackEntityEvent) event; + + return entityData.check(event, data -> data.isInstance(playerEvent.getAttacked())); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return entityData != null ? "attempting to attack " + entityData.toString(event, debug) : "attack attempt"; + } + +} diff --git a/src/main/java/ch/njol/skript/events/EvtClick.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtClick.java similarity index 66% rename from src/main/java/ch/njol/skript/events/EvtClick.java rename to src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtClick.java index a75ca55e7f6..409e77cedde 100644 --- a/src/main/java/ch/njol/skript/events/EvtClick.java +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtClick.java @@ -1,4 +1,4 @@ -package ch.njol.skript.events; +package org.skriptlang.skript.bukkit.entity.player.elements.events; import ch.njol.skript.Skript; import ch.njol.skript.aliases.ItemType; @@ -8,6 +8,8 @@ import ch.njol.skript.lang.Literal; import ch.njol.skript.lang.SkriptEvent; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; +import ch.njol.skript.util.Direction; import ch.njol.util.coll.CollectionUtils; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; @@ -16,7 +18,6 @@ import org.bukkit.entity.Vehicle; import org.bukkit.event.Event; import org.bukkit.event.block.Action; -import org.bukkit.event.player.PlayerEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -24,13 +25,17 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; import org.skriptlang.skript.lang.comparator.Relation; +import org.skriptlang.skript.registration.SyntaxRegistry; import java.util.function.Predicate; public class EvtClick extends SkriptEvent { - // TODO: UNTIL MC 26.1.1 + // TODO: Remove this once skripts minimum supported version is 26.1.1 private final static boolean USE_OLD_PIAEE_BEHAVIOR = !Skript.isRunningMinecraft(26,1,1); /** @@ -43,24 +48,71 @@ public class EvtClick extends SkriptEvent { */ public final static ClickEventTracker interactTracker = new ClickEventTracker(Skript.getInstance()); - static { - Class[] eventTypes = CollectionUtils.array( - PlayerInteractEvent.class, PlayerInteractEntityEvent.class, PlayerInteractAtEntityEvent.class - ); - Skript.registerEvent("Click", EvtClick.class, eventTypes, + public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry eventValueRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtClick.class, "Player Click") + .supplier(EvtClick::new) + .addEvents(CollectionUtils.array(PlayerInteractEvent.class, PlayerInteractEntityEvent.class, PlayerInteractAtEntityEvent.class)) + .addPatterns( "[(" + RIGHT + ":right|" + LEFT + ":left)(| |-)][mouse(| |-)]click[ing] [on %-entitydata/itemtype/blockdata%] [(with|using|holding) %-itemtype%]", - "[(" + RIGHT + ":right|" + LEFT + ":left)(| |-)][mouse(| |-)]click[ing] (with|using|holding) %itemtype% on %entitydata/itemtype/blockdata%") - .description("Called when a user clicks on a block, an entity or air with or without an item in their hand.", - "Please note that rightclick events with an empty hand while not looking at a block are not sent to the server, so there's no way to detect them.", - "Also note that a leftclick on an entity is an attack and thus not covered by the 'click' event, but the 'damage' event.") - .examples("on click:", - "on rightclick holding a fishing rod:", - "on leftclick on a stone or obsidian:", - "on rightclick on a creeper:", - "on click with a sword:", - "on click on chest[facing=north]:", - "on click on campfire[lit=true]:") - .since("1.0, 2.10 (blockdata)"); + "[(" + RIGHT + ":right|" + LEFT + ":left)(| |-)][mouse(| |-)]click[ing] (with|using|holding) %itemtype% on %entitydata/itemtype/blockdata%" + ) + .addDescription(""" + Called when a user clicks on a block, an entity or air with or without an item in their hand. + Note that right click events with an empty hand while not looking at a block are not sent to the server, so there's no way to detect them. + Also note that a left click on an entity is an attack and thus not covered by the 'click' event, but the 'damage' event. + """) + .addExample(""" + on rightclick holding a fishing rod: + send "Nice %event-item stack% you got there!" to player + """) + .addExample(""" + on rightclick on a creeper: + send "How has it not exploded by now?" to player + push target entity of player upwards at speed 2 + """) + .addExample(""" + on click on chest[facing=north]: + send "Well, it's a chest alright.." to player + set event-block to chest[facing=south] + send "I don't think it likes me.." to player + """) + .addExample(""" + on leftclick on obsidian: + send "Looks pretty hard to break.." + chance of 10%: + break event-block using player's tool + send "How.." to player + """) + .addSince("1.0") + .addSince("2.10 (blockdata)") + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerInteractEntityEvent.class, Entity.class) + .getter(PlayerInteractEntityEvent::getRightClicked) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerInteractEntityEvent.class, ItemStack.class) + .getter(event -> { + EquipmentSlot hand = event.getHand(); + return switch (hand) { + case EquipmentSlot.HAND -> event.getPlayer().getInventory().getItemInMainHand(); + case EquipmentSlot.OFF_HAND -> event.getPlayer().getInventory().getItemInOffHand(); + default -> null; + }; + }) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerInteractEvent.class, ItemStack.class) + .getter(PlayerInteractEvent::getItem) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerInteractEvent.class, Block.class) + .getter(PlayerInteractEvent::getClickedBlock) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerInteractEvent.class, Direction.class) + .getter(event -> new Direction(new double[]{event.getBlockFace().getModX(), event.getBlockFace().getModY(), event.getBlockFace().getModZ()})) + .build()); } /** @@ -208,12 +260,15 @@ public boolean check(Event event) { @Override public String toString(@Nullable Event event, boolean debug) { - return switch (click) { - case LEFT -> "left"; - case RIGHT -> "right"; - default -> ""; - } + "click" + (type != null ? " on " + type.toString(event, debug) : "") + - (tools != null ? " holding " + tools.toString(event, debug) : ""); + return new SyntaxStringBuilder(event, debug) + .append(switch (click) { + case LEFT -> "left click"; + case RIGHT -> "right click"; + default -> "click"; + }) + .appendIf(type != null, "on", type) + .appendIf(tools != null, "holding", tools) + .toString(); } } diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtCommand.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtCommand.java new file mode 100644 index 00000000000..85e69204173 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtCommand.java @@ -0,0 +1,97 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.SyntaxStringBuilder; +import ch.njol.util.StringUtils; +import ch.njol.util.coll.CollectionUtils; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.server.ServerCommandEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +import java.util.Arrays; + +// TODO condition to check whether a given command exists. +public class EvtCommand extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtCommand.class, "Command") + .supplier(EvtCommand::new) + .addEvents(CollectionUtils.array(PlayerCommandPreprocessEvent.class, ServerCommandEvent.class)) + .addPatterns("command [%-strings%]") + .addDescription(""" + Called when a player or console executes any command (including ones from outside of Skript). + See Is a Skript command condition to check if it is a skript command. + """) + .addExample(""" + on command "/ban": + player is not op + send "Nice try.." to player + cancel event + """) + .addExample(""" + on command: + add command to {commands::%player's uuid%::*} + """) + .addExample(""" + on command: + if {combat::%player's uuid%} is set: + cancel event + send "No commands for you!" to player + """) + .addSince("2.0") + .build()); + } + + @Nullable Literal commandsLiteral; + private @Nullable String[] commands; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + if (args[0] != null) { + commandsLiteral = ((Literal) args[0]); + commands = Arrays.stream(commandsLiteral.getAll()) + .map(string -> string.startsWith("/") ? string.substring(1) : string) + .toArray(String[]::new); + } + return true; + } + + @Override + public boolean check(Event event) { + if (event instanceof ServerCommandEvent serverEvent && serverEvent.getCommand().isEmpty()) + return false; + + if (commands == null) + return true; + + String message = switch (event) { + case PlayerCommandPreprocessEvent playerEvent -> playerEvent.getMessage().substring(1); + case ServerCommandEvent serverEvent -> serverEvent.getCommand(); + default -> null; + }; + + if (message == null) + return false; + + return Arrays.stream(commands).anyMatch(candidate -> + StringUtils.startsWithIgnoreCase(message, candidate) // matches the command label + && (candidate.contains(" ") // if candidate contains arguments, then any command that starts with the candidate is a match + || message.length() == candidate.length() // exact match + || Character.isWhitespace(message.charAt(candidate.length())))); // matches label with space after + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return new SyntaxStringBuilder(event, debug) + .append("command") + .appendIf(commandsLiteral != null, commandsLiteral) + .toString(); + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerCommandSend.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerCommandSend.java new file mode 100644 index 00000000000..6b68c7c90df --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerCommandSend.java @@ -0,0 +1,67 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerCommandSendEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +import java.util.ArrayList; +import java.util.Collection; + +public class EvtPlayerCommandSend extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerCommandSend.class, "Send Command List") + .supplier(EvtPlayerCommandSend::new) + .addEvent(PlayerCommandSendEvent.class) + .addPatterns( + "send[ing] [of [the]] [server] command[s] list", + "[server] command list send" + ) + .addDescription(""" + Called when the server sends a list of commands to the player. + This usually happens on join. The sent commands \ + can be modified via the sent commands expression. + Modifications will affect what commands show up for the player to tab complete. + They will not affect what commands the player can actually run. + Adding new commands to the list is illegal behavior and will be ignored. + """) + .addExample(""" + on send command list: + set command list to command list where [input does not contain ":"] + remove "help" from command list + """) + .addSince("2.8.0") + .build()); + } + + private final Collection originalCommands = new ArrayList<>(); + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + return true; + } + + @Override + public boolean check(Event event) { + originalCommands.clear(); + originalCommands.addAll(((PlayerCommandSendEvent) event).getCommands()); + return true; + } + + public ImmutableCollection getOriginalCommands() { + return ImmutableList.copyOf(originalCommands); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "sending of the server command list"; + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerEditBook.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerEditBook.java new file mode 100644 index 00000000000..22f0c4a065c --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerEditBook.java @@ -0,0 +1,77 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerEditBookEvent; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue.Time; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtPlayerEditBook extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry eventValueRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerEditBook.class, "Player Edit Book") + .supplier(EvtPlayerEditBook::new) + .addEvent(PlayerEditBookEvent.class) + .addPatterns("book (edit|change|write)") + .addDescription("Called when a player edits a book.") + .addExample(""" + on book change: + send "Nice edit!" to player + """) + .addSince("2.2-dev31") + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerEditBookEvent.class, ItemStack.class) + .getter(event -> { + ItemStack book = new ItemStack(Material.WRITABLE_BOOK); + book.setItemMeta(event.getPreviousBookMeta()); + return book; + }) + .time(Time.PAST) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerEditBookEvent.class, ItemStack.class) + .getter(event -> { + ItemStack book = new ItemStack(Material.WRITABLE_BOOK); + book.setItemMeta(event.getNewBookMeta()); + return book; + }) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerEditBookEvent.class, Component[].class) + .getter(event -> event.getPreviousBookMeta().pages().toArray(new Component[0])) + .time(Time.PAST) + .build()); + + eventValueRegistry.register(EventValue.builder(PlayerEditBookEvent.class, Component[].class) + .getter(event -> event.getNewBookMeta().pages().toArray(new Component[0])) + .build()); + } + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + return true; + } + + @Override + public boolean check(Event event) { + PlayerEditBookEvent playerEvent = (PlayerEditBookEvent) event; + + return !playerEvent.isSigning(); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "book edit"; + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerEnterChunk.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerEnterChunk.java new file mode 100644 index 00000000000..3ea417ebe92 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerEnterChunk.java @@ -0,0 +1,48 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerMoveEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtPlayerEnterChunk extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerEnterChunk.class, "Player Enter Chunk") + .supplier(EvtPlayerEnterChunk::new) + .addEvent(PlayerMoveEvent.class) + .addPatterns("[player] (enter[s] [a] chunk|chunk enter[ing])") + .addDescription(""" + Called when a player enters a chunk. + Note that this event is based on 'player move' event, and may be called frequently internally. + """) + .addExample(""" + on player enter a chunk: + send "You entered a chunk: %past event-chunk% -> %event-chunk%!" to player" + """) + .addSince("2.7") + .build()); + } + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + return true; + } + + @Override + public boolean check(Event event) { + PlayerMoveEvent playerEvent = (PlayerMoveEvent) event; + + return !playerEvent.getFrom().getChunk().equals(playerEvent.getTo().getChunk()); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "player enter chunk"; + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerFirstJoin.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerFirstJoin.java new file mode 100644 index 00000000000..d383fba7323 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerFirstJoin.java @@ -0,0 +1,46 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerJoinEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtPlayerFirstJoin extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerFirstJoin.class, "Player First Join") + .supplier(EvtPlayerFirstJoin::new) + .addEvent(PlayerJoinEvent.class) + .addPatterns("first (join|login)") + .addDescription("Called when a player joins the server for the first time.") + .addExample(""" + on player first join: + set the join message to "[NEW] %player%!" + """) + .addSince("1.3.7") + .addSince("INSERT VERSION ('player' and 'logging in' in pattern)") + .build()); + } + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + return true; + } + + @Override + public boolean check(Event event) { + PlayerJoinEvent playerEvent = (PlayerJoinEvent) event; + + return !playerEvent.getPlayer().hasPlayedBefore(); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "player first join"; + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerGameModeChange.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerGameModeChange.java index 1625dac946b..18c72ce2794 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerGameModeChange.java +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerGameModeChange.java @@ -15,7 +15,7 @@ public class EvtPlayerGameModeChange extends SkriptEvent { - public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry registry) { + public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry eventValueRegistry) { syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerGameModeChange.class, "Player GameMode Change") .supplier(EvtPlayerGameModeChange::new) .addEvent(PlayerGameModeChangeEvent.class) @@ -35,7 +35,7 @@ public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry re .addSince("1.0") .build()); - registry.register(EventValue.builder(PlayerGameModeChangeEvent.class, GameMode.class) + eventValueRegistry.register(EventValue.builder(PlayerGameModeChangeEvent.class, GameMode.class) .getter(PlayerGameModeChangeEvent::getNewGameMode) .patterns("gamemode") .build()); @@ -45,8 +45,8 @@ public static void register(SyntaxRegistry syntaxRegistry, EventValueRegistry re @Override @SuppressWarnings("unchecked") - public boolean init(Literal[] literals, int i, ParseResult parseResult) { - gamemode = (Literal) literals[0]; + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + gamemode = (Literal) args[0]; return true; } @@ -54,8 +54,10 @@ public boolean init(Literal[] literals, int i, ParseResult parseResult) { public boolean check(Event event) { if (gamemode == null) return true; + GameMode gamemode = this.gamemode.getSingle(event); PlayerGameModeChangeEvent playerEvent = (PlayerGameModeChangeEvent) event; + return playerEvent.getNewGameMode().equals(gamemode); } diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerLevelChange.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerLevelChange.java new file mode 100644 index 00000000000..15069b48f9a --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerLevelChange.java @@ -0,0 +1,63 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerLevelChangeEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtPlayerLevelChange extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerLevelChange.class, "Player Level Change") + .supplier(EvtPlayerLevelChange::new) + .addEvent(PlayerLevelChangeEvent.class) + .addPatterns("[player] level (change|1:up|-1:down)") + .addDescription(""" + Called when a player's level changes,\s + e.g. by gathering experience or by enchanting something. + """) + .addExample(""" + on player level change: + send "experience!" to player + """) + .addExample(""" + on player level up: + send "Its going up!" to player + """) + .addSince("1.0") + .addSince("2.4 (level up/down)") + .build()); + } + + private Kleenean leveling; + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + leveling = Kleenean.get(parseResult.mark); + return true; + } + + @Override + public boolean check(Event event) { + PlayerLevelChangeEvent playerEvent = (PlayerLevelChangeEvent) event; + + if (leveling.isTrue()) { + return playerEvent.getNewLevel() > playerEvent.getOldLevel(); + } else if (leveling.isFalse()) { + return playerEvent.getNewLevel() < playerEvent.getOldLevel(); + } + + return true; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "player level " + (leveling.isTrue() ? "up" : leveling.isFalse() ? "down" : "change"); + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerPickItem.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerPickItem.java index c53c7fc4576..15dbd8df563 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerPickItem.java +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerPickItem.java @@ -1,14 +1,13 @@ package org.skriptlang.skript.bukkit.entity.player.elements.events; import ch.njol.skript.aliases.ItemType; +import ch.njol.skript.classes.Changer.ChangeMode; import ch.njol.skript.classes.data.DefaultComparators; import ch.njol.skript.entity.EntityData; import ch.njol.skript.lang.Literal; import ch.njol.skript.lang.SkriptEvent; import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.SyntaxStringBuilder; -import ch.njol.skript.registrations.EventConverter; -import ch.njol.skript.registrations.EventValues; import ch.njol.skript.util.Patterns; import ch.njol.skript.util.slot.InventorySlot; import ch.njol.skript.util.slot.Slot; @@ -21,8 +20,10 @@ import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValue.Time; +import org.skriptlang.skript.bukkit.lang.eventvalue.EventValueRegistry; import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; -import org.skriptlang.skript.docs.Origin; import org.skriptlang.skript.lang.comparator.Relation; import org.skriptlang.skript.registration.SyntaxRegistry; @@ -35,7 +36,7 @@ public class EvtPlayerPickItem extends SkriptEvent { {"[player] pick[ing] [of] %entitydata/itemtype/blockdata%", null} }); - public static void register(SyntaxRegistry registry) { + public static void register(SyntaxRegistry registry, EventValueRegistry eventValueRegistry) { registry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerPickItem.class, "Player Pick Item") .supplier(EvtPlayerPickItem::new) .addEvents(CollectionUtils.array(PlayerPickBlockEvent.class, PlayerPickEntityEvent.class)) @@ -55,35 +56,29 @@ public static void register(SyntaxRegistry registry) { .addRequiredPlugin("1.21.5+") .build()); - EventValues.registerEventValue(PlayerPickItemEvent.class, Slot.class, new EventConverter<>() { - @Override - public void set(PlayerPickItemEvent event, @Nullable Slot slot) { - if (!(slot instanceof InventorySlot inventorySlot) || inventorySlot.getInventory() != event.getPlayer().getInventory()) - return; - event.setSourceSlot(inventorySlot.getIndex()); - } - - @Override - public @Nullable Slot convert(PlayerPickItemEvent event) { + eventValueRegistry.register(EventValue.builder(PlayerPickItemEvent.class, Slot.class) + .getter(event -> { int source = event.getSourceSlot(); if (source == -1) return null; return new InventorySlot(event.getPlayer().getInventory(), source); - } - }, EventValues.TIME_PAST); - EventValues.registerEventValue(PlayerPickItemEvent.class, Slot.class, new EventConverter<>() { - @Override - public void set(PlayerPickItemEvent event, @Nullable Slot slot) { + }) + .registerChanger(ChangeMode.SET, (event, slot) -> { if (!(slot instanceof InventorySlot inventorySlot) || inventorySlot.getInventory() != event.getPlayer().getInventory()) return; - event.setTargetSlot(inventorySlot.getIndex()); - } + event.setSourceSlot(inventorySlot.getIndex()); + }) + .time(Time.PAST) + .build()); - @Override - public Slot convert(PlayerPickItemEvent event) { - return new InventorySlot(event.getPlayer().getInventory(), event.getTargetSlot()); - } - }); + eventValueRegistry.register(EventValue.builder(PlayerPickItemEvent.class, Slot.class) + .getter(event -> new InventorySlot(event.getPlayer().getInventory(), event.getTargetSlot())) + .registerChanger(ChangeMode.SET, (event, slot) -> { + if (!(slot instanceof InventorySlot inventorySlot) || inventorySlot.getInventory() != event.getPlayer().getInventory()) + return; + event.setTargetSlot(inventorySlot.getIndex()); + }) + .build()); } private @Nullable PickType pickType; @@ -134,18 +129,15 @@ public boolean check(Event event) { @Override public String toString(@Nullable Event event, boolean debug) { - SyntaxStringBuilder builder = new SyntaxStringBuilder(event, debug); - builder.append("player picking"); - if (pickType != null) { - switch (pickType) { - case ANY -> builder.append("an item"); - case BLOCK -> builder.append("a block"); - case ENTITY -> builder.append("an entity"); - } - } else if (type != null) { - builder.append(type); - } - return builder.toString(); + return new SyntaxStringBuilder(event, debug) + .append("player picking") + .appendIf(pickType != null, switch (pickType) { + case ANY -> "an item"; + case BLOCK -> "a block"; + case ENTITY -> "an entity"; + }) + .appendIf(pickType == null, type) + .toString(); } private enum PickType { diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerSignBook.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerSignBook.java new file mode 100644 index 00000000000..24da85ca1f9 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtPlayerSignBook.java @@ -0,0 +1,46 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerEditBookEvent; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtPlayerSignBook extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtPlayerSignBook.class, "Player Sign Book") + .supplier(EvtPlayerSignBook::new) + .addEvent(PlayerEditBookEvent.class) + .addPatterns("book sign[ing]", "[player] sign[ing] [a] book") + .addDescription("Called when a player signs a book.") + .addExample(""" + on player sign book: + send "Now everyone will know you wrote %event-item stack%!" to player + """) + .addSince("2.2-dev31") + .addSince("INSERT VERSION ('player signing a book' pattern)") + .build()); + } + + @Override + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + return true; + } + + @Override + public boolean check(Event event) { + PlayerEditBookEvent playerEvent = (PlayerEditBookEvent) event; + + return playerEvent.isSigning(); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "player sign book"; + } + +} diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtResourcePackResponse.java b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtResourcePackResponse.java new file mode 100644 index 00000000000..16197319978 --- /dev/null +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/player/elements/events/EvtResourcePackResponse.java @@ -0,0 +1,70 @@ +package org.skriptlang.skript.bukkit.entity.player.elements.events; + +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import org.bukkit.event.Event; +import org.bukkit.event.player.PlayerResourcePackStatusEvent; +import org.bukkit.event.player.PlayerResourcePackStatusEvent.Status; +import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos; +import org.skriptlang.skript.registration.SyntaxRegistry; + +public class EvtResourcePackResponse extends SkriptEvent { + + public static void register(SyntaxRegistry syntaxRegistry) { + syntaxRegistry.register(BukkitSyntaxInfos.Event.KEY, BukkitSyntaxInfos.Event.builder(EvtResourcePackResponse.class, "Resource Pack Request Response") + .supplier(EvtResourcePackResponse::new) + .addEvent(PlayerResourcePackStatusEvent.class) + .addPatterns( + "resource pack [request] response", + "resource pack [request] %resourcepackstates%" + ) + .addDescription(""" + Called when a player takes action on a resource pack request sent via the\s + send resource pack effect. + The resource pack condition can be used\s + to check the resource pack state. + This event will be triggered once when the player accepts or declines the resource pack request,\s + and once when the resource pack is successfully installed or failed to download. + """) + .addExample(""" + on resource pack request response: + if the resource pack was declined or failed to download: + kick player due to "You must accept the resource pack to play!" + """) + .addExample(""" + on resource pack accept: + send "Welcome to the server!" to player + """) + .addSince("2.4") + .build()); + } + + private @Nullable Literal states; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult) { + if (matchedPattern == 1) + states = (Literal) args[0]; + return true; + } + + @Override + public boolean check(Event event) { + if (states == null) + return true; + + PlayerResourcePackStatusEvent playerEvent = (PlayerResourcePackStatusEvent) event; + + Status state = playerEvent.getStatus(); + return states.check(event, state::equals); + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return states != null ? "resource pack " + states.toString(event, debug) : "resource pack request response"; + } + +}