1
0
mirror of https://github.com/lucko/LuckPerms.git synced 2025-09-09 22:00:40 +02:00

Add extra parameter to EventBus#subscribe which allows a handler to be bound to a plugin

This commit is contained in:
Luck
2018-04-02 17:26:02 +01:00
parent c13b01da01
commit 7684ac5d3a
18 changed files with 488 additions and 41 deletions

View File

@@ -31,16 +31,20 @@ import java.util.function.Consumer;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
* The internal LuckPerms event bus. * The LuckPerms event bus.
* *
* <p>LuckPerms events are posted to any listeners registered with the bus.</p> * <p>Used to subscribe (or "listen") to LuckPerms events.</p>
* *
* @since 3.0 * @since 3.0
*/ */
public interface EventBus { public interface EventBus {
/** /**
* Subscribes to an event. * Registers a new subscription to the given event.
*
* <p>The returned {@link EventHandler} instance encapsulates the subscription state. It has
* methods which can be used to terminate the subscription, or view stats about the nature of
* the subscription.</p>
* *
* @param eventClass the event class * @param eventClass the event class
* @param handler the event handler * @param handler the event handler
@@ -48,7 +52,28 @@ public interface EventBus {
* @return an event handler instance representing this subscription * @return an event handler instance representing this subscription
*/ */
@Nonnull @Nonnull
<T extends LuckPermsEvent> EventHandler<T> subscribe(@Nonnull Class<T> eventClass, @Nonnull Consumer<T> handler); <T extends LuckPermsEvent> EventHandler<T> subscribe(@Nonnull Class<T> eventClass, @Nonnull Consumer<? super T> handler);
/**
* Registers a new subscription to the given event.
*
* <p>The returned {@link EventHandler} instance encapsulates the subscription state. It has
* methods which can be used to terminate the subscription, or view stats about the nature of
* the subscription.</p>
*
* <p>Unlike {@link #subscribe(Class, Consumer)}, this method accepts an additional parameter
* for {@code plugin}. This object must be a "plugin" instance on the platform, and is used to
* automatically {@link EventHandler#unregister() unregister} the subscription when the
* corresponding plugin is disabled.</p>
*
* @param <T> the event class
* @param plugin a plugin instance to bind the subscription to.
* @param eventClass the event class
* @param handler the event handler
* @return an event handler instance representing this subscription
*/
@Nonnull
<T extends LuckPermsEvent> EventHandler<T> subscribe(Object plugin, @Nonnull Class<T> eventClass, @Nonnull Consumer<? super T> handler);
/** /**
* Gets a set of all registered handlers for a given event. * Gets a set of all registered handlers for a given event.

View File

@@ -30,7 +30,7 @@ import java.util.function.Consumer;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
/** /**
* Represents a handler for a LuckPerms event * Represents a subscription to a {@link LuckPermsEvent}.
* *
* @param <T> the event class * @param <T> the event class
*/ */
@@ -64,7 +64,7 @@ public interface EventHandler<T extends LuckPermsEvent> extends AutoCloseable {
* @return the event consumer * @return the event consumer
*/ */
@Nonnull @Nonnull
Consumer<T> getConsumer(); Consumer<? super T> getConsumer();
/** /**
* Gets the number of times this handler has been called * Gets the number of times this handler has been called

View File

@@ -45,7 +45,7 @@ public class BukkitCommandExecutor extends CommandManager implements CommandExec
private final LPBukkitPlugin plugin; private final LPBukkitPlugin plugin;
BukkitCommandExecutor(LPBukkitPlugin plugin) { public BukkitCommandExecutor(LPBukkitPlugin plugin) {
super(plugin); super(plugin);
this.plugin = plugin; this.plugin = plugin;
} }

View File

@@ -0,0 +1,60 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bukkit;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.event.AbstractEventBus;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin;
public class BukkitEventBus extends AbstractEventBus<Plugin> implements Listener {
public BukkitEventBus(LPBukkitPlugin plugin, LuckPermsApiProvider apiProvider) {
super(plugin, apiProvider);
// register listener
LPBukkitBootstrap bootstrap = plugin.getBootstrap();
bootstrap.getServer().getPluginManager().registerEvents(this, bootstrap);
}
@Override
protected Plugin checkPlugin(Object plugin) throws IllegalArgumentException {
if (plugin instanceof Plugin) {
return (Plugin) plugin;
}
throw new IllegalArgumentException("Object " + plugin + " (" + plugin.getClass().getName() + ") is not a plugin.");
}
@EventHandler
public void onPluginDisable(PluginDisableEvent e) {
Plugin plugin = e.getPlugin();
unregisterHandlers(plugin);
}
}

View File

@@ -43,11 +43,13 @@ import me.lucko.luckperms.bukkit.model.server.LPDefaultsMap;
import me.lucko.luckperms.bukkit.model.server.LPPermissionMap; import me.lucko.luckperms.bukkit.model.server.LPPermissionMap;
import me.lucko.luckperms.bukkit.model.server.LPSubscriptionMap; import me.lucko.luckperms.bukkit.model.server.LPSubscriptionMap;
import me.lucko.luckperms.bukkit.vault.VaultHookManager; import me.lucko.luckperms.bukkit.vault.VaultHookManager;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory; import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory;
import me.lucko.luckperms.common.command.access.CommandPermission; import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.listener.ConnectionListener; import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.managers.group.StandardGroupManager; import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
@@ -171,6 +173,11 @@ public class LPBukkitPlugin extends AbstractLuckPermsPlugin {
tryVaultHook(false); tryVaultHook(false);
} }
@Override
protected AbstractEventBus provideEventBus(LuckPermsApiProvider apiProvider) {
return new BukkitEventBus(this, apiProvider);
}
public void tryVaultHook(boolean force) { public void tryVaultHook(boolean force) {
if (this.vaultHookManager != null) { if (this.vaultHookManager != null) {
return; // already hooked return; // already hooked

View File

@@ -45,7 +45,7 @@ public class BungeeCommandExecutor extends Command implements TabExecutor {
private final LPBungeePlugin plugin; private final LPBungeePlugin plugin;
private final CommandManager manager; private final CommandManager manager;
BungeeCommandExecutor(LPBungeePlugin plugin, CommandManager manager) { public BungeeCommandExecutor(LPBungeePlugin plugin, CommandManager manager) {
super("luckpermsbungee", null, "lpb", "bperm", "bperms", "bpermission", "bpermissions"); super("luckpermsbungee", null, "lpb", "bperm", "bperms", "bpermission", "bpermissions");
this.plugin = plugin; this.plugin = plugin;
this.manager = manager; this.manager = manager;

View File

@@ -0,0 +1,97 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.bungee;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.event.AbstractEventBus;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
public class BungeeEventBus extends AbstractEventBus<Plugin> implements Listener {
private final LPBungeeBootstrap bootstrap;
public BungeeEventBus(LPBungeePlugin plugin, LuckPermsApiProvider apiProvider) {
super(plugin, apiProvider);
this.bootstrap = plugin.getBootstrap();
}
@Override
protected Plugin checkPlugin(Object plugin) throws IllegalArgumentException {
if (plugin instanceof Plugin) {
Plugin bungeePlugin = (Plugin) plugin;
// add a custom log handler to effectively listen for the plugin being disabled.
// BungeeCord doesn't really support enabling/disabling plugins at runtime, and as
// such doesn't have a PluginDisableEvent. However, some plugins do exist to reload
// plugins at runtime. We rely on these plugins following the BungeeCord behaviour,
// and #close ing the plugins logger, so we can unregister the listeners. :)
Handler[] handlers = bungeePlugin.getLogger().getHandlers();
for (Handler handler : handlers) {
if (handler instanceof UnloadHookLoggerHandler) {
return bungeePlugin;
}
}
bungeePlugin.getLogger().addHandler(new UnloadHookLoggerHandler(bungeePlugin));
return bungeePlugin;
}
throw new IllegalArgumentException("Object " + plugin + " (" + plugin.getClass().getName() + ") is not a plugin.");
}
@Override
public void close() {
for (Plugin plugin : this.bootstrap.getProxy().getPluginManager().getPlugins()) {
for (Handler handler : plugin.getLogger().getHandlers()) {
if (handler instanceof UnloadHookLoggerHandler) {
plugin.getLogger().removeHandler(handler);
}
}
}
super.close();
}
private final class UnloadHookLoggerHandler extends Handler {
private final Plugin plugin;
private UnloadHookLoggerHandler(Plugin plugin) {
this.plugin = plugin;
}
@Override
public void close() {
unregisterHandlers(this.plugin);
}
@Override public void publish(LogRecord record) {}
@Override public void flush() {}
}
}

View File

@@ -34,10 +34,12 @@ import me.lucko.luckperms.bungee.contexts.RedisBungeeCalculator;
import me.lucko.luckperms.bungee.listeners.BungeeConnectionListener; import me.lucko.luckperms.bungee.listeners.BungeeConnectionListener;
import me.lucko.luckperms.bungee.listeners.BungeePermissionCheckListener; import me.lucko.luckperms.bungee.listeners.BungeePermissionCheckListener;
import me.lucko.luckperms.bungee.messaging.BungeeMessagingFactory; import me.lucko.luckperms.bungee.messaging.BungeeMessagingFactory;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory; import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory;
import me.lucko.luckperms.common.command.CommandManager; import me.lucko.luckperms.common.command.CommandManager;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.listener.ConnectionListener; import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.managers.group.StandardGroupManager; import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
@@ -139,6 +141,11 @@ public class LPBungeePlugin extends AbstractLuckPermsPlugin {
} }
@Override
protected AbstractEventBus provideEventBus(LuckPermsApiProvider apiProvider) {
return new BungeeEventBus(this, apiProvider);
}
@Override @Override
protected void registerApiOnPlatform(LuckPermsApi api) { protected void registerApiOnPlatform(LuckPermsApi api) {
// BungeeCord doesn't have a services manager // BungeeCord doesn't have a services manager

View File

@@ -39,6 +39,7 @@ import me.lucko.luckperms.api.event.LuckPermsEvent;
import me.lucko.luckperms.common.api.LuckPermsApiProvider; import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -51,7 +52,7 @@ import javax.annotation.Nonnull;
/** /**
* Simple implementation of EventBus. * Simple implementation of EventBus.
*/ */
public class LuckPermsEventBus implements EventBus { public abstract class AbstractEventBus<P> implements EventBus, AutoCloseable {
/** /**
* The plugin instance * The plugin instance
@@ -77,7 +78,7 @@ public class LuckPermsEventBus implements EventBus {
private final LoadingCache<Class<? extends LuckPermsEvent>, List<LuckPermsEventHandler<?>>> handlerCache = Caffeine.newBuilder() private final LoadingCache<Class<? extends LuckPermsEvent>, List<LuckPermsEventHandler<?>>> handlerCache = Caffeine.newBuilder()
.build(eventClass -> { .build(eventClass -> {
ImmutableList.Builder<LuckPermsEventHandler<?>> matched = ImmutableList.builder(); ImmutableList.Builder<LuckPermsEventHandler<?>> matched = ImmutableList.builder();
LuckPermsEventBus.this.handlerMap.asMap().forEach((clazz, handlers) -> { AbstractEventBus.this.handlerMap.asMap().forEach((clazz, handlers) -> {
if (clazz.isAssignableFrom(eventClass)) { if (clazz.isAssignableFrom(eventClass)) {
matched.addAll(handlers); matched.addAll(handlers);
} }
@@ -85,29 +86,30 @@ public class LuckPermsEventBus implements EventBus {
return matched.build(); return matched.build();
}); });
public LuckPermsEventBus(LuckPermsPlugin plugin, LuckPermsApiProvider apiProvider) { protected AbstractEventBus(LuckPermsPlugin plugin, LuckPermsApiProvider apiProvider) {
this.plugin = plugin; this.plugin = plugin;
this.apiProvider = apiProvider; this.apiProvider = apiProvider;
} }
public LuckPermsPlugin getPlugin() {
return this.plugin;
}
@Nonnull @Nonnull
@Override @Override
public <T extends LuckPermsEvent> EventHandler<T> subscribe(@Nonnull Class<T> eventClass, @Nonnull Consumer<T> handler) { public <T extends LuckPermsEvent> EventHandler<T> subscribe(@Nonnull Class<T> eventClass, @Nonnull Consumer<? super T> handler) {
Objects.requireNonNull(eventClass, "eventClass"); Objects.requireNonNull(eventClass, "eventClass");
Objects.requireNonNull(handler, "handler"); Objects.requireNonNull(handler, "handler");
return registerSubscription(eventClass, handler, null);
if (!eventClass.isInterface()) {
throw new IllegalArgumentException("class " + eventClass + " is not an interface");
}
if (!LuckPermsEvent.class.isAssignableFrom(eventClass)) {
throw new IllegalArgumentException("class " + eventClass.getName() + " does not implement LuckPermsEvent");
} }
LuckPermsEventHandler<T> eventHandler = new LuckPermsEventHandler<>(this, eventClass, handler); @Nonnull
this.handlerMap.put(eventClass, eventHandler); @Override
this.handlerCache.invalidateAll(); public <T extends LuckPermsEvent> EventHandler<T> subscribe(Object plugin, @Nonnull Class<T> eventClass, @Nonnull Consumer<? super T> handler) {
Objects.requireNonNull(plugin, "plugin");
return eventHandler; Objects.requireNonNull(eventClass, "eventClass");
Objects.requireNonNull(handler, "handler");
return registerSubscription(eventClass, handler, checkPlugin(plugin));
} }
@Nonnull @Nonnull
@@ -122,11 +124,79 @@ public class LuckPermsEventBus implements EventBus {
return ret.build(); return ret.build();
} }
/**
* Checks that the given plugin object is a valid plugin instance for the platform
*
* @param plugin the object
* @return a plugin
* @throws IllegalArgumentException if the plugin is invalid
*/
protected abstract P checkPlugin(Object plugin) throws IllegalArgumentException;
/**
* Registers a subscription for the given class, handler and plugin
*
* @param eventClass the event class
* @param handler the handler
* @param plugin the plugin, nullable
* @param <T> the event type
* @return the resultant handler
*/
private <T extends LuckPermsEvent> EventHandler<T> registerSubscription(Class<T> eventClass, Consumer<? super T> handler, Object plugin) {
if (!eventClass.isInterface()) {
throw new IllegalArgumentException("class " + eventClass + " is not an interface");
}
if (!LuckPermsEvent.class.isAssignableFrom(eventClass)) {
throw new IllegalArgumentException("class " + eventClass.getName() + " does not implement LuckPermsEvent");
}
LuckPermsEventHandler<T> eventHandler = new LuckPermsEventHandler<>(this, eventClass, handler, plugin);
this.handlerMap.put(eventClass, eventHandler);
this.handlerCache.invalidateAll();
return eventHandler;
}
/**
* Removes a specific handler from the bus
*
* @param handler the handler to remove
*/
public void unregisterHandler(LuckPermsEventHandler<?> handler) { public void unregisterHandler(LuckPermsEventHandler<?> handler) {
this.handlerMap.remove(handler.getEventClass(), handler); this.handlerMap.remove(handler.getEventClass(), handler);
this.handlerCache.invalidateAll(); this.handlerCache.invalidateAll();
} }
/**
* Removes all handlers for a specific plugin
*
* @param plugin the plugin
*/
protected void unregisterHandlers(P plugin) {
List<LuckPermsEventHandler<?>> handlers = new ArrayList<>(this.handlerMap.values());
for (LuckPermsEventHandler<?> handler : handlers) {
if (handler.getPlugin() == plugin) {
handler.unregister();
}
}
}
/**
* Unregisters all handlers in this event bus
*/
@Override
public void close() {
List<LuckPermsEventHandler<?>> handlers = new ArrayList<>(this.handlerMap.values());
for (LuckPermsEventHandler<?> handler : handlers) {
handler.unregister();
}
}
/**
* Fires the given event to all registered handlers in this event bus
*
* @param event the event to fire
*/
public void fireEvent(LuckPermsEvent event) { public void fireEvent(LuckPermsEvent event) {
if (event instanceof AbstractEvent) { if (event instanceof AbstractEvent) {
((AbstractEvent) event).setApi(this.apiProvider); ((AbstractEvent) event).setApi(this.apiProvider);
@@ -142,14 +212,15 @@ public class LuckPermsEventBus implements EventBus {
} }
} }
/**
* Fires the given event asynchronously to all registered handlers in this event bus
*
* @param event the event to fire
*/
public void fireEventAsync(LuckPermsEvent event) { public void fireEventAsync(LuckPermsEvent event) {
if (event instanceof Cancellable) { if (event instanceof Cancellable) {
throw new IllegalArgumentException("cannot call Cancellable event async"); throw new IllegalArgumentException("cannot call Cancellable event async");
} }
this.plugin.getBootstrap().getScheduler().doAsync(() -> fireEvent(event)); this.plugin.getBootstrap().getScheduler().doAsync(() -> fireEvent(event));
} }
public LuckPermsPlugin getPlugin() {
return this.plugin;
}
} }

View File

@@ -37,7 +37,6 @@ import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause; import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.api.event.log.LogBroadcastEvent; import me.lucko.luckperms.api.event.log.LogBroadcastEvent;
import me.lucko.luckperms.api.event.log.LogNotifyEvent; import me.lucko.luckperms.api.event.log.LogNotifyEvent;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.api.delegates.model.ApiPermissionHolder; import me.lucko.luckperms.common.api.delegates.model.ApiPermissionHolder;
import me.lucko.luckperms.common.api.delegates.model.ApiUser; import me.lucko.luckperms.common.api.delegates.model.ApiUser;
import me.lucko.luckperms.common.event.impl.EventConfigReload; import me.lucko.luckperms.common.event.impl.EventConfigReload;
@@ -78,7 +77,6 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender; import me.lucko.luckperms.common.sender.Sender;
import java.util.Collection; import java.util.Collection;
@@ -87,13 +85,13 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public final class EventFactory { public final class EventFactory {
private final LuckPermsEventBus eventBus; private final AbstractEventBus eventBus;
public EventFactory(LuckPermsPlugin plugin, LuckPermsApiProvider apiProvider) { public EventFactory(AbstractEventBus eventBus) {
this.eventBus = new LuckPermsEventBus(plugin, apiProvider); this.eventBus = eventBus;
} }
public LuckPermsEventBus getEventBus() { public AbstractEventBus getEventBus() {
return this.eventBus; return this.eventBus;
} }

View File

@@ -33,21 +33,51 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Simple implementation of {@link EventHandler}.
*
* @param <T> the event type
*/
public class LuckPermsEventHandler<T extends LuckPermsEvent> implements EventHandler<T> { public class LuckPermsEventHandler<T extends LuckPermsEvent> implements EventHandler<T> {
private final LuckPermsEventBus eventBus;
/**
* The event bus which created this handler
*/
private final AbstractEventBus<?> eventBus;
/**
* The event class
*/
private final Class<T> eventClass; private final Class<T> eventClass;
private final Consumer<T> consumer; /**
* The delegate "event handler"
*/
private final Consumer<? super T> consumer;
/**
* The plugin which "owns" this handler
*/
@Nullable
private final Object plugin;
/**
* If this handler is active
*/
private final AtomicBoolean active = new AtomicBoolean(true); private final AtomicBoolean active = new AtomicBoolean(true);
/**
* How many times this handler has been called
*/
private final AtomicInteger callCount = new AtomicInteger(0); private final AtomicInteger callCount = new AtomicInteger(0);
public LuckPermsEventHandler(LuckPermsEventBus eventBus, Class<T> eventClass, Consumer<T> consumer) { public LuckPermsEventHandler(AbstractEventBus<?> eventBus, Class<T> eventClass, Consumer<? super T> consumer, @Nullable Object plugin) {
this.eventBus = eventBus; this.eventBus = eventBus;
this.eventClass = eventClass; this.eventClass = eventClass;
this.consumer = consumer; this.consumer = consumer;
this.plugin = plugin;
} }
@Override @Override
@@ -91,7 +121,12 @@ public class LuckPermsEventHandler<T extends LuckPermsEvent> implements EventHan
@Nonnull @Nonnull
@Override @Override
public Consumer<T> getConsumer() { public Consumer<? super T> getConsumer() {
return this.consumer; return this.consumer;
} }
@Nullable
public Object getPlugin() {
return this.plugin;
}
} }

View File

@@ -41,6 +41,7 @@ import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.LuckPermsCalculator; import me.lucko.luckperms.common.contexts.LuckPermsCalculator;
import me.lucko.luckperms.common.dependencies.DependencyManager; import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.dependencies.DependencyRegistry; import me.lucko.luckperms.common.dependencies.DependencyRegistry;
import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.event.EventFactory; import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.inheritance.InheritanceHandler; import me.lucko.luckperms.common.inheritance.InheritanceHandler;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
@@ -160,7 +161,7 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
// register with the LP API // register with the LP API
this.apiProvider = new LuckPermsApiProvider(this); this.apiProvider = new LuckPermsApiProvider(this);
this.eventFactory = new EventFactory(this, this.apiProvider); this.eventFactory = new EventFactory(provideEventBus(this.apiProvider));
ApiRegistrationUtil.registerProvider(this.apiProvider); ApiRegistrationUtil.registerProvider(this.apiProvider);
registerApiOnPlatform(this.apiProvider); registerApiOnPlatform(this.apiProvider);
@@ -234,6 +235,7 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
protected abstract PlatformCalculatorFactory provideCalculatorFactory(); protected abstract PlatformCalculatorFactory provideCalculatorFactory();
protected abstract void setupContextManager(); protected abstract void setupContextManager();
protected abstract void setupPlatformHooks(); protected abstract void setupPlatformHooks();
protected abstract AbstractEventBus provideEventBus(LuckPermsApiProvider apiProvider);
protected abstract void registerApiOnPlatform(LuckPermsApi api); protected abstract void registerApiOnPlatform(LuckPermsApi api);
protected abstract void registerHousekeepingTasks(); protected abstract void registerHousekeepingTasks();
protected abstract void performFinalSetup(); protected abstract void performFinalSetup();

View File

@@ -27,11 +27,13 @@ package me.lucko.luckperms.nukkit;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory; import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory;
import me.lucko.luckperms.common.command.access.CommandPermission; import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.listener.ConnectionListener; import me.lucko.luckperms.common.listener.ConnectionListener;
import me.lucko.luckperms.common.managers.group.StandardGroupManager; import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
@@ -162,6 +164,11 @@ public class LPNukkitPlugin extends AbstractLuckPermsPlugin {
} }
} }
@Override
protected AbstractEventBus provideEventBus(LuckPermsApiProvider apiProvider) {
return new NukkitEventBus(this, apiProvider);
}
@Override @Override
protected void registerApiOnPlatform(LuckPermsApi api) { protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getServer().getServiceManager().register(LuckPermsApi.class, api, this.bootstrap, ServicePriority.NORMAL); this.bootstrap.getServer().getServiceManager().register(LuckPermsApi.class, api, this.bootstrap, ServicePriority.NORMAL);

View File

@@ -38,7 +38,7 @@ import java.util.Arrays;
public class NukkitCommandExecutor extends CommandManager implements CommandExecutor { public class NukkitCommandExecutor extends CommandManager implements CommandExecutor {
private final LPNukkitPlugin plugin; private final LPNukkitPlugin plugin;
NukkitCommandExecutor(LPNukkitPlugin plugin) { public NukkitCommandExecutor(LPNukkitPlugin plugin) {
super(plugin); super(plugin);
this.plugin = plugin; this.plugin = plugin;
} }

View File

@@ -0,0 +1,60 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.nukkit;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.event.AbstractEventBus;
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.Listener;
import cn.nukkit.event.plugin.PluginDisableEvent;
import cn.nukkit.plugin.Plugin;
public class NukkitEventBus extends AbstractEventBus<Plugin> implements Listener {
public NukkitEventBus(LPNukkitPlugin plugin, LuckPermsApiProvider apiProvider) {
super(plugin, apiProvider);
// register listener
LPNukkitBootstrap bootstrap = plugin.getBootstrap();
bootstrap.getServer().getPluginManager().registerEvents(this, bootstrap);
}
@Override
protected Plugin checkPlugin(Object plugin) throws IllegalArgumentException {
if (plugin instanceof Plugin) {
return (Plugin) plugin;
}
throw new IllegalArgumentException("Object " + plugin + " (" + plugin.getClass().getName() + ") is not a plugin.");
}
@EventHandler
public void onPluginDisable(PluginDisableEvent e) {
Plugin plugin = e.getPlugin();
unregisterHandlers(plugin);
}
}

View File

@@ -27,12 +27,14 @@ package me.lucko.luckperms.sponge;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory; import me.lucko.luckperms.common.calculators.PlatformCalculatorFactory;
import me.lucko.luckperms.common.command.CommandManager; import me.lucko.luckperms.common.command.CommandManager;
import me.lucko.luckperms.common.command.abstraction.Command; import me.lucko.luckperms.common.command.abstraction.Command;
import me.lucko.luckperms.common.command.access.CommandPermission; import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter; import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.event.AbstractEventBus;
import me.lucko.luckperms.common.managers.track.StandardTrackManager; import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.messaging.MessagingFactory; import me.lucko.luckperms.common.messaging.MessagingFactory;
import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.model.User;
@@ -159,6 +161,11 @@ public class LPSpongePlugin extends AbstractLuckPermsPlugin {
} }
} }
@Override
protected AbstractEventBus provideEventBus(LuckPermsApiProvider apiProvider) {
return new SpongeEventBus(this, apiProvider);
}
@Override @Override
protected void registerApiOnPlatform(LuckPermsApi api) { protected void registerApiOnPlatform(LuckPermsApi api) {
this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LuckPermsApi.class, api); this.bootstrap.getGame().getServiceManager().setProvider(this.bootstrap, LuckPermsApi.class, api);

View File

@@ -52,7 +52,7 @@ public class SpongeCommandExecutor extends CommandManager implements CommandCall
private final LPSpongePlugin plugin; private final LPSpongePlugin plugin;
SpongeCommandExecutor(LPSpongePlugin plugin) { public SpongeCommandExecutor(LPSpongePlugin plugin) {
super(plugin); super(plugin);
this.plugin = plugin; this.plugin = plugin;
} }

View File

@@ -0,0 +1,71 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.sponge;
import me.lucko.luckperms.common.api.LuckPermsApiProvider;
import me.lucko.luckperms.common.event.AbstractEventBus;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.game.GameReloadEvent;
import org.spongepowered.api.plugin.PluginContainer;
public class SpongeEventBus extends AbstractEventBus<PluginContainer> {
public SpongeEventBus(LPSpongePlugin plugin, LuckPermsApiProvider apiProvider) {
super(plugin, apiProvider);
// register listener
LPSpongeBootstrap bootstrap = plugin.getBootstrap();
bootstrap.getGame().getEventManager().registerListeners(bootstrap, this);
}
@Override
protected PluginContainer checkPlugin(Object plugin) throws IllegalArgumentException {
if (plugin instanceof PluginContainer) {
return (PluginContainer) plugin;
}
PluginContainer pluginContainer = Sponge.getPluginManager().fromInstance(plugin).orElse(null);
if (pluginContainer != null) {
return pluginContainer;
}
throw new IllegalArgumentException("Object " + plugin + " (" + plugin.getClass().getName() + ") is not a plugin.");
}
@Listener
public void onReload(GameReloadEvent e) {
// sponge doesn't really support unloading of plugins at runtime.
// this probably won't ever work/be useful, but I suppose it's worth a try.
PluginContainer pluginContainer = e.getContext().get(EventContextKeys.PLUGIN).orElse(null);
if (pluginContainer == null) {
return;
}
unregisterHandlers(pluginContainer);
}
}