Listeners name refactor + Fix #831 for both Spigot and CraftBukkit

This commit is contained in:
Gabriele C 2016-08-03 01:02:25 +02:00
parent bff99902b0
commit 75421fd156
16 changed files with 167 additions and 41 deletions

View File

@ -20,12 +20,14 @@ import fr.xephi.authme.hooks.BungeeCordMessage;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.MetricsStarter;
import fr.xephi.authme.listener.AuthMeBlockListener;
import fr.xephi.authme.listener.AuthMeEntityListener;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.listener.AuthMePlayerListener16;
import fr.xephi.authme.listener.AuthMePlayerListener18;
import fr.xephi.authme.listener.AuthMeServerListener;
import fr.xephi.authme.listener.AsyncSingleSessionListener;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.listener.EntityListener;
import fr.xephi.authme.listener.PlayerListener;
import fr.xephi.authme.listener.PlayerListener16;
import fr.xephi.authme.listener.PlayerListener18;
import fr.xephi.authme.listener.ServerListener;
import fr.xephi.authme.listener.SyncSingleSessionListener;
import fr.xephi.authme.output.ConsoleFilter;
import fr.xephi.authme.output.Log4JFilter;
import fr.xephi.authme.output.MessageKey;
@ -53,6 +55,8 @@ import fr.xephi.authme.util.MigrationService;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.ValidationService;
import tools.utils.ServerUtils;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -316,24 +320,31 @@ public class AuthMe extends JavaPlugin {
PluginManager pluginManager = getServer().getPluginManager();
// Register event listeners
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener.class), this);
pluginManager.registerEvents(injector.getSingleton(AuthMeBlockListener.class), this);
pluginManager.registerEvents(injector.getSingleton(AuthMeEntityListener.class), this);
pluginManager.registerEvents(injector.getSingleton(AuthMeServerListener.class), this);
pluginManager.registerEvents(injector.getSingleton(PlayerListener.class), this);
pluginManager.registerEvents(injector.getSingleton(BlockListener.class), this);
pluginManager.registerEvents(injector.getSingleton(EntityListener.class), this);
pluginManager.registerEvents(injector.getSingleton(ServerListener.class), this);
// Try to register 1.6 player listeners
try {
Class.forName("org.bukkit.event.player.PlayerEditBookEvent");
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener16.class), this);
pluginManager.registerEvents(injector.getSingleton(PlayerListener16.class), this);
} catch (ClassNotFoundException ignore) {
}
// Try to register 1.8 player listeners
try {
Class.forName("org.bukkit.event.player.PlayerInteractAtEntityEvent");
pluginManager.registerEvents(injector.getSingleton(AuthMePlayerListener18.class), this);
pluginManager.registerEvents(injector.getSingleton(PlayerListener18.class), this);
} catch (ClassNotFoundException ignore) {
}
// Choose the right SingleSessionListener
if(Bukkit.getOnlineMode() || ServerUtils.isSpigot()) {
pluginManager.registerEvents(injector.getSingleton(AsyncSingleSessionListener.class), this);
} else {
pluginManager.registerEvents(injector.getSingleton(SyncSingleSessionListener.class), this);
}
}
private void reloadSupportHook() {

View File

@ -0,0 +1,39 @@
package fr.xephi.authme.listener;
import javax.inject.Inject;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import fr.xephi.authme.output.Messages;
/*
* This listener is registered only if the server is in online-mode or the implementation is Spigot.
* The reason is that only Spigot fires the Async version of the event on an offline-mode server!
*/
public class AsyncSingleSessionListener implements Listener {
@Inject
private Messages m;
@Inject
private OnJoinVerifier onJoinVerifier;
@EventHandler(priority = EventPriority.LOWEST)
public void onSyncPreLogin(AsyncPlayerPreLoginEvent event) {
if(event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
return;
}
final String name = event.getName();
try {
onJoinVerifier.checkSingleSession(name);
} catch (FailedVerificationException e) {
event.setKickMessage(m.retrieveSingle(e.getReason(), e.getArgs()));
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
return;
}
}
}

View File

@ -7,7 +7,7 @@ import org.bukkit.event.block.BlockPlaceEvent;
import javax.inject.Inject;
public class AuthMeBlockListener implements Listener {
public class BlockListener implements Listener {
@Inject
private ListenerService listenerService;

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.listener;
import fr.xephi.authme.ConsoleLogger;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
@ -20,14 +21,14 @@ import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class AuthMeEntityListener implements Listener {
public class EntityListener implements Listener {
private final ListenerService listenerService;
private Method getShooter;
private boolean shooterIsLivingEntity;
@Inject
AuthMeEntityListener(ListenerService listenerService) {
EntityListener(ListenerService listenerService) {
this.listenerService = listenerService;
try {
getShooter = Projectile.class.getDeclaredMethod("getShooter");

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.listener;
import fr.xephi.authme.AntiBot;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
@ -15,6 +14,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.TeleportationService;
import fr.xephi.authme.util.ValidationService;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -25,6 +25,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
@ -52,7 +53,7 @@ import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOW_UNAU
/**
* Listener class for player events.
*/
public class AuthMePlayerListener implements Listener {
public class PlayerListener implements Listener {
public static final ConcurrentHashMap<String, String> joinMessage = new ConcurrentHashMap<>();
@ -201,26 +202,27 @@ public class AuthMePlayerListener implements Listener {
management.performJoin(player);
}
// Note: AsyncPlayerPreLoginEvent is not fired by all servers in offline mode
// e.g. CraftBukkit does not. So we need to run crucial things in onPlayerLogin, too
// We have no performance improvements if we do the same thing on two different events
// Important: the single session feature works if we use the low priority to the sync handler
@EventHandler(priority = EventPriority.LOWEST)
public void onLoginSingleSession(PlayerLoginEvent event) {
if(event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
public void onAsyncPreLogin(AsyncPlayerPreLoginEvent event) {
// Spigot only
try {
Class.forName("org.spigotmc.CustomTimingsHandler");
} catch(Exception e) {
return;
}
if(event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
return;
}
final Player player = event.getPlayer();
final String name = player.getName();
final String name = event.getName();
try {
onJoinVerifier.checkSingleSession(name);
} catch (FailedVerificationException e) {
ConsoleLogger.warning("DEBUG: " + name + " tried to join the game but an user with the same name was already online!" );
event.setKickMessage(m.retrieveSingle(e.getReason(), e.getArgs()));
event.setResult(PlayerLoginEvent.Result.KICK_OTHER);
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
return;
}
}

View File

@ -10,7 +10,7 @@ import javax.inject.Inject;
/**
* Listener of player events for events introduced in Minecraft 1.6.
*/
public class AuthMePlayerListener16 implements Listener {
public class PlayerListener16 implements Listener {
@Inject
private ListenerService listenerService;

View File

@ -10,7 +10,7 @@ import javax.inject.Inject;
/**
* Listener of player events for events introduced in Minecraft 1.8.
*/
public class AuthMePlayerListener18 implements Listener {
public class PlayerListener18 implements Listener {
@Inject
private ListenerService listenerService;

View File

@ -14,7 +14,7 @@ import javax.inject.Inject;
/**
*/
public class AuthMeServerListener implements Listener {
public class ServerListener implements Listener {
@Inject
private PluginHooks pluginHooks;

View File

@ -0,0 +1,41 @@
package fr.xephi.authme.listener;
import javax.inject.Inject;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerPreLoginEvent;
import fr.xephi.authme.output.Messages;
/*
* This listener is registered only if the server is in offline-mode and the implementation is not Spigot.
* The reason is that only Spigot fires the Async version of this event on an offline-mode server!
*/
public class SyncSingleSessionListener implements Listener {
@Inject
private Messages m;
@Inject
private OnJoinVerifier onJoinVerifier;
// Note: the PlayerPreLoginEvent causes the login thread to synchronize with the main thread
@SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.LOWEST)
public void onSyncPreLogin(PlayerPreLoginEvent event) {
if(event.getResult() != PlayerPreLoginEvent.Result.ALLOWED) {
return;
}
final String name = event.getName();
try {
onJoinVerifier.checkSingleSession(name);
} catch (FailedVerificationException e) {
event.setKickMessage(m.retrieveSingle(e.getReason(), e.getArgs()));
event.setResult(PlayerPreLoginEvent.Result.KICK_OTHER);
return;
}
}
}

View File

@ -7,7 +7,7 @@ import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.LoginEvent;
import fr.xephi.authme.events.RestoreInventoryEvent;
import fr.xephi.authme.listener.AuthMePlayerListener;
import fr.xephi.authme.listener.PlayerListener;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.service.BungeeService;
@ -100,7 +100,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
teleportationService.teleportOnLogin(player, auth, limbo);
// We can now display the join message (if delayed)
String jm = AuthMePlayerListener.joinMessage.get(name);
String jm = PlayerListener.joinMessage.get(name);
if (jm != null) {
if (!jm.isEmpty()) {
for (Player p : bukkitService.getOnlinePlayers()) {
@ -109,7 +109,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
}
}
}
AuthMePlayerListener.joinMessage.remove(name);
PlayerListener.joinMessage.remove(name);
}
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {

View File

@ -7,7 +7,7 @@ import fr.xephi.authme.api.NewAPI;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.listener.AuthMeBlockListener;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.process.login.ProcessSyncPlayerLogin;
@ -113,7 +113,7 @@ public class AuthMeInitializationTest {
// then
// Take a few samples and ensure that they are not null
assertThat(injector.getIfAvailable(AuthMeBlockListener.class), not(nullValue()));
assertThat(injector.getIfAvailable(BlockListener.class), not(nullValue()));
assertThat(injector.getIfAvailable(CommandHandler.class), not(nullValue()));
assertThat(injector.getIfAvailable(Management.class), not(nullValue()));
assertThat(injector.getIfAvailable(NewAPI.class), not(nullValue()));

View File

@ -9,19 +9,22 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.listener.ListenerService;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
/**
* Test for {@link AuthMeBlockListener}.
* Test for {@link BlockListener}.
*/
@RunWith(MockitoJUnitRunner.class)
public class AuthMeBlockListenerTest {
@InjectMocks
private AuthMeBlockListener listener;
private BlockListener listener;
@Mock
private ListenerService listenerService;

View File

@ -1,6 +1,14 @@
package fr.xephi.authme.listener;
import com.google.common.collect.Sets;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.listener.EntityListener;
import fr.xephi.authme.listener.PlayerListener;
import fr.xephi.authme.listener.PlayerListener16;
import fr.xephi.authme.listener.PlayerListener18;
import fr.xephi.authme.listener.ServerListener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.junit.Test;
@ -20,9 +28,9 @@ import static org.junit.Assert.fail;
*/
public final class ListenerConsistencyTest {
private static final Class<?>[] LISTENERS = { AuthMeBlockListener.class, AuthMeEntityListener.class,
AuthMePlayerListener.class, AuthMePlayerListener16.class, AuthMePlayerListener18.class,
AuthMeServerListener.class };
private static final Class<?>[] LISTENERS = { BlockListener.class, EntityListener.class,
PlayerListener.class, PlayerListener16.class, PlayerListener18.class,
ServerListener.class };
private static final Set<String> CANCELED_EXCEPTIONS = Sets.newHashSet("AuthMePlayerListener#onPlayerJoin",
"AuthMePlayerListener#onPreLogin", "AuthMePlayerListener#onPlayerLogin",

View File

@ -6,6 +6,7 @@ import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.listener.ListenerService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.util.ValidationService;

View File

@ -4,6 +4,8 @@ import fr.xephi.authme.AntiBot;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.listener.FailedVerificationException;
import fr.xephi.authme.listener.OnJoinVerifier;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.PermissionsManager;

View File

@ -0,0 +1,18 @@
package tools.utils;
public class ServerUtils {
/**
* Check if the server implementation is based on Spigot
*
* @return true if the implementation is based on Spigot
*/
public static boolean isSpigot() {
try {
Class.forName("org.spigotmc.CustomTimingsHandler");
return true;
} catch (ClassNotFoundException ignored) {
}
return false;
}
}