Remove 1.7 support

This commit is contained in:
Gabriele C 2018-11-30 09:23:30 +01:00
parent fdcbb3334e
commit c11e4b9f15
16 changed files with 45 additions and 379 deletions

39
pom.xml
View File

@ -6,7 +6,7 @@
<groupId>fr.xephi</groupId>
<artifactId>authme</artifactId>
<version>5.5.0-SNAPSHOT</version>
<version>5.5.1-SNAPSHOT</version>
<name>AuthMeReloaded</name>
<description>The first authentication plugin for the Bukkit API!</description>
@ -146,7 +146,7 @@
<configuration>
<rules>
<requireMavenVersion>
<version>3.3.9</version>
<version>${maven.minimumVersion}</version>
</requireMavenVersion>
</rules>
<fail>true</fail>
@ -275,14 +275,9 @@
<!--
Relocate all lib we use in order to fix class loading errors if we use different versions
than already loaded libs (i.e. by Mojang -> gson)
than already loaded libs
-->
<relocations>
<!-- Include all google libraries, because they are not available before 1.12 -->
<relocation>
<pattern>com.google</pattern>
<shadedPattern>fr.xephi.authme.libs.com.google</shadedPattern>
</relocation>
<relocation>
<pattern>ch.jalu</pattern>
<shadedPattern>fr.xephi.authme.libs.ch.jalu</shadedPattern>
@ -439,22 +434,6 @@
<optional>true</optional>
</dependency>
<!-- GSON (required to provide 1.7.10 and below compatibility) -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<optional>true</optional>
</dependency>
<!-- Guava (required to allow compatibility with any version since 1.7.10) -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>27.0.1-jre</version>
<optional>true</optional>
</dependency>
<!-- MaxMind GEO IP with our modifications to use GSON in replacement of the big Jackson dependency -->
<!-- GSON is already included and therefore it reduces the file size in comparison to the original version -->
<dependency>
@ -550,22 +529,10 @@
<artifactId>junit</artifactId>
<groupId>junit</groupId>
</exclusion>
<exclusion>
<artifactId>persistence-api</artifactId>
<groupId>javax.persistence</groupId>
</exclusion>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
<exclusion>
<artifactId>bungeecord-chat</artifactId>
<groupId>net.md-5</groupId>
</exclusion>
<exclusion>
<artifactId>gson</artifactId>
<groupId>com.google.code.gson</groupId>
</exclusion>
</exclusions>
</dependency>

View File

@ -6,21 +6,8 @@ import com.google.common.annotations.VisibleForTesting;
import fr.xephi.authme.api.v3.AuthMeApi;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.initialization.DataSourceProvider;
import fr.xephi.authme.initialization.OnShutdownPlayerSaver;
import fr.xephi.authme.initialization.OnStartupTasks;
import fr.xephi.authme.initialization.SettingsProvider;
import fr.xephi.authme.initialization.TaskCloser;
import fr.xephi.authme.listener.BlockListener;
import fr.xephi.authme.listener.EntityListener;
import fr.xephi.authme.listener.PlayerListener;
import fr.xephi.authme.listener.PlayerListener111;
import fr.xephi.authme.listener.PlayerListener16;
import fr.xephi.authme.listener.PlayerListener18;
import fr.xephi.authme.listener.PlayerListener19;
import fr.xephi.authme.listener.PlayerListener19Spigot;
import fr.xephi.authme.listener.ServerListener;
import fr.xephi.authme.initialization.*;
import fr.xephi.authme.listener.*;
import fr.xephi.authme.security.crypts.Sha256;
import fr.xephi.authme.service.BackupService;
import fr.xephi.authme.service.BukkitService;
@ -121,7 +108,7 @@ public class AuthMe extends JavaPlugin {
loadPluginInfo(getDescription().getVersion());
// Prevent running AuthMeBridge due to major exploit issues
if(getServer().getPluginManager().isPluginEnabled("AuthMeBridge")) {
if (getServer().getPluginManager().isPluginEnabled("AuthMeBridge")) {
ConsoleLogger.warning("Detected AuthMeBridge, support for it has been dropped as it was "
+ "causing exploit issues, please use AuthMeBungee instead! Aborting!");
stopOrUnload();
@ -272,16 +259,6 @@ public class AuthMe extends JavaPlugin {
pluginManager.registerEvents(injector.getSingleton(EntityListener.class), this);
pluginManager.registerEvents(injector.getSingleton(ServerListener.class), this);
// Try to register 1.6 player listeners
if (isClassLoaded("org.bukkit.event.player.PlayerEditBookEvent")) {
pluginManager.registerEvents(injector.getSingleton(PlayerListener16.class), this);
}
// Try to register 1.8 player listeners
if (isClassLoaded("org.bukkit.event.player.PlayerInteractAtEntityEvent")) {
pluginManager.registerEvents(injector.getSingleton(PlayerListener18.class), this);
}
// Try to register 1.9 player listeners
if (isClassLoaded("org.bukkit.event.player.PlayerSwapHandItemsEvent")) {
pluginManager.registerEvents(injector.getSingleton(PlayerListener19.class), this);
@ -341,7 +318,6 @@ public class AuthMe extends JavaPlugin {
* @param cmd The command (Bukkit).
* @param commandLabel The command label (Bukkit).
* @param args The command arguments (Bukkit).
*
* @return True if the command was executed, false otherwise.
*/
@Override

View File

@ -35,24 +35,7 @@ import org.bukkit.event.block.SignChangeEvent;
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;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.Inventory;
import javax.inject.Inject;
@ -285,11 +268,7 @@ public class PlayerListener implements Listener {
// Keep pre-UUID compatibility
try {
try {
permissionsManager.loadUserData(event.getUniqueId());
} catch (NoSuchMethodError e) {
permissionsManager.loadUserData(name);
}
permissionsManager.loadUserData(event.getUniqueId());
} catch (PermissionLoadUserException e) {
ConsoleLogger.logException("Unable to load the permission data of user " + name, e);
}
@ -520,4 +499,18 @@ public class PlayerListener implements Listener {
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerEditBook(PlayerEditBookEvent event) {
if (listenerService.shouldCancelEvent(event)) {
event.setCancelled(true);
}
}
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
if (listenerService.shouldCancelEvent(event)) {
event.setCancelled(true);
}
}
}

View File

@ -1,25 +0,0 @@
package fr.xephi.authme.listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerEditBookEvent;
import javax.inject.Inject;
/**
* Listener of player events for events introduced in Minecraft 1.6.
*/
public class PlayerListener16 implements Listener {
@Inject
private ListenerService listenerService;
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerEditBook(PlayerEditBookEvent event) {
if (listenerService.shouldCancelEvent(event)) {
event.setCancelled(true);
}
}
}

View File

@ -1,25 +0,0 @@
package fr.xephi.authme.listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import javax.inject.Inject;
/**
* Listener of player events for events introduced in Minecraft 1.8.
*/
public class PlayerListener18 implements Listener {
@Inject
private ListenerService listenerService;
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerInteractAtEntity(PlayerInteractAtEntityEvent event) {
if (listenerService.shouldCancelEvent(event)) {
event.setCancelled(true);
}
}
}

View File

@ -455,11 +455,7 @@ public class PermissionsManager implements Reloadable {
*/
public boolean loadUserData(OfflinePlayer offlinePlayer) {
try {
try {
loadUserData(offlinePlayer.getUniqueId());
} catch (NoSuchMethodError e) {
loadUserData(offlinePlayer.getName());
}
loadUserData(offlinePlayer.getUniqueId());
} catch (PermissionLoadUserException e) {
ConsoleLogger.logException("Unable to load the permission data of user " + offlinePlayer.getName(), e);
return false;
@ -480,16 +476,4 @@ public class PermissionsManager implements Reloadable {
handler.loadUserData(uuid);
}
/**
* Loads the permission data of the given player name.
*
* @param name the name of the player.
* @throws PermissionLoadUserException if the action failed.
*/
public void loadUserData(String name) throws PermissionLoadUserException {
if (!isEnabled()) {
return;
}
handler.loadUserData(name);
}
}

View File

@ -197,13 +197,4 @@ public class LuckPermsHandler implements PermissionHandler {
}
}
@Override
public void loadUserData(String name) throws PermissionLoadUserException {
try {
UUID uuid = luckPermsApi.getUserManager().lookupUuid(name).get(5, TimeUnit.SECONDS);
loadUserData(uuid);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
throw new PermissionLoadUserException("Unable to load the permission data of the user " + name, e);
}
}
}

View File

@ -110,6 +110,4 @@ public interface PermissionHandler {
default void loadUserData(UUID uuid) throws PermissionLoadUserException {
}
default void loadUserData(String name) throws PermissionLoadUserException {
}
}

View File

@ -2,7 +2,6 @@ package fr.xephi.authme.service;
import com.google.common.collect.Iterables;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
@ -20,11 +19,8 @@ import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Optional;
import java.util.Set;
@ -41,14 +37,12 @@ public class BukkitService implements SettingsDependent {
public static final int TICKS_PER_MINUTE = 60 * TICKS_PER_SECOND;
private final AuthMe authMe;
private final boolean getOnlinePlayersIsCollection;
private Method getOnlinePlayers;
private boolean useAsyncTasks;
@Inject
BukkitService(AuthMe authMe, Settings settings) {
this.authMe = authMe;
getOnlinePlayersIsCollection = doesOnlinePlayersMethodReturnCollection();
reload(settings);
}
@ -237,40 +231,12 @@ public class BukkitService implements SettingsDependent {
}
/**
* Safe way to retrieve the list of online players from the server. Depending on the
* implementation of the server, either an array of {@link Player} instances is being returned,
* or a Collection. Always use this wrapper to retrieve online players instead of {@link
* Bukkit#getOnlinePlayers()} directly.
* Gets a view of all currently online players.
*
* @return collection of online players
*
* @see <a href="https://www.spigotmc.org/threads/solved-cant-use-new-getonlineplayers.33061/">SpigotMC
* forum</a>
* @see <a href="http://stackoverflow.com/questions/32130851/player-changed-from-array-to-collection">StackOverflow</a>
*/
@SuppressWarnings("unchecked")
public Collection<? extends Player> getOnlinePlayers() {
if (getOnlinePlayersIsCollection) {
return Bukkit.getOnlinePlayers();
}
try {
// The lookup of a method via Reflections is rather expensive, so we keep a reference to it
if (getOnlinePlayers == null) {
getOnlinePlayers = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
}
Object obj = getOnlinePlayers.invoke(null);
if (obj instanceof Collection<?>) {
return (Collection<? extends Player>) obj;
} else if (obj instanceof Player[]) {
return Arrays.asList((Player[]) obj);
} else {
String type = (obj == null) ? "null" : obj.getClass().getName();
ConsoleLogger.warning("Unknown list of online players of type " + type);
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
ConsoleLogger.logException("Could not retrieve list of online players:", e);
}
return Collections.emptyList();
return Bukkit.getOnlinePlayers();
}
/**
@ -346,23 +312,6 @@ public class BukkitService implements SettingsDependent {
}
}
/**
* Method run upon initialization to verify whether or not the Bukkit implementation
* returns the online players as a {@link Collection}.
*
* @return true if a collection is returned by the bukkit implementation, false otherwise
* @see #getOnlinePlayers()
*/
private static boolean doesOnlinePlayersMethodReturnCollection() {
try {
Method method = Bukkit.class.getDeclaredMethod("getOnlinePlayers");
return method.getReturnType() == Collection.class;
} catch (NoSuchMethodException e) {
ConsoleLogger.warning("Error verifying if getOnlinePlayers is a collection! Method doesn't exist");
}
return false;
}
/**
* Adds a ban to the this list. If a previous ban exists, this will
* update the previous entry.

View File

@ -7,7 +7,6 @@ import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.PluginHookService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.util.PlayerUtils;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
@ -160,7 +159,7 @@ public class PurgeExecutor {
makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players"));
for (OfflinePlayer offlinePlayer : cleared) {
File playerFile = new File(dataFolder, PlayerUtils.getUuidOrName(offlinePlayer) + ".dat");
File playerFile = new File(dataFolder, offlinePlayer.getUniqueId() + ".dat");
if (playerFile.delete()) {
i++;
}
@ -192,7 +191,7 @@ public class PurgeExecutor {
int deletedFiles = 0;
for (OfflinePlayer offlinePlayer : cleared) {
File playerFile = new File(userDataFolder, PlayerUtils.getUuidOrName(offlinePlayer) + ".yml");
File playerFile = new File(userDataFolder, offlinePlayer.getUniqueId() + ".yml");
if (playerFile.exists() && playerFile.delete()) {
deletedFiles++;
}

View File

@ -1,6 +1,5 @@
package fr.xephi.authme.util;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
/**
@ -12,42 +11,24 @@ public final class PlayerUtils {
private PlayerUtils() {
}
/**
* Get player's UUID if can, name otherwise.
*
* @param player Player to retrieve
*
* @return player's UUID or Name in String.
*/
public static String getUuidOrName(OfflinePlayer player) {
// We may made this configurable in future
// so we can have uuid support.
try {
return player.getUniqueId().toString();
} catch (NoSuchMethodError ignore) {
return player.getName();
}
}
/**
* Returns the IP of the given player.
*
* @param p The player to return the IP address for
*
* @param player The player to return the IP address for
* @return The player's IP address
*/
public static String getPlayerIp(Player p) {
return p.getAddress().getAddress().getHostAddress();
public static String getPlayerIp(Player player) {
return player.getAddress().getAddress().getHostAddress();
}
/**
* Returns if the player is an NPC or not.
*
* @param player The player to check
*
* @return True if the player is an NPC, false otherwise
*/
public static boolean isNpc(Player player) {
return player.hasMetadata("NPC");
return player.hasMetadata("NPC");
}
}

View File

@ -1,30 +0,0 @@
package fr.xephi.authme.listener;
import org.bukkit.event.player.PlayerEditBookEvent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock;
/**
* Test for {@link PlayerListener16}.
*/
@RunWith(MockitoJUnitRunner.class)
public class PlayerListener16Test {
@InjectMocks
private PlayerListener16 listener;
@Mock
private ListenerService listenerService;
@Test
public void shouldCancelEvent() {
withServiceMock(listenerService)
.check(listener::onPlayerEditBook, PlayerEditBookEvent.class);
}
}

View File

@ -1,30 +0,0 @@
package fr.xephi.authme.listener;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static fr.xephi.authme.listener.EventCancelVerifier.withServiceMock;
/**
* Test for {@link PlayerListener18}.
*/
@RunWith(MockitoJUnitRunner.class)
public class PlayerListener18Test {
@InjectMocks
private PlayerListener18 listener;
@Mock
private ListenerService listenerService;
@Test
public void shouldCancelEvent() {
withServiceMock(listenerService)
.check(listener::onPlayerInteractAtEntity, PlayerInteractAtEntityEvent.class);
}
}

View File

@ -28,21 +28,7 @@ import org.bukkit.event.block.SignChangeEvent;
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.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerShearEntityEvent;
import org.bukkit.event.player.*;
import org.bukkit.inventory.InventoryView;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -890,6 +876,18 @@ public class PlayerListenerTest {
verify(joinMessageService).putMessage("thename0", "thename0 is joining us");
}
@Test
public void shouldCancelPlayerEditBookEvent() {
withServiceMock(listenerService)
.check(listener::onPlayerEditBook, PlayerEditBookEvent.class);
}
@Test
public void shouldCancelPlayerInteractAtEntityEvent() {
withServiceMock(listenerService)
.check(listener::onPlayerInteractAtEntity, PlayerInteractAtEntityEvent.class);
}
private static Player mockPlayerWithName(String name) {
Player player = mock(Player.class);
given(player.getName()).willReturn(name);

View File

@ -21,10 +21,7 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collection;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
@ -62,34 +59,6 @@ public class BukkitServiceTest {
bukkitService = new BukkitService(authMe, settings);
}
/**
* Checks that {@link BukkitService#getOnlinePlayersIsCollection} is initialized to {@code true} on startup;
* the test scope is configured with a Bukkit implementation that returns a Collection and not an array.
*/
@Test
public void shouldHavePlayerListAsCollectionMethod() {
// given / when
boolean doesMethodReturnCollection = ReflectionTestUtils
.getFieldValue(BukkitService.class, bukkitService, "getOnlinePlayersIsCollection");
// then
assertThat(doesMethodReturnCollection, equalTo(true));
}
@Test
public void shouldRetrieveListOfOnlinePlayersFromReflectedMethod() {
// given
ReflectionTestUtils.setField(BukkitService.class, bukkitService, "getOnlinePlayersIsCollection", false);
ReflectionTestUtils.setField(BukkitService.class, bukkitService, "getOnlinePlayers",
ReflectionTestUtils.getMethod(BukkitServiceTest.class, "onlinePlayersImpl"));
// when
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
// then
assertThat(players, hasSize(2));
}
@Test
public void shouldDispatchCommand() {
// given

View File

@ -36,35 +36,6 @@ public class PlayerUtilsTest {
assertThat(result, equalTo(ip));
}
@Test
public void shouldGetUuid() {
// given
UUID uuid = UUID.randomUUID();
Player player = mock(Player.class);
given(player.getUniqueId()).willReturn(uuid);
// when
String result = PlayerUtils.getUuidOrName(player);
// then
assertThat(result, equalTo(uuid.toString()));
}
@Test
public void shouldFallbackToName() {
// given
Player player = mock(Player.class);
doThrow(NoSuchMethodError.class).when(player).getUniqueId();
String name = "Bobby12";
given(player.getName()).willReturn(name);
// when
String result = PlayerUtils.getUuidOrName(player);
// then
assertThat(result, equalTo(name));
}
@Test
public void shouldHaveHiddenConstructor() {
// given / when / then