Allow plugins to register session handlers.

This commit is contained in:
wizjany 2015-08-02 04:42:10 -04:00
parent 43a9228304
commit cde9a403f7
16 changed files with 187 additions and 15 deletions

View File

@ -24,7 +24,22 @@
import com.sk89q.guavabackport.cache.LoadingCache;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.session.handler.*;
import com.sk89q.worldguard.session.handler.EntryFlag;
import com.sk89q.worldguard.session.handler.ExitFlag;
import com.sk89q.worldguard.session.handler.FarewellFlag;
import com.sk89q.worldguard.session.handler.FeedFlag;
import com.sk89q.worldguard.session.handler.GameModeFlag;
import com.sk89q.worldguard.session.handler.GodMode;
import com.sk89q.worldguard.session.handler.GreetingFlag;
import com.sk89q.worldguard.session.handler.Handler;
import com.sk89q.worldguard.session.handler.Handler.Factory;
import com.sk89q.worldguard.session.handler.HealFlag;
import com.sk89q.worldguard.session.handler.InvincibilityFlag;
import com.sk89q.worldguard.session.handler.NotifyEntryFlag;
import com.sk89q.worldguard.session.handler.NotifyExitFlag;
import com.sk89q.worldguard.session.handler.TimeLockFlag;
import com.sk89q.worldguard.session.handler.WaterBreathing;
import com.sk89q.worldguard.session.handler.WeatherLockFlag;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -34,6 +49,7 @@
import javax.annotation.Nullable;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.LinkedList;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -77,6 +93,7 @@ public Session load(CacheKey key) throws Exception {
public SessionManager(WorldGuardPlugin plugin) {
checkNotNull(plugin, "plugin");
this.plugin = plugin;
registerDefaultHandlers();
}
/**
@ -129,6 +146,56 @@ public void resetState(Player player) {
}
}
private LinkedList<Factory<? extends Handler>> handlers = new LinkedList<Factory<? extends Handler>>();
private void registerDefaultHandlers() {
// our list shouldn't be getting concurrently modified
// so we can safely order by providing null for 'after'
registerHandler(HealFlag.FACTORY, null);
registerHandler(FeedFlag.FACTORY, null);
registerHandler(NotifyEntryFlag.FACTORY, null);
registerHandler(NotifyExitFlag.FACTORY, null);
registerHandler(EntryFlag.FACTORY, null);
registerHandler(ExitFlag.FACTORY, null);
registerHandler(FarewellFlag.FACTORY, null);
registerHandler(GreetingFlag.FACTORY, null);
registerHandler(GameModeFlag.FACTORY, null);
registerHandler(InvincibilityFlag.FACTORY, null);
registerHandler(TimeLockFlag.FACTORY, null);
registerHandler(WeatherLockFlag.FACTORY, null);
registerHandler(GodMode.FACTORY, null);
registerHandler(WaterBreathing.FACTORY, null);
}
/**
* Register a handler with the SessionManager.
*
* You may specify another handler class to ensure your handler is always registered after that class.
* If that class is not already registered, this method will return false.
*
* For example, flags that always act on a player in a region (like {@link HealFlag} and {@link FeedFlag})
* should be registered earlier, whereas flags that only take effect when a player leaves the region (like
* {@link FarewellFlag} and {@link GreetingFlag}) should be registered after the {@link ExitFlag.Factory}.class handler factory.
*
* @param factory a factory which takes a session and returns an instance of your handler
* @param after the handler factory to insert the first handler after, to ensure a specific order when creating new sessions
*
* @return {@code true} (as specified by {@link Collection#add})
* {@code false} if {@param after} is not registered
*/
public boolean registerHandler(Factory<? extends Handler> factory, @Nullable Factory<? extends Handler> after) {
if (factory == null) return false;
if (after == null) {
handlers.add(factory);
} else {
int index = handlers.indexOf(after);
if (index == -1) return false;
handlers.add(index, factory); // shifts "after" right one, and everything after "after" right one
}
return true;
}
/**
* Create a session for a player.
*
@ -137,20 +204,9 @@ public void resetState(Player player) {
*/
private Session createSession(Player player) {
Session session = new Session(this);
session.register(new HealFlag(session));
session.register(new FeedFlag(session));
session.register(new NotifyEntryFlag(session));
session.register(new NotifyExitFlag(session));
session.register(new EntryFlag(session));
session.register(new ExitFlag(session));
session.register(new FarewellFlag(session));
session.register(new GreetingFlag(session));
session.register(new GameModeFlag(session));
session.register(new InvincibilityFlag(session));
session.register(new TimeLockFlag(session));
session.register(new WeatherLockFlag(session));
session.register(new GodMode(session));
session.register(new WaterBreathing(session));
for (Factory<? extends Handler> factory : handlers) {
session.register(factory.create(session));
}
session.initialize(player);
return session;
}

View File

@ -33,6 +33,14 @@
public class EntryFlag extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<EntryFlag> {
@Override
public EntryFlag create(Session session) {
return new EntryFlag(session);
}
}
private static final long MESSAGE_THRESHOLD = 1000 * 2;
private long lastMessage;

View File

@ -32,6 +32,14 @@
public class ExitFlag extends FlagValueChangeHandler<State> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<ExitFlag> {
@Override
public ExitFlag create(Session session) {
return new ExitFlag(session);
}
}
private static final long MESSAGE_THRESHOLD = 1000 * 2;
private String storedMessage;
private boolean exitViaTeleport = false;

View File

@ -34,6 +34,14 @@
public class FarewellFlag extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<FarewellFlag> {
@Override
public FarewellFlag create(Session session) {
return new FarewellFlag(session);
}
}
private Set<String> lastMessageStack = Collections.emptySet();
public FarewellFlag(Session session) {

View File

@ -28,6 +28,14 @@
public class FeedFlag extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<FeedFlag> {
@Override
public FeedFlag create(Session session) {
return new FeedFlag(session);
}
}
private long lastFeed = 0;
public FeedFlag(Session session) {

View File

@ -32,6 +32,14 @@
public class GameModeFlag extends FlagValueChangeHandler<GameMode> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<GameModeFlag> {
@Override
public GameModeFlag create(Session session) {
return new GameModeFlag(session);
}
}
private GameMode originalGameMode;
private GameMode setGameMode;

View File

@ -29,6 +29,14 @@
public class GodMode extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<GodMode> {
@Override
public GodMode create(Session session) {
return new GodMode(session);
}
}
private boolean godMode;
public GodMode(Session session) {

View File

@ -35,6 +35,14 @@
public class GreetingFlag extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<GreetingFlag> {
@Override
public GreetingFlag create(Session session) {
return new GreetingFlag(session);
}
}
private Set<String> lastMessageStack = Collections.emptySet();
public GreetingFlag(Session session) {

View File

@ -39,6 +39,10 @@
*/
public abstract class Handler {
public static abstract class Factory<T extends Handler> {
public abstract T create(Session session);
}
private final Session session;
/**

View File

@ -28,6 +28,14 @@
public class HealFlag extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<HealFlag> {
@Override
public HealFlag create(Session session) {
return new HealFlag(session);
}
}
private long lastHeal = 0;
public HealFlag(Session session) {

View File

@ -31,6 +31,14 @@
public class InvincibilityFlag extends FlagValueChangeHandler<State> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<InvincibilityFlag> {
@Override
public InvincibilityFlag create(Session session) {
return new InvincibilityFlag(session);
}
}
@Nullable
private State invincibility;

View File

@ -30,6 +30,14 @@
public class NotifyEntryFlag extends FlagValueChangeHandler<Boolean> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<NotifyEntryFlag> {
@Override
public NotifyEntryFlag create(Session session) {
return new NotifyEntryFlag(session);
}
}
public NotifyEntryFlag(Session session) {
super(session, DefaultFlag.NOTIFY_ENTER);
}

View File

@ -29,6 +29,14 @@
public class NotifyExitFlag extends FlagValueChangeHandler<Boolean> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<NotifyExitFlag> {
@Override
public NotifyExitFlag create(Session session) {
return new NotifyExitFlag(session);
}
}
private Boolean notifiedForLeave = false;
public NotifyExitFlag(Session session) {

View File

@ -31,6 +31,14 @@
public class TimeLockFlag extends FlagValueChangeHandler<String> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<TimeLockFlag> {
@Override
public TimeLockFlag create(Session session) {
return new TimeLockFlag(session);
}
}
private Long initialTime;
private boolean initialRelative;

View File

@ -24,6 +24,14 @@
public class WaterBreathing extends Handler {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<WaterBreathing> {
@Override
public WaterBreathing create(Session session) {
return new WaterBreathing(session);
}
}
public boolean waterBreathing;
public WaterBreathing(Session session) {

View File

@ -31,6 +31,14 @@
public class WeatherLockFlag extends FlagValueChangeHandler<WeatherType> {
public static final Factory FACTORY = new Factory();
public static class Factory extends Handler.Factory<WeatherLockFlag> {
@Override
public WeatherLockFlag create(Session session) {
return new WeatherLockFlag(session);
}
}
private WeatherType initialWeather;
public WeatherLockFlag(Session session) {