mirror of
https://github.com/CarmJos/EasyListener.git
synced 2024-09-19 21:35:51 +00:00
feat(api): 提供functional注册方式,预设方法提供方式变更。
BREAKING CHANGE: 大部分API的实现方式发生变革,与先前版本并不兼容。
This commit is contained in:
parent
ed376a8239
commit
10b4800ac9
33
README.md
33
README.md
@ -12,43 +12,18 @@
|
|||||||
|
|
||||||
### [开发示例](src/test/java/DemoPlugin.java)
|
### [开发示例](src/test/java/DemoPlugin.java)
|
||||||
|
|
||||||
您可以点击这里访问项目的 [JavaDoc](https://carmjos.github.io/EasyListener) 。
|
相关开发示例请 [点击这里](src/test/java/DemoPlugin.java),您也可以直接访问项目的 [JavaDoc](https://carmjos.github.io/EasyListener) 。
|
||||||
|
|
||||||
```java
|
```java
|
||||||
|
|
||||||
public class DemoPlugin extends JavaPlugin {
|
public class DemoPlugin extends JavaPlugin {
|
||||||
|
|
||||||
protected final EasyListener listeners = EasyListener.create(this);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
listeners // 基本用法
|
EasyListener listeners = EasyListener.create(this);
|
||||||
.handle(PlayerInteractAtEntityEvent.class, (event) -> {
|
// listeners...; // Do something...
|
||||||
Entity clicked = event.getRightClicked();
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
if (clicked instanceof Player) {
|
|
||||||
player.sendMessage("你点了 " + clicked.getName() + " 一下!");
|
|
||||||
}
|
|
||||||
|
|
||||||
}) // 处理一个事件
|
|
||||||
.cancel(PlayerPickupArrowEvent.class) // 取消一个事件
|
|
||||||
.cancel(
|
|
||||||
EntityDamageEvent.class, EventPriority.HIGHEST,
|
|
||||||
(event) -> event.getCause() != EntityDamageEvent.DamageCause.ENTITY_ATTACK
|
|
||||||
); // 有条件的取消一个事件
|
|
||||||
|
|
||||||
listeners // 额外提供的快捷方法
|
|
||||||
.cancelDeath(null) // 所有玩家取消死亡
|
|
||||||
.cancelBreak(player -> !player.isOp()) // 禁止非OP玩家破坏方块/接水或岩浆
|
|
||||||
.cancelPlace(player -> !player.isOp()) // 禁止非OP玩家放置方块/放水或岩浆
|
|
||||||
.cancelPVP((attacker, victim) -> !attacker.isOp()) // 禁止非op玩家PVP
|
|
||||||
.cancelWeatherChange() // 取消天气变更
|
|
||||||
.cancelJoinMessage() // 取消加入消息
|
|
||||||
// .cancelQuitMessage()
|
|
||||||
// .handleJoinMessage(player -> "玩家 " + player.getName() + " 加入了服务器。")
|
|
||||||
.handleQuitMessage(player -> "玩家 " + player.getName() + " 退出了服务器。"); // 设定退出消息
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
2
pom.xml
2
pom.xml
@ -13,7 +13,7 @@
|
|||||||
</properties>
|
</properties>
|
||||||
<groupId>cc.carm.lib</groupId>
|
<groupId>cc.carm.lib</groupId>
|
||||||
<artifactId>easylistener</artifactId>
|
<artifactId>easylistener</artifactId>
|
||||||
<version>1.2.0</version>
|
<version>2.0.0</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>EasyListener</name>
|
<name>EasyListener</name>
|
||||||
|
@ -1,27 +1,17 @@
|
|||||||
package cc.carm.lib.easylistener;
|
package cc.carm.lib.easylistener;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import cc.carm.lib.easylistener.handler.BundleEventHandler;
|
||||||
import org.bukkit.entity.Entity;
|
import cc.carm.lib.easylistener.handler.MultiEventHandler;
|
||||||
import org.bukkit.entity.Player;
|
import cc.carm.lib.easylistener.handler.SingleEventHandler;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.*;
|
import org.bukkit.event.*;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.plugin.*;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
|
||||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
||||||
import org.bukkit.event.entity.EntitySpawnEvent;
|
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
|
||||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
|
||||||
import org.bukkit.event.player.PlayerBucketFillEvent;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import org.bukkit.event.weather.WeatherChangeEvent;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.BiPredicate;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,7 +19,13 @@ import java.util.function.Predicate;
|
|||||||
*
|
*
|
||||||
* @author CarmJos
|
* @author CarmJos
|
||||||
*/
|
*/
|
||||||
public interface EasyListener extends Listener {
|
public class EasyListener implements Listener {
|
||||||
|
|
||||||
|
protected final Plugin plugin;
|
||||||
|
|
||||||
|
public EasyListener(Plugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个新的 {@link EasyListener} 实例
|
* 创建一个新的 {@link EasyListener} 实例
|
||||||
@ -37,18 +33,35 @@ public interface EasyListener extends Listener {
|
|||||||
* @param plugin {@link Plugin}插件实例
|
* @param plugin {@link Plugin}插件实例
|
||||||
* @return {@link EasyListener} 实例
|
* @return {@link EasyListener} 实例
|
||||||
*/
|
*/
|
||||||
static @NotNull ListenerManager create(@NotNull Plugin plugin) {
|
public static @NotNull EasyListener create(@NotNull Plugin plugin) {
|
||||||
return new ListenerManager(plugin);
|
return new EasyListener(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注销本监听器内的全部监听器。
|
* 注销本监听器内的全部监听器。
|
||||||
* <br> 也可以通过 {@link HandlerList#unregister(Listener)} 方法注销本监听器。
|
* <br> 也可以通过 {@link HandlerList#unregister(Listener)} 方法注销本监听器。
|
||||||
*/
|
*/
|
||||||
default void unregisterAll() {
|
public void unregisterAll() {
|
||||||
HandlerList.unregisterAll(this);
|
HandlerList.unregisterAll(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <E extends Event> @NotNull SingleEventHandler<E> handleEvent(@NotNull Class<E> eventClass) {
|
||||||
|
return new SingleEventHandler<>(this, eventClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <E extends Event> @NotNull MultiEventHandler<E> handleEvents(@NotNull Class<E> eventType) {
|
||||||
|
return new MultiEventHandler<>(this, eventType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> @NotNull BundleEventHandler<T, Event> handleBundle(@NotNull Class<T> elementClass) {
|
||||||
|
return handleBundle(elementClass, Event.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T, E extends Event> @NotNull BundleEventHandler<T, E> handleBundle(@NotNull Class<T> elementClass,
|
||||||
|
@NotNull Class<E> eventType) {
|
||||||
|
return new BundleEventHandler<>(this, elementClass, eventType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理一个事件。
|
* 处理一个事件。
|
||||||
*
|
*
|
||||||
@ -59,9 +72,40 @@ public interface EasyListener extends Listener {
|
|||||||
* @param <T> {@link Event} 事件的类型
|
* @param <T> {@link Event} 事件的类型
|
||||||
* @return 本实例
|
* @return 本实例
|
||||||
*/
|
*/
|
||||||
<T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
public <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
||||||
@Nullable EventPriority priority, boolean ignoreCancelled,
|
@Nullable EventPriority priority, boolean ignoreCancelled,
|
||||||
@NotNull Consumer<T> eventConsumer);
|
@NotNull Consumer<T> eventConsumer) {
|
||||||
|
register(eventClass, eventConsumer, Optional.ofNullable(priority).orElse(EventPriority.NORMAL), ignoreCancelled);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有条件地取消一个事件。
|
||||||
|
* <br> 本方法在条件满足时对事件进行取消,不会改变事件取消的状态。
|
||||||
|
* <br> 因此,已经被取消的事件将不再进行判断和取消。。
|
||||||
|
*
|
||||||
|
* @param eventClass {@link Event} 事件类
|
||||||
|
* @param priority {@link EventPriority} 事件处理优先级
|
||||||
|
* @param eventPredicate 判断事件是否可以取消的条件
|
||||||
|
* @param afterCancelled 当事件被取消后执行的方法
|
||||||
|
* @param <T> {@link Event} 事件的类型,必须实现 {@link Cancellable} 。
|
||||||
|
* @return 本实例
|
||||||
|
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
||||||
|
*/
|
||||||
|
public <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass,
|
||||||
|
@Nullable EventPriority priority,
|
||||||
|
@Nullable Predicate<? super T> eventPredicate,
|
||||||
|
@Nullable Consumer<? super T> afterCancelled) {
|
||||||
|
requireType(Cancellable.class, eventClass, "Event class " + eventClass.getName() + " is not cancellable");
|
||||||
|
|
||||||
|
final Predicate<? super T> predicate = Optional.ofNullable(eventPredicate).orElse(t -> true);
|
||||||
|
return handle(eventClass, priority, true, (event) -> {
|
||||||
|
if (predicate.test(event)) {
|
||||||
|
((Cancellable) event).setCancelled(true);
|
||||||
|
if (afterCancelled != null) afterCancelled.accept(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 有条件地取消一个事件。
|
* 有条件地取消一个事件。
|
||||||
@ -75,9 +119,11 @@ public interface EasyListener extends Listener {
|
|||||||
* @return 本实例
|
* @return 本实例
|
||||||
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
||||||
*/
|
*/
|
||||||
<T extends Event> EasyListener cancel(@NotNull Class<T> eventClass,
|
public <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass,
|
||||||
@Nullable EventPriority priority,
|
@Nullable EventPriority priority,
|
||||||
@Nullable Predicate<T> eventPredicate);
|
@Nullable Predicate<? super T> eventPredicate) {
|
||||||
|
return cancel(eventClass, priority, eventPredicate, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理一个事件。
|
* 处理一个事件。
|
||||||
@ -87,8 +133,8 @@ public interface EasyListener extends Listener {
|
|||||||
* @param <T> {@link Event} 事件的类型
|
* @param <T> {@link Event} 事件的类型
|
||||||
* @return 本实例
|
* @return 本实例
|
||||||
*/
|
*/
|
||||||
default <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
public <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
||||||
@NotNull Consumer<T> eventConsumer) {
|
@NotNull Consumer<T> eventConsumer) {
|
||||||
return handle(eventClass, null, eventConsumer);
|
return handle(eventClass, null, eventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,9 +147,9 @@ public interface EasyListener extends Listener {
|
|||||||
* @param <T> {@link Event} 事件的类型
|
* @param <T> {@link Event} 事件的类型
|
||||||
* @return 本实例
|
* @return 本实例
|
||||||
*/
|
*/
|
||||||
default <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
public <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
||||||
boolean ignoreCancelled,
|
boolean ignoreCancelled,
|
||||||
@NotNull Consumer<T> eventConsumer) {
|
@NotNull Consumer<T> eventConsumer) {
|
||||||
return handle(eventClass, null, ignoreCancelled, eventConsumer);
|
return handle(eventClass, null, ignoreCancelled, eventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,9 +162,9 @@ public interface EasyListener extends Listener {
|
|||||||
* @param <T> {@link Event} 事件的类型
|
* @param <T> {@link Event} 事件的类型
|
||||||
* @return 本实例
|
* @return 本实例
|
||||||
*/
|
*/
|
||||||
default <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
public <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
||||||
@Nullable EventPriority priority,
|
@Nullable EventPriority priority,
|
||||||
@NotNull Consumer<T> eventConsumer) {
|
@NotNull Consumer<T> eventConsumer) {
|
||||||
return handle(eventClass, priority, false, eventConsumer);
|
return handle(eventClass, priority, false, eventConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +176,7 @@ public interface EasyListener extends Listener {
|
|||||||
* @return 本实例
|
* @return 本实例
|
||||||
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
||||||
*/
|
*/
|
||||||
default <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass) {
|
public <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass) {
|
||||||
return cancel(eventClass, null, null);
|
return cancel(eventClass, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,115 +189,70 @@ public interface EasyListener extends Listener {
|
|||||||
* @return 本实例
|
* @return 本实例
|
||||||
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
* @throws IllegalArgumentException 如果事件没有实现 {@link Cancellable} 则抛出此异常
|
||||||
*/
|
*/
|
||||||
default <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass,
|
public <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass,
|
||||||
@Nullable Predicate<T> eventPredicate) {
|
@Nullable Predicate<T> eventPredicate) {
|
||||||
return cancel(eventClass, null, eventPredicate);
|
return cancel(eventClass, null, eventPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// >---------------------------
|
public Plugin getPlugin() {
|
||||||
// 预设快捷操作方法
|
return plugin;
|
||||||
|
|
||||||
default EasyListener cancelJoinMessage() {
|
|
||||||
return handleJoinMessage(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener handleJoinMessage(@Nullable Function<Player, String> joinMessage) {
|
|
||||||
final Function<Player, String> message = Optional.ofNullable(joinMessage).orElse(t -> "");
|
|
||||||
return handle(PlayerJoinEvent.class, (event) -> event.setJoinMessage(message.apply(event.getPlayer())));
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelQuitMessage() {
|
|
||||||
return handleQuitMessage(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener handleQuitMessage(@Nullable Function<Player, String> quitMessage) {
|
|
||||||
final Function<Player, String> message = Optional.ofNullable(quitMessage).orElse(t -> "");
|
|
||||||
return handle(PlayerQuitEvent.class, (event) -> event.setQuitMessage(message.apply(event.getPlayer())));
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelWeatherChange() {
|
|
||||||
return cancelWeatherChange(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelWeatherChange(@Nullable Predicate<WeatherChangeEvent> weatherPredicate) {
|
|
||||||
return cancel(WeatherChangeEvent.class, weatherPredicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelBreak(@Nullable Predicate<Player> player) {
|
|
||||||
final Predicate<Player> predicate = Optional.ofNullable(player).orElse(t -> true);
|
|
||||||
return cancelBreak(
|
|
||||||
(event) -> predicate.test(event.getPlayer()),
|
|
||||||
(event) -> predicate.test(event.getPlayer())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelBreak(@Nullable Predicate<BlockBreakEvent> blockBreakPredicate,
|
|
||||||
@Nullable Predicate<PlayerBucketFillEvent> bucketFillPredicate) {
|
|
||||||
return cancel(BlockBreakEvent.class, blockBreakPredicate)
|
|
||||||
.cancel(PlayerBucketFillEvent.class, bucketFillPredicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelPlace(@Nullable Predicate<Player> player) {
|
|
||||||
final Predicate<Player> predicate = Optional.ofNullable(player).orElse(t -> true);
|
|
||||||
return cancelPlace(
|
|
||||||
(event) -> predicate.test(event.getPlayer()),
|
|
||||||
(event) -> predicate.test(event.getPlayer())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default EasyListener cancelPlace(@Nullable Predicate<BlockPlaceEvent> blockBreakPredicate,
|
|
||||||
@Nullable Predicate<PlayerBucketEmptyEvent> bucketEmptyPredicate) {
|
|
||||||
return cancel(BlockPlaceEvent.class, blockBreakPredicate)
|
|
||||||
.cancel(PlayerBucketEmptyEvent.class, bucketEmptyPredicate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 有条件的取消玩家PVP。
|
* 通过 {@link SimplePluginManager} 获取到一个事件类的 {@link HandlerList} 。
|
||||||
*
|
*
|
||||||
* @param predicate 判断器,返回true则取消事件。两参数分别为 attacker 与 victim 。
|
* @param eventClass 事件类
|
||||||
* @return 当前实例
|
* @return 事件类的 {@link HandlerList}
|
||||||
*/
|
*/
|
||||||
default EasyListener cancelPVP(@Nullable BiPredicate<Player, Player> predicate) {
|
private @NotNull HandlerList getEventListeners(@NotNull Class<? extends Event> eventClass) {
|
||||||
final BiPredicate<Player, Player> p = Optional.ofNullable(predicate).orElse((attacker, victim) -> true);
|
try {
|
||||||
return cancelAttack((attacker, damager) -> {
|
Method method = SimplePluginManager.class.getDeclaredMethod("getEventListeners", Class.class);
|
||||||
if (!(attacker instanceof Player) || !(damager instanceof Player)) return false;
|
method.setAccessible(true);
|
||||||
else return p.test((Player) attacker, (Player) damager);
|
return (HandlerList) method.invoke(Bukkit.getPluginManager(), eventClass);
|
||||||
});
|
} catch (Exception e) {
|
||||||
|
throw new IllegalPluginAccessException(e.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 有条件的取消两个实体间的伤害。
|
* 创建一个事件的执行器实例。
|
||||||
*
|
*
|
||||||
* @param predicate 判断器,返回true则取消事件。两参数分别为 attacker 与 victim 。
|
* @param eventClass 事件类
|
||||||
* @return 当前实例
|
* @param eventConsumer 事件执行内容
|
||||||
|
* @param <T> 事件类型
|
||||||
|
* @return 事件的执行器实例
|
||||||
*/
|
*/
|
||||||
default EasyListener cancelAttack(@Nullable BiPredicate<Entity/*attacker*/, Entity/*victim*/> predicate) {
|
protected <T extends Event> EventExecutor createExecutor(@NotNull Class<T> eventClass,
|
||||||
final BiPredicate<Entity, Entity> p = Optional.ofNullable(predicate).orElse((attacker, victim) -> true);
|
@NotNull Consumer<T> eventConsumer) {
|
||||||
return cancel(EntityDamageByEntityEvent.class, (event) -> p.test(event.getDamager(), event.getEntity()));
|
return (listener, event) -> {
|
||||||
|
try {
|
||||||
|
if (!eventClass.isAssignableFrom(event.getClass())) return;
|
||||||
|
eventConsumer.accept(eventClass.cast(event));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throw new EventException(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
default EasyListener cancelDeath(@Nullable Predicate<Player> predicate) {
|
protected void requireType(@NotNull Class<?> target, @NotNull Class<?> value,
|
||||||
return cancelDeath(predicate, (event) -> {
|
@Nullable String message) throws IllegalArgumentException {
|
||||||
event.setDeathMessage(null);
|
if (target.isAssignableFrom(value)) return;
|
||||||
event.setKeepInventory(true);
|
if (message == null) throw new IllegalArgumentException();
|
||||||
event.setKeepLevel(true);
|
else throw new IllegalArgumentException(message);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
protected void register(@NotNull Class<? extends Event> eventClass, @NotNull RegisteredListener listener) {
|
||||||
default EasyListener cancelDeath(@Nullable Predicate<Player> predicate,
|
getEventListeners(eventClass).register(listener);
|
||||||
@Nullable Consumer<PlayerDeathEvent> handler) {
|
|
||||||
final Predicate<Player> p = Optional.ofNullable(predicate).orElse((player) -> true);
|
|
||||||
return handle(PlayerDeathEvent.class, (event) -> {
|
|
||||||
if (!p.test(event.getEntity())) return;
|
|
||||||
event.getEntity().setHealth(event.getEntity().getMaxHealth());
|
|
||||||
Optional.ofNullable(handler).ifPresent(consumer -> consumer.accept(event));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default EasyListener cancelSpawn(@Nullable BiPredicate<Entity, Location> predicate) {
|
protected void register(@NotNull Class<? extends Event> eventClass, @NotNull EventExecutor executor,
|
||||||
final BiPredicate<Entity, Location> p = Optional.ofNullable(predicate).orElse((entity, location) -> !(entity instanceof Player));
|
@NotNull EventPriority priority, boolean ignoreCancelled) {
|
||||||
return cancel(EntitySpawnEvent.class, (event) -> p.test(event.getEntity(), event.getLocation()));
|
register(eventClass, new RegisteredListener(this, executor, priority, getPlugin(), ignoreCancelled));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T extends Event> void register(@NotNull Class<T> eventClass, @NotNull Consumer<T> eventConsumer,
|
||||||
|
@NotNull EventPriority priority, boolean ignoreCancelled) {
|
||||||
|
register(eventClass, createExecutor(eventClass, eventConsumer), priority, ignoreCancelled);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,103 +0,0 @@
|
|||||||
package cc.carm.lib.easylistener;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.*;
|
|
||||||
import org.bukkit.plugin.*;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Predicate;
|
|
||||||
|
|
||||||
@SuppressWarnings("SameParameterValue")
|
|
||||||
public class ListenerManager implements EasyListener {
|
|
||||||
|
|
||||||
protected final Plugin plugin;
|
|
||||||
|
|
||||||
public ListenerManager(Plugin plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Plugin getPlugin() {
|
|
||||||
return plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过 {@link SimplePluginManager} 获取到一个事件类的 {@link HandlerList} 。
|
|
||||||
*
|
|
||||||
* @param eventClass 事件类
|
|
||||||
* @return 事件类的 {@link HandlerList}
|
|
||||||
*/
|
|
||||||
private @NotNull HandlerList getEventListeners(@NotNull Class<? extends Event> eventClass) {
|
|
||||||
try {
|
|
||||||
Method method = SimplePluginManager.class.getDeclaredMethod("getEventListeners", Class.class);
|
|
||||||
method.setAccessible(true);
|
|
||||||
return (HandlerList) method.invoke(Bukkit.getPluginManager(), eventClass);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalPluginAccessException(e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建一个事件的执行器实例。
|
|
||||||
*
|
|
||||||
* @param eventClass 事件类
|
|
||||||
* @param eventConsumer 事件执行内容
|
|
||||||
* @param <T> 事件类型
|
|
||||||
* @return 事件的执行器实例
|
|
||||||
*/
|
|
||||||
protected <T extends Event> EventExecutor createExecutor(@NotNull Class<T> eventClass,
|
|
||||||
@NotNull Consumer<T> eventConsumer) {
|
|
||||||
return (listener, event) -> {
|
|
||||||
try {
|
|
||||||
if (!eventClass.isAssignableFrom(event.getClass())) return;
|
|
||||||
eventConsumer.accept(eventClass.cast(event));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
throw new EventException(t);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void requireType(@NotNull Class<?> target, @NotNull Class<?> value,
|
|
||||||
@Nullable String message) throws IllegalArgumentException {
|
|
||||||
if (target.isAssignableFrom(value)) return;
|
|
||||||
if (message == null) throw new IllegalArgumentException();
|
|
||||||
else throw new IllegalArgumentException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void register(@NotNull Class<? extends Event> eventClass, @NotNull RegisteredListener listener) {
|
|
||||||
getEventListeners(eventClass).register(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void register(@NotNull Class<? extends Event> eventClass, @NotNull EventExecutor executor,
|
|
||||||
@NotNull EventPriority priority, boolean ignoreCancelled) {
|
|
||||||
register(eventClass, new RegisteredListener(this, executor, priority, getPlugin(), ignoreCancelled));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T extends Event> void register(@NotNull Class<T> eventClass, @NotNull Consumer<T> eventConsumer,
|
|
||||||
@NotNull EventPriority priority, boolean ignoreCancelled) {
|
|
||||||
register(eventClass, createExecutor(eventClass, eventConsumer), priority, ignoreCancelled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends Event> EasyListener handle(@NotNull Class<T> eventClass,
|
|
||||||
@Nullable EventPriority priority, boolean ignoreCancelled,
|
|
||||||
@NotNull Consumer<T> eventConsumer) {
|
|
||||||
register(eventClass, eventConsumer, Optional.ofNullable(priority).orElse(EventPriority.NORMAL), ignoreCancelled);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <T extends Event> EasyListener cancel(@NotNull Class<T> eventClass, @Nullable EventPriority priority,
|
|
||||||
@Nullable Predicate<T> eventPredicate) {
|
|
||||||
requireType(Cancellable.class, eventClass, "Event class " + eventClass.getName() + " is not cancellable");
|
|
||||||
|
|
||||||
final Predicate<T> predicate = Optional.ofNullable(eventPredicate).orElse(t -> true);
|
|
||||||
return handle(eventClass, priority, true, (event) -> {
|
|
||||||
if (predicate.test(event)) ((Cancellable) event).setCancelled(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,123 @@
|
|||||||
|
package cc.carm.lib.easylistener.defaults;
|
||||||
|
|
||||||
|
import cc.carm.lib.easylistener.EasyListener;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntitySpawnEvent;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
||||||
|
import org.bukkit.event.player.PlayerBucketFillEvent;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
import org.bukkit.event.weather.WeatherChangeEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiPredicate;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class CommonListeners {
|
||||||
|
|
||||||
|
public static void cancelJoinMessage(@NotNull EasyListener source) {
|
||||||
|
handleJoinMessage(source, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handleJoinMessage(@NotNull EasyListener source, @Nullable Function<Player, String> joinMessage) {
|
||||||
|
final Function<Player, String> message = Optional.ofNullable(joinMessage).orElse(t -> "");
|
||||||
|
source.handle(PlayerJoinEvent.class, (event) -> event.setJoinMessage(message.apply(event.getPlayer())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelQuitMessage(@NotNull EasyListener source) {
|
||||||
|
handleQuitMessage(source, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void handleQuitMessage(@NotNull EasyListener source, @Nullable Function<Player, String> quitMessage) {
|
||||||
|
final Function<Player, String> message = Optional.ofNullable(quitMessage).orElse(t -> "");
|
||||||
|
source.handle(PlayerQuitEvent.class, (event) -> event.setQuitMessage(message.apply(event.getPlayer())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelWeatherChange(@NotNull EasyListener source) {
|
||||||
|
cancelWeatherChange(source, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelWeatherChange(@NotNull EasyListener source,
|
||||||
|
@Nullable Predicate<WeatherChangeEvent> weatherPredicate) {
|
||||||
|
source.cancel(WeatherChangeEvent.class, weatherPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelBreak(@NotNull EasyListener source, @Nullable Predicate<Player> playerPredicate) {
|
||||||
|
source.handleBundle(Player.class)
|
||||||
|
.from(BlockBreakEvent.class, BlockBreakEvent::getPlayer)
|
||||||
|
.from(PlayerBucketFillEvent.class, PlayerBucketFillEvent::getPlayer)
|
||||||
|
.filter(playerPredicate).cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelPlace(@NotNull EasyListener source, @Nullable Predicate<Player> playerPredicate) {
|
||||||
|
source.handleBundle(Player.class)
|
||||||
|
.from(BlockPlaceEvent.class, BlockPlaceEvent::getPlayer)
|
||||||
|
.from(PlayerBucketEmptyEvent.class, PlayerBucketEmptyEvent::getPlayer)
|
||||||
|
.filter(playerPredicate).cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有条件的取消玩家PVP。
|
||||||
|
*
|
||||||
|
* @param source 用于注册的源 {@link EasyListener} 对象。
|
||||||
|
* @param predicate 判断器,返回true则取消事件。两参数分别为 attacker 与 victim 。
|
||||||
|
*/
|
||||||
|
public static void cancelPVP(@NotNull EasyListener source,
|
||||||
|
@Nullable BiPredicate<Player, Player> predicate) {
|
||||||
|
final BiPredicate<Player, Player> p = Optional.ofNullable(predicate).orElse((attacker, victim) -> true);
|
||||||
|
cancelAttack(source, (attacker, damager) -> {
|
||||||
|
if (!(attacker instanceof Player) || !(damager instanceof Player)) return false;
|
||||||
|
else return p.test((Player) attacker, (Player) damager);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有条件的取消两个实体间的伤害。
|
||||||
|
*
|
||||||
|
* @param source 用于注册的源 {@link EasyListener} 对象。
|
||||||
|
* @param predicate 判断器,返回true则取消事件。两参数分别为 attacker 与 victim 。
|
||||||
|
*/
|
||||||
|
public static void cancelAttack(@NotNull EasyListener source,
|
||||||
|
@Nullable BiPredicate<Entity/*attacker*/, Entity/*victim*/> predicate) {
|
||||||
|
final BiPredicate<Entity, Entity> p = Optional.ofNullable(predicate).orElse((attacker, victim) -> true);
|
||||||
|
source.cancel(EntityDamageByEntityEvent.class, (event) -> p.test(event.getDamager(), event.getEntity()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelDeath(@NotNull EasyListener source,
|
||||||
|
@Nullable Predicate<Player> predicate) {
|
||||||
|
cancelDeath(source, predicate, event -> {
|
||||||
|
event.setDeathMessage(null);
|
||||||
|
event.setKeepInventory(true);
|
||||||
|
event.setKeepLevel(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public static void cancelDeath(@NotNull EasyListener source,
|
||||||
|
@Nullable Predicate<Player> predicate,
|
||||||
|
@Nullable Consumer<PlayerDeathEvent> handler) {
|
||||||
|
final Predicate<Player> p = Optional.ofNullable(predicate).orElse((player) -> true);
|
||||||
|
source.handle(PlayerDeathEvent.class, (event) -> {
|
||||||
|
if (!p.test(event.getEntity())) return;
|
||||||
|
event.getEntity().setHealth(event.getEntity().getMaxHealth());
|
||||||
|
Optional.ofNullable(handler).ifPresent(consumer -> consumer.accept(event));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancelSpawn(@NotNull EasyListener source,
|
||||||
|
@Nullable BiPredicate<Entity, Location> predicate) {
|
||||||
|
final BiPredicate<Entity, Location> p = Optional.ofNullable(predicate).orElse((entity, location) -> !(entity instanceof Player));
|
||||||
|
source.cancel(EntitySpawnEvent.class, (event) -> p.test(event.getEntity(), event.getLocation()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package cc.carm.lib.easylistener.defaults;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.block.BlockEvent;
|
||||||
|
import org.bukkit.event.entity.EntityEvent;
|
||||||
|
import org.bukkit.event.inventory.ClickType;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.player.PlayerEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
import org.bukkit.event.world.WorldEvent;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class EventFilters {
|
||||||
|
|
||||||
|
public <T extends Cancellable> Predicate<T> isCancelled() {
|
||||||
|
return Cancellable::isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends Cancellable> Predicate<T> notCancelled() {
|
||||||
|
return e -> !e.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends PlayerMoveEvent> Predicate<T> moveInSameBlock() {
|
||||||
|
return e -> {
|
||||||
|
if (e.getTo() == null) return false;
|
||||||
|
|
||||||
|
World fromWorld = e.getFrom().getWorld();
|
||||||
|
World toWorld = e.getTo().getWorld();
|
||||||
|
if (!Objects.equals(fromWorld, toWorld)) return false;
|
||||||
|
|
||||||
|
return e.getFrom().getBlockX() != e.getTo().getBlockX() ||
|
||||||
|
e.getFrom().getBlockZ() != e.getTo().getBlockZ() ||
|
||||||
|
e.getFrom().getBlockY() != e.getTo().getBlockY();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends PlayerInteractEvent> Predicate<T> interactAction(Action... actionType) {
|
||||||
|
return e -> Arrays.stream(actionType).anyMatch(a -> a == e.getAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends InventoryClickEvent> Predicate<T> invClickType(ClickType... clickTypes) {
|
||||||
|
return e -> Arrays.stream(clickTypes).anyMatch(a -> a == e.getClick());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends PlayerEvent> Predicate<T> playerIsOp() {
|
||||||
|
return e -> e.getPlayer().isOp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends PlayerEvent> Predicate<T> playerHasPerm(@NotNull String permission) {
|
||||||
|
return e -> e.getPlayer().hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends PlayerEvent> Predicate<T> playerInWorld(@NotNull String worldName) {
|
||||||
|
return e -> e.getPlayer().getWorld().getName().equals(worldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends EntityEvent> Predicate<T> entityOf(@NotNull EntityType type) {
|
||||||
|
return e -> e.getEntityType() == type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends WorldEvent> Predicate<T> worldOf(@NotNull String worldName) {
|
||||||
|
return e -> e.getWorld().getName().equals(worldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends BlockEvent> Predicate<T> blockOf(@NotNull Material material) {
|
||||||
|
return e -> e.getBlock().getType() == material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends BlockEvent> Predicate<T> blockInWorld(@NotNull String worldName) {
|
||||||
|
return e -> e.getBlock().getWorld().getName().equals(worldName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package cc.carm.lib.easylistener.defaults;
|
||||||
|
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class EventHandlers {
|
||||||
|
|
||||||
|
private EventHandlers() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Consumer<? extends Cancellable> SET_CANCELLED = event -> event.setCancelled(true);
|
||||||
|
public static final Consumer<? extends Cancellable> UNSET_CANCELLED = event -> event.setCancelled(false);
|
||||||
|
|
||||||
|
public static final Consumer<? extends PlayerMoveEvent> CANCEL_MOVE_BY_TELEPORT = event -> event.getPlayer().teleport(event.getFrom());
|
||||||
|
|
||||||
|
public static Consumer<? extends Cancellable> setCancelled() {
|
||||||
|
return SET_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Consumer<? extends Cancellable> unsetCancelled() {
|
||||||
|
return UNSET_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Consumer<? extends Cancellable> setCancelled(boolean cancelled) {
|
||||||
|
return cancelled ? SET_CANCELLED : UNSET_CANCELLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Consumer<? extends PlayerMoveEvent> cancelMoveByTeleport() {
|
||||||
|
return CANCEL_MOVE_BY_TELEPORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package cc.carm.lib.easylistener.handler;
|
||||||
|
|
||||||
|
import cc.carm.lib.easylistener.EasyListener;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public abstract class BaseEventHandler<T, S extends BaseEventHandler<T, S>> {
|
||||||
|
|
||||||
|
protected final @NotNull EasyListener source;
|
||||||
|
|
||||||
|
protected EventPriority priority = null;
|
||||||
|
protected boolean ignoreCancelled = false;
|
||||||
|
|
||||||
|
protected Predicate<T> predicate;
|
||||||
|
|
||||||
|
public BaseEventHandler(@NotNull EasyListener source) {
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract S getThis();
|
||||||
|
|
||||||
|
public S priority(@Nullable EventPriority priority) {
|
||||||
|
this.priority = priority;
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public S setIgnoreCancelled(boolean ignore) {
|
||||||
|
this.ignoreCancelled = ignore;
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public S acceptCancelled() {
|
||||||
|
return setIgnoreCancelled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public S ignoreCancelled() {
|
||||||
|
return setIgnoreCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public S filter(@Nullable Predicate<T> predicate) {
|
||||||
|
if (predicate == null) return getThis();
|
||||||
|
this.predicate = Optional.ofNullable(this.predicate).map(p -> p.and(predicate)).orElse(predicate);
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
package cc.carm.lib.easylistener.handler;
|
||||||
|
|
||||||
|
import cc.carm.lib.easylistener.EasyListener;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.*;
|
||||||
|
|
||||||
|
public class BundleEventHandler<T, E extends Event> {
|
||||||
|
|
||||||
|
protected final EasyListener source;
|
||||||
|
|
||||||
|
protected final Class<E> eventType;
|
||||||
|
protected final Class<T> handleClass;
|
||||||
|
protected final Map<Class<? extends E>, EventWrapper<? extends E, T>> wrappers = new HashMap<>();
|
||||||
|
|
||||||
|
protected BiPredicate<T, E> predicate;
|
||||||
|
|
||||||
|
public BundleEventHandler(EasyListener source, Class<T> handleClass, Class<E> eventType) {
|
||||||
|
this.source = source;
|
||||||
|
this.eventType = eventType;
|
||||||
|
this.handleClass = handleClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <U extends E> BundleEventHandler<T, E> from(@NotNull Class<U> eventClass,
|
||||||
|
@NotNull Function<U, T> wrapFunction) {
|
||||||
|
return from(eventClass, null, wrapFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <U extends E> BundleEventHandler<T, E> from(@NotNull Class<U> eventClass,
|
||||||
|
@Nullable EventPriority priority,
|
||||||
|
@NotNull Function<U, T> wrapFunction) {
|
||||||
|
this.wrappers.put(eventClass, new EventWrapper<>(eventClass, priority, wrapFunction));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BundleEventHandler<T, E> filter(@Nullable BiPredicate<T, E> predicate) {
|
||||||
|
if (predicate == null) return this;
|
||||||
|
|
||||||
|
this.predicate = Optional.ofNullable(this.predicate).map(p -> p.and(predicate)).orElse(predicate);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BundleEventHandler<T, E> filter(@Nullable Predicate<T> predicate) {
|
||||||
|
if (predicate == null) return this;
|
||||||
|
BiPredicate<T, E> append = (t, e) -> predicate.test(t);
|
||||||
|
this.predicate = Optional.ofNullable(this.predicate).map(p -> p.and(append)).orElse(append);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener handle(@NotNull BiConsumer<T, E> consumer) {
|
||||||
|
BiPredicate<T, E> predicate = Optional.ofNullable(this.predicate).orElse((t, e) -> true);
|
||||||
|
this.wrappers.values().forEach(wrapper -> wrapper.handle(source, predicate, consumer));
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener handle(@NotNull Consumer<T> consumer) {
|
||||||
|
return handle((t, e) -> consumer.accept(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel() {
|
||||||
|
return cancel((BiConsumer<T, E>) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel(@Nullable BiConsumer<T, E> afterCancelled) {
|
||||||
|
BiConsumer<T, E> consumer = Optional.ofNullable(afterCancelled).orElse((t, e) -> {
|
||||||
|
//Do nothing
|
||||||
|
});
|
||||||
|
this.wrappers.values().forEach(wrapper -> wrapper.cancel(source, predicate, consumer));
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel(@Nullable Consumer<T> afterCancelled) {
|
||||||
|
return cancel((t, e) -> Optional.ofNullable(afterCancelled).ifPresent(c -> c.accept(t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class EventWrapper<E extends Event, T> {
|
||||||
|
|
||||||
|
protected final @NotNull Class<E> eventClass;
|
||||||
|
protected final @NotNull Function<E, T> wrapper;
|
||||||
|
|
||||||
|
protected final EventPriority priority;
|
||||||
|
|
||||||
|
public EventWrapper(@NotNull Class<E> eventClass, EventPriority priority,
|
||||||
|
@NotNull Function<E, T> wrapper) {
|
||||||
|
this.eventClass = eventClass;
|
||||||
|
this.wrapper = wrapper;
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(@NotNull EasyListener source,
|
||||||
|
@NotNull BiPredicate<T, ? super E> predicate, @NotNull BiConsumer<T, ? super E> consumer) {
|
||||||
|
source.handle(this.eventClass, this.priority, event -> {
|
||||||
|
T wrapper = this.wrapper.apply(event);
|
||||||
|
if (predicate.test(wrapper, event)) consumer.accept(wrapper, event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel(@NotNull EasyListener source,
|
||||||
|
@NotNull BiPredicate<T, ? super E> predicate,
|
||||||
|
@NotNull BiConsumer<T, ? super E> afterCancelled) {
|
||||||
|
source.cancel(
|
||||||
|
this.eventClass, this.priority,
|
||||||
|
event -> predicate.test(this.wrapper.apply(event), event),
|
||||||
|
event -> afterCancelled.accept(this.wrapper.apply(event), event)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
package cc.carm.lib.easylistener.handler;
|
||||||
|
|
||||||
|
import cc.carm.lib.easylistener.EasyListener;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class MultiEventHandler<T extends Event> extends BaseEventHandler<T, MultiEventHandler<T>> {
|
||||||
|
|
||||||
|
protected final Class<T> eventType;
|
||||||
|
|
||||||
|
protected final Set<Class<? extends T>> eventClasses = new HashSet<>();
|
||||||
|
protected Predicate<T> eventPredicate;
|
||||||
|
|
||||||
|
public MultiEventHandler(EasyListener source, Class<T> eventType) {
|
||||||
|
super(source);
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MultiEventHandler<T> getThis() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultiEventHandler<T> from(@NotNull Class<? extends T> eventClass) {
|
||||||
|
this.eventClasses.add(eventClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener handle(@NotNull Consumer<T> eventConsumer) {
|
||||||
|
|
||||||
|
for (Class<? extends T> clazz : this.eventClasses) {
|
||||||
|
source.handle(clazz, priority, ignoreCancelled, (event) -> {
|
||||||
|
Predicate<T> predicate = Optional.ofNullable(eventPredicate).orElse(t -> true);
|
||||||
|
if (predicate.test(event)) eventConsumer.accept(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel() {
|
||||||
|
return cancel(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel(@Nullable Consumer<T> afterCancelled) {
|
||||||
|
this.eventClasses.forEach(clazz -> source.cancel(clazz, priority, eventPredicate, afterCancelled));
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package cc.carm.lib.easylistener.handler;
|
||||||
|
|
||||||
|
import cc.carm.lib.easylistener.EasyListener;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class SingleEventHandler<T extends Event> extends BaseEventHandler<T, SingleEventHandler<T>> {
|
||||||
|
|
||||||
|
protected final Class<T> eventClass;
|
||||||
|
|
||||||
|
public SingleEventHandler(EasyListener source, Class<T> eventClass) {
|
||||||
|
super(source);
|
||||||
|
this.eventClass = eventClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SingleEventHandler<T> getThis() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener handle(@NotNull Consumer<T> eventConsumer) {
|
||||||
|
return source.handle(eventClass, priority, ignoreCancelled, (event) -> {
|
||||||
|
Predicate<T> predicate = Optional.ofNullable(this.predicate).orElse(t -> true);
|
||||||
|
if (predicate.test(event)) eventConsumer.accept(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel() {
|
||||||
|
return cancel(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EasyListener cancel(@Nullable Consumer<T> afterCancelled) {
|
||||||
|
return source.cancel(eventClass, priority, predicate, afterCancelled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,21 +1,21 @@
|
|||||||
import cc.carm.lib.easylistener.EasyListener;
|
import cc.carm.lib.easylistener.EasyListener;
|
||||||
|
import cc.carm.lib.easylistener.defaults.CommonListeners;
|
||||||
|
import cc.carm.lib.easylistener.defaults.EventFilters;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
import org.bukkit.event.player.*;
|
||||||
import org.bukkit.event.player.PlayerPickupArrowEvent;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
public class DemoPlugin extends JavaPlugin {
|
public class DemoPlugin extends JavaPlugin {
|
||||||
|
|
||||||
protected final EasyListener listeners = EasyListener.create(this);
|
protected final EasyListener source = EasyListener.create(this);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
|
// 基本用法
|
||||||
listeners // 基本用法
|
source.handle(PlayerInteractAtEntityEvent.class, (event) -> {
|
||||||
.handle(PlayerInteractAtEntityEvent.class, (event) -> {
|
|
||||||
Entity clicked = event.getRightClicked();
|
Entity clicked = event.getRightClicked();
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
@ -30,16 +30,40 @@ public class DemoPlugin extends JavaPlugin {
|
|||||||
(event) -> event.getCause() != EntityDamageEvent.DamageCause.ENTITY_ATTACK
|
(event) -> event.getCause() != EntityDamageEvent.DamageCause.ENTITY_ATTACK
|
||||||
); // 有条件的取消一个事件
|
); // 有条件的取消一个事件
|
||||||
|
|
||||||
listeners // 额外提供的快捷方法
|
|
||||||
.cancelDeath(null) // 所有玩家取消死亡
|
// Functional 用法
|
||||||
.cancelBreak(player -> !player.isOp()) // 禁止非OP玩家破坏方块/接水或岩浆
|
source.handleEvent(PlayerInteractAtEntityEvent.class)
|
||||||
.cancelPlace(player -> !player.isOp()) // 禁止非OP玩家放置方块/放水或岩浆
|
.filter(e -> e.getRightClicked() instanceof Player)
|
||||||
.cancelPVP((attacker, victim) -> !attacker.isOp()) // 禁止非op玩家PVP
|
.filter(EventFilters.playerHasPerm("yc.admin"))
|
||||||
.cancelWeatherChange() // 取消天气变更
|
.handle(e -> {
|
||||||
.cancelJoinMessage() // 取消加入消息
|
Player player = e.getPlayer();
|
||||||
// .cancelQuitMessage()
|
player.sendMessage("你点了 " + e.getRightClicked().getName() + " 一下!");
|
||||||
// .handleJoinMessage(player -> "玩家 " + player.getName() + " 加入了服务器。")
|
});
|
||||||
.handleQuitMessage(player -> "玩家 " + player.getName() + " 退出了服务器。"); // 设定退出消息
|
|
||||||
|
source.handleEvents(PlayerEvent.class)
|
||||||
|
.from(PlayerJoinEvent.class)
|
||||||
|
.from(PlayerQuitEvent.class)
|
||||||
|
.filter(EventFilters.playerHasPerm("yc.admin"))
|
||||||
|
.handle(playerEvent -> System.out.println(playerEvent.getPlayer().getName()));
|
||||||
|
|
||||||
|
source.handleBundle(Player.class)
|
||||||
|
.from(PlayerJoinEvent.class, PlayerEvent::getPlayer)
|
||||||
|
.from(PlayerInteractEvent.class, PlayerEvent::getPlayer)
|
||||||
|
.filter(p -> p.hasPermission("yc.admin"))
|
||||||
|
.handle((p, e) -> p.sendMessage("hi!"));
|
||||||
|
|
||||||
|
|
||||||
|
// 预设的快捷方法
|
||||||
|
CommonListeners.cancelDeath(source, null); // 所有玩家取消死亡
|
||||||
|
CommonListeners.cancelBreak(source, player -> !player.isOp()); // 禁止非OP玩家破坏方块/接水或岩浆
|
||||||
|
CommonListeners.cancelPlace(source, player -> !player.isOp()); // 禁止非OP玩家建造方块/接水或岩浆
|
||||||
|
|
||||||
|
CommonListeners.cancelPVP(source, (attacker, victim) -> !attacker.isOp()); // 禁止非op玩家攻击别人
|
||||||
|
CommonListeners.cancelWeatherChange(source); // 取消天气变化
|
||||||
|
CommonListeners.cancelJoinMessage(source); // 取消加入消息
|
||||||
|
// CommonListeners.cancelQuitMessage(listeners);
|
||||||
|
// CommonListeners.handleJoinMessage(listeners, player -> "玩家 " + player.getName() + " 加入了服务器。");
|
||||||
|
CommonListeners.handleQuitMessage(source, player -> "玩家 " + player.getName() + " 退出了服务器。"); // 设定退出消息
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user