This commit is contained in:
ljacqu 2016-07-06 20:55:56 +02:00
commit d297d0b528
43 changed files with 1089 additions and 781 deletions

View File

@ -12,9 +12,280 @@
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="JAVA">
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PROTECTED>true</PROTECTED>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PUBLIC>true</PUBLIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PROTECTED>true</PROTECTED>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<FINAL>true</FINAL>
<PRIVATE>true</PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PUBLIC>true</PUBLIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PROTECTED>true</PROTECTED>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PACKAGE_PRIVATE>true</PACKAGE_PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<FIELD>true</FIELD>
<PRIVATE>true</PRIVATE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<FIELD>true</FIELD>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INITIALIZER_BLOCK>true</INITIALIZER_BLOCK>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CONSTRUCTOR>true</CONSTRUCTOR>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD>true</METHOD>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<METHOD>true</METHOD>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<METHOD>true</METHOD>
<PRIVATE>true</PRIVATE>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<ENUM>true</ENUM>
</match>
</rule>
</section>
<section>
<rule>
<match>
<INTERFACE>true</INTERFACE>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<CLASS>true</CLASS>
<STATIC>true</STATIC>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<CLASS>true</CLASS>
</match>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</value>
</option>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Project" />
</component>
</project>

View File

@ -5,8 +5,8 @@ import fr.xephi.authme.api.API;
import fr.xephi.authme.api.NewAPI;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.backup.PlayerDataStorage;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.command.CommandHandler;
import fr.xephi.authme.datasource.CacheDataSource;
import fr.xephi.authme.datasource.DataSource;
@ -29,6 +29,7 @@ import fr.xephi.authme.output.ConsoleFilter;
import fr.xephi.authme.output.Log4JFilter;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.permission.AuthGroupHandler;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PermissionsSystemType;
import fr.xephi.authme.process.Management;
@ -283,15 +284,15 @@ public class AuthMe extends JavaPlugin {
// Some statically injected things
initializer.register(PlayerCache.class, PlayerCache.getInstance());
messages = initializer.get(Messages.class);
permsMan = initializer.get(PermissionsManager.class);
bukkitService = initializer.get(BukkitService.class);
pluginHooks = initializer.get(PluginHooks.class);
messages = initializer.get(Messages.class);
permsMan = initializer.get(PermissionsManager.class);
bukkitService = initializer.get(BukkitService.class);
pluginHooks = initializer.get(PluginHooks.class);
passwordSecurity = initializer.get(PasswordSecurity.class);
spawnLoader = initializer.get(SpawnLoader.class);
commandHandler = initializer.get(CommandHandler.class);
management = initializer.get(Management.class);
geoLiteApi = initializer.get(GeoLiteAPI.class);
spawnLoader = initializer.get(SpawnLoader.class);
commandHandler = initializer.get(CommandHandler.class);
management = initializer.get(Management.class);
geoLiteApi = initializer.get(GeoLiteAPI.class);
initializer.get(NewAPI.class);
initializer.get(API.class);
}
@ -321,7 +322,7 @@ public class AuthMe extends JavaPlugin {
// Register event listeners
pluginManager.registerEvents(initializer.get(AuthMePlayerListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMeBlockListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMeEntityListener.class), this);
pluginManager.registerEvents(initializer.get(AuthMeServerListener.class), this);
@ -421,11 +422,12 @@ public class AuthMe extends JavaPlugin {
// Save player data
BukkitService bukkitService = initializer.getIfAvailable(BukkitService.class);
LimboCache limboCache = initializer.getIfAvailable(LimboCache.class);
AuthGroupHandler authGroupHandler = initializer.getIfAvailable(AuthGroupHandler.class);
if (bukkitService != null && limboCache != null) {
Collection<? extends Player> players = bukkitService.getOnlinePlayers();
for (Player player : players) {
savePlayer(player, limboCache);
savePlayer(player, limboCache, authGroupHandler);
}
}
@ -441,8 +443,8 @@ public class AuthMe extends JavaPlugin {
//returns only the async takss
for (BukkitWorker pendingTask : getServer().getScheduler().getActiveWorkers()) {
if (pendingTask.getOwner().equals(AuthMe.this)
//it's not a peridic task
&& !getServer().getScheduler().isQueued(pendingTask.getTaskId())) {
//it's not a peridic task
&& !getServer().getScheduler().isQueued(pendingTask.getTaskId())) {
pendingTasks.add(pendingTask.getTaskId());
}
}
@ -465,7 +467,7 @@ public class AuthMe extends JavaPlugin {
break;
}
for (Iterator<Integer> iterator = pendingTasks.iterator(); iterator.hasNext();) {
for (Iterator<Integer> iterator = pendingTasks.iterator(); iterator.hasNext(); ) {
int taskId = iterator.next();
if (!getServer().getScheduler().isCurrentlyRunning(taskId)) {
iterator.remove();
@ -558,28 +560,30 @@ public class AuthMe extends JavaPlugin {
}
// Save Player Data
private void savePlayer(Player player, LimboCache limboCache) {
private void savePlayer(Player player, LimboCache limboCache, AuthGroupHandler authGroupHandler) {
if (safeIsNpc(player) || Utils.isUnrestricted(player)) {
return;
}
String name = player.getName().toLowerCase();
if (PlayerCache.getInstance().isAuthenticated(name) && !player.isDead() && Settings.isSaveQuitLocationEnabled) {
final PlayerAuth auth = PlayerAuth.builder()
.name(player.getName().toLowerCase())
.realName(player.getName())
.location(player.getLocation()).build();
database.updateQuitLoc(auth);
}
if (limboCache.hasLimboPlayer(name)) {
LimboPlayer limbo = limboCache.getLimboPlayer(name);
if (!Settings.noTeleport) {
player.teleport(limbo.getLoc());
if (limboCache.hasPlayerData(name)) {
limboCache.restoreData(player);
limboCache.removeFromCache(player);
} else {
if (newSettings.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
Location loc = spawnLoader.getPlayerLocationOrSpawn(player);
final PlayerAuth auth = PlayerAuth.builder()
.name(player.getName().toLowerCase())
.realName(player.getName())
.location(loc).build();
database.updateQuitLoc(auth);
}
if (newSettings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)
&& !newSettings.getProperty(RestrictionSettings.NO_TELEPORT)) {
PlayerDataStorage playerDataStorage = initializer.getIfAvailable(PlayerDataStorage.class);
if (playerDataStorage != null && !playerDataStorage.hasData(player)) {
playerDataStorage.saveData(player);
}
}
Utils.addNormal(player, limbo.getGroup());
player.setOp(limbo.isOperator());
limbo.getTimeoutTask().cancel();
limboCache.deleteLimboPlayer(name);
}
PlayerCache.getInstance().removePlayer(name);
}
@ -588,12 +592,6 @@ public class AuthMe extends JavaPlugin {
return pluginHooks != null && pluginHooks.isNpc(player) || player.hasMetadata("NPC");
}
// Return the spawn location of a player
@Deprecated
public Location getSpawnLocation(Player player) {
return spawnLoader.getSpawnLocation(player);
}
private void scheduleRecallEmailTask() {
if (!newSettings.getProperty(RECALL_PLAYERS)) {
return;
@ -632,7 +630,6 @@ public class AuthMe extends JavaPlugin {
}
/**
* Handle Bukkit commands.
*
@ -663,6 +660,7 @@ public class AuthMe extends JavaPlugin {
/**
* @return permission manager
*
* @deprecated should be used in API classes only (temporarily)
*/
@Deprecated
@ -672,6 +670,7 @@ public class AuthMe extends JavaPlugin {
/**
* @return process manager
*
* @deprecated should be used in API classes only (temporarily)
*/
@Deprecated
@ -681,6 +680,7 @@ public class AuthMe extends JavaPlugin {
/**
* @return the datasource
*
* @deprecated should be used in API classes only (temporarily)
*/
@Deprecated
@ -690,6 +690,7 @@ public class AuthMe extends JavaPlugin {
/**
* @return password manager
*
* @deprecated should be used in API classes only (temporarily)
*/
@Deprecated
@ -699,6 +700,7 @@ public class AuthMe extends JavaPlugin {
/**
* @return plugin hooks
*
* @deprecated should be used in API classes only (temporarily)
*/
@Deprecated

View File

@ -27,7 +27,7 @@ public class SessionManager implements SettingsDependent {
* @return True if a session is found.
*/
public boolean hasSession(String name) {
return sessions.containsKey(name);
return enabled && sessions.containsKey(name);
}
/**

View File

@ -4,6 +4,7 @@ package fr.xephi.authme.cache.auth;
import java.util.concurrent.ConcurrentHashMap;
/**
* Used to manage player's Authenticated status
*/
public class PlayerCache {
@ -55,11 +56,11 @@ public class PlayerCache {
}
/**
* Method isAuthenticated.
* get player's authenticated status.
*
* @param user String
* @param user player's name
*
* @return boolean
* @return true if player is logged in, false otherwise.
*/
public boolean isAuthenticated(String user) {
return cache.containsKey(user.toLowerCase());

View File

@ -1,131 +0,0 @@
package fr.xephi.authme.cache.backup;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import org.bukkit.entity.Player;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
public class JsonCache {
private final Gson gson;
private final File cacheDir;
public JsonCache() {
cacheDir = new File(AuthMe.getInstance().getDataFolder(), "cache");
if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) {
ConsoleLogger.showError("Failed to create cache directory.");
}
gson = new GsonBuilder()
.registerTypeAdapter(PlayerData.class, new PlayerDataSerializer())
.registerTypeAdapter(PlayerData.class, new PlayerDataDeserializer())
.setPrettyPrinting()
.create();
}
public PlayerData readCache(Player player) {
String name = player.getName().toLowerCase();
File file = new File(cacheDir, name + File.separator + "cache.json");
if (!file.exists()) {
return null;
}
try {
String str = Files.toString(file, Charsets.UTF_8);
return gson.fromJson(str, PlayerData.class);
} catch (IOException e) {
ConsoleLogger.writeStackTrace(e);
return null;
}
}
public void removeCache(Player player) {
String name = player.getName().toLowerCase();
File file = new File(cacheDir, name);
if (file.exists()) {
purgeDirectory(file);
if (!file.delete()) {
ConsoleLogger.showError("Failed to remove" + player.getName() + "cache.");
}
}
}
public boolean doesCacheExist(Player player) {
String name = player.getName().toLowerCase();
File file = new File(cacheDir, name + File.separator + "cache.json");
return file.exists();
}
private class PlayerDataDeserializer implements JsonDeserializer<PlayerData> {
@Override
public PlayerData deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext context) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (jsonObject == null) {
return null;
}
String group = null;
boolean operator = false;
boolean fly = false;
JsonElement e;
if ((e = jsonObject.get("group")) != null) {
group = e.getAsString();
}
if ((e = jsonObject.get("operator")) != null) {
operator = e.getAsBoolean();
}
if ((e = jsonObject.get("fly")) != null) {
fly = e.getAsBoolean();
}
return new PlayerData(group, operator, fly);
}
}
private class PlayerDataSerializer implements JsonSerializer<PlayerData> {
@Override
public JsonElement serialize(PlayerData playerData, Type type,
JsonSerializationContext context) {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("group", playerData.getGroup());
jsonObject.addProperty("operator", playerData.getOperator());
jsonObject.addProperty("fly", playerData.isFlyEnabled());
return jsonObject;
}
}
/**
* Delete a given directory and all its content.
*
* @param directory The directory to remove
*/
private static void purgeDirectory(File directory) {
if (!directory.isDirectory()) {
return;
}
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File target : files) {
if (target.isDirectory()) {
purgeDirectory(target);
}
target.delete();
}
}
}

View File

@ -1,26 +0,0 @@
package fr.xephi.authme.cache.backup;
public class PlayerData {
private final String group;
private final boolean operator;
private final boolean flyEnabled;
public PlayerData(String group, boolean operator, boolean flyEnabled) {
this.group = group;
this.operator = operator;
this.flyEnabled = flyEnabled;
}
public String getGroup() {
return group;
}
public boolean getOperator() {
return operator;
}
public boolean isFlyEnabled() {
return flyEnabled;
}
}

View File

@ -0,0 +1,211 @@
package fr.xephi.authme.cache.backup;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.initialization.DataFolder;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.FileUtils;
import fr.xephi.authme.util.Utils;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
/**
* Class used to store player's data (OP, flying, speed, position) to disk.
*/
public class PlayerDataStorage {
private final Gson gson;
private final File cacheDir;
private PermissionsManager permissionsManager;
private SpawnLoader spawnLoader;
private BukkitService bukkitService;
@Inject
PlayerDataStorage(@DataFolder File dataFolder, PermissionsManager permsMan,
SpawnLoader spawnLoader, BukkitService bukkitService) {
this.permissionsManager = permsMan;
this.spawnLoader = spawnLoader;
this.bukkitService = bukkitService;
cacheDir = new File(dataFolder, "playerdata");
if (!cacheDir.exists() && !cacheDir.isDirectory() && !cacheDir.mkdir()) {
ConsoleLogger.showError("Failed to create userdata directory.");
}
gson = new GsonBuilder()
.registerTypeAdapter(PlayerData.class, new PlayerDataSerializer())
.registerTypeAdapter(PlayerData.class, new PlayerDataDeserializer())
.setPrettyPrinting()
.create();
}
/**
* Read and construct new PlayerData from existing player data.
*
* @param player player to read
*
* @return PlayerData object if the data is exist, null otherwise.
*/
public PlayerData readData(Player player) {
String id = Utils.getUUIDorName(player);
File file = new File(cacheDir, id + File.separator + "data.json");
if (!file.exists()) {
return null;
}
try {
String str = Files.toString(file, Charsets.UTF_8);
return gson.fromJson(str, PlayerData.class);
} catch (IOException e) {
ConsoleLogger.writeStackTrace(e);
return null;
}
}
/**
* Save player data (OP, flying, location, etc) to disk.
*
* @param player player to save
*/
public void saveData(Player player) {
String id = Utils.getUUIDorName(player);
Location location = spawnLoader.getPlayerLocationOrSpawn(player);
String group = permissionsManager.getPrimaryGroup(player);
boolean operator = player.isOp();
boolean canFly = player.getAllowFlight();
float walkSpeed = player.getWalkSpeed();
float flySpeed = player.getFlySpeed();
PlayerData playerData = new PlayerData(location, operator, group, canFly, walkSpeed, flySpeed);
try {
File file = new File(cacheDir, id + File.separator + "data.json");
Files.createParentDirs(file);
Files.touch(file);
Files.write(gson.toJson(playerData), file, Charsets.UTF_8);
} catch (IOException e) {
ConsoleLogger.logException("Failed to write " + player.getName() + " data.", e);
}
}
/**
* Remove player data, this will delete
* "playerdata/&lt;uuid or name&gt;/" folder from disk.
*
* @param player player to remove
*/
public void removeData(Player player) {
String id = Utils.getUUIDorName(player);
File file = new File(cacheDir, id);
if (file.exists()) {
FileUtils.purgeDirectory(file);
if (!file.delete()) {
ConsoleLogger.showError("Failed to remove " + player.getName() + " cache.");
}
}
}
/**
* Use to check is player data is exist.
*
* @param player player to check
*
* @return true if data exist, false otherwise.
*/
public boolean hasData(Player player) {
String id = Utils.getUUIDorName(player);
File file = new File(cacheDir, id + File.separator + "data.json");
return file.exists();
}
private class PlayerDataDeserializer implements JsonDeserializer<PlayerData> {
@Override
public PlayerData deserialize(JsonElement jsonElement, Type type,
JsonDeserializationContext context) {
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (jsonObject == null) {
return null;
}
Location loc = null;
String group = "";
boolean operator = false;
boolean canFly = false;
float walkSpeed = 0.2f;
float flySpeed = 0.2f;
JsonElement e;
if ((e = jsonObject.getAsJsonObject("location")) != null) {
JsonObject obj = e.getAsJsonObject();
World world = bukkitService.getWorld(obj.get("world").getAsString());
if (world != null) {
double x = obj.get("x").getAsDouble();
double y = obj.get("y").getAsDouble();
double z = obj.get("z").getAsDouble();
float yaw = obj.get("yaw").getAsFloat();
float pitch = obj.get("pitch").getAsFloat();
loc = new Location(world, x, y, z, yaw, pitch);
}
}
if ((e = jsonObject.get("group")) != null) {
group = e.getAsString();
}
if ((e = jsonObject.get("operator")) != null) {
operator = e.getAsBoolean();
}
if ((e = jsonObject.get("can-fly")) != null) {
canFly = e.getAsBoolean();
}
if ((e = jsonObject.get("walk-speed")) != null) {
walkSpeed = e.getAsFloat();
}
if ((e = jsonObject.get("fly-speed")) != null) {
flySpeed = e.getAsFloat();
}
return new PlayerData(loc, operator, group, canFly, walkSpeed, flySpeed);
}
}
private class PlayerDataSerializer implements JsonSerializer<PlayerData> {
@Override
public JsonElement serialize(PlayerData playerData, Type type,
JsonSerializationContext context) {
JsonObject obj = new JsonObject();
obj.addProperty("group", playerData.getGroup());
Location loc = playerData.getLocation();
JsonObject obj2 = new JsonObject();
obj2.addProperty("world", loc.getWorld().getName());
obj2.addProperty("x", loc.getX());
obj2.addProperty("y", loc.getY());
obj2.addProperty("z", loc.getZ());
obj2.addProperty("yaw", loc.getYaw());
obj2.addProperty("pitch", loc.getPitch());
obj.add("location", obj2);
obj.addProperty("operator", playerData.isOperator());
obj.addProperty("can-fly", playerData.isCanFly());
obj.addProperty("walk-speed", playerData.getWalkSpeed());
obj.addProperty("fly-speed", playerData.getFlySpeed());
return obj;
}
}
}

View File

@ -1,9 +1,12 @@
package fr.xephi.authme.cache.limbo;
import fr.xephi.authme.cache.backup.JsonCache;
import fr.xephi.authme.cache.backup.PlayerData;
import fr.xephi.authme.cache.backup.PlayerDataStorage;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.StringUtils;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -13,99 +16,144 @@ import java.util.concurrent.ConcurrentHashMap;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Manages all {@link LimboPlayer} instances.
* Manages all {@link PlayerData} instances.
*/
public class LimboCache {
private final ConcurrentHashMap<String, LimboPlayer> cache = new ConcurrentHashMap<>();
private final JsonCache jsonCache = new JsonCache();
private final ConcurrentHashMap<String, PlayerData> cache = new ConcurrentHashMap<>();
@Inject
private PlayerDataStorage playerDataStorage;
private NewSetting settings;
private PermissionsManager permissionsManager;
@Inject
private SpawnLoader spawnLoader;
@Inject
LimboCache(PermissionsManager permissionsManager, SpawnLoader spawnLoader) {
LimboCache(NewSetting settings, PermissionsManager permissionsManager,
SpawnLoader spawnLoader, PlayerDataStorage playerDataStorage) {
this.settings = settings;
this.permissionsManager = permissionsManager;
this.spawnLoader = spawnLoader;
this.playerDataStorage = playerDataStorage;
}
/**
* Add a limbo player.
* Load player data if exist, otherwise current player's data will be stored.
*
* @param player Player instance to add.
*/
public void addLimboPlayer(Player player) {
public void addPlayerData(Player player) {
String name = player.getName().toLowerCase();
Location location = player.isDead() ? spawnLoader.getSpawnLocation(player) : player.getLocation();
Location location = spawnLoader.getPlayerLocationOrSpawn(player);
boolean operator = player.isOp();
boolean flyEnabled = player.getAllowFlight();
float walkSpeed = player.getWalkSpeed();
float flySpeed = player.getFlySpeed();
String playerGroup = "";
if (permissionsManager.hasGroupSupport()) {
playerGroup = permissionsManager.getPrimaryGroup(player);
}
if (jsonCache.doesCacheExist(player)) {
PlayerData cache = jsonCache.readCache(player);
if (playerDataStorage.hasData(player)) {
PlayerData cache = playerDataStorage.readData(player);
if (cache != null) {
location = cache.getLocation();
playerGroup = cache.getGroup();
operator = cache.getOperator();
flyEnabled = cache.isFlyEnabled();
operator = cache.isOperator();
flyEnabled = cache.isCanFly();
walkSpeed = cache.getWalkSpeed();
flySpeed = cache.getFlySpeed();
}
} else {
playerDataStorage.saveData(player);
}
cache.put(name, new LimboPlayer(name, location, operator, playerGroup, flyEnabled));
cache.put(name, new PlayerData(location, operator, playerGroup, flyEnabled, walkSpeed, flySpeed));
}
/**
* Method deleteLimboPlayer.
* Restore player's data to player if exist.
*
* @param name String
* @param player Player instance to restore
*/
public void deleteLimboPlayer(String name) {
checkNotNull(name);
name = name.toLowerCase();
LimboPlayer cachedPlayer = cache.remove(name);
public void restoreData(Player player) {
String lowerName = player.getName().toLowerCase();
if (cache.containsKey(lowerName)) {
PlayerData data = cache.get(lowerName);
player.setOp(data.isOperator());
player.setAllowFlight(data.isCanFly());
player.setWalkSpeed(data.getWalkSpeed());
player.setFlySpeed(data.getFlySpeed());
restoreGroup(player, data.getGroup());
if (!settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
player.teleport(data.getLocation());
}
data.clearTasks();
}
}
/**
* Remove PlayerData from cache and disk.
*
* @param player Player player to remove.
*/
public void deletePlayerData(Player player) {
removeFromCache(player);
playerDataStorage.removeData(player);
}
/**
* Remove PlayerData from cache.
*
* @param player player to remove.
*/
public void removeFromCache(Player player) {
String name = player.getName().toLowerCase();
PlayerData cachedPlayer = cache.remove(name);
if (cachedPlayer != null) {
cachedPlayer.clearTasks();
}
}
/**
* Method getLimboPlayer.
* Method getPlayerData.
*
* @param name String
*
* @return LimboPlayer
* @return PlayerData
*/
public LimboPlayer getLimboPlayer(String name) {
public PlayerData getPlayerData(String name) {
checkNotNull(name);
return cache.get(name.toLowerCase());
}
/**
* Method hasLimboPlayer.
* Method hasPlayerData.
*
* @param name String
*
* @return boolean
*/
public boolean hasLimboPlayer(String name) {
public boolean hasPlayerData(String name) {
checkNotNull(name);
return cache.containsKey(name.toLowerCase());
}
/**
* Method updateLimboPlayer.
* Method updatePlayerData.
*
* @param player Player
*/
public void updateLimboPlayer(Player player) {
public void updatePlayerData(Player player) {
checkNotNull(player);
deleteLimboPlayer(player.getName().toLowerCase());
addLimboPlayer(player);
removeFromCache(player);
addPlayerData(player);
}
private void restoreGroup(Player player, String group) {
if (!settings.getProperty(PluginSettings.ENABLE_PERMISSION_CHECK)
|| !permissionsManager.hasGroupSupport() || StringUtils.isEmpty(group)) {
return;
}
permissionsManager.setGroup(player, group);
}
}

View File

@ -7,32 +7,25 @@ import org.bukkit.scheduler.BukkitTask;
* Represents a player which is not logged in and keeps track of certain states (like OP status, flying)
* which may be revoked from the player until he has logged in or registered.
*/
public class LimboPlayer {
public class PlayerData {
private final String name;
private final boolean fly;
private final boolean canFly;
private final boolean operator;
private final String group;
private final Location loc;
private final float walkSpeed;
private final float flySpeed;
private BukkitTask timeoutTask = null;
private BukkitTask messageTask = null;
public LimboPlayer(String name, Location loc, boolean operator,
String group, boolean fly) {
this.name = name;
public PlayerData(Location loc, boolean operator,
String group, boolean fly, float walkSpeed, float flySpeed) {
this.loc = loc;
this.operator = operator;
this.group = group;
this.fly = fly;
}
/**
* Return the name of the player.
*
* @return The player's name
*/
public String getName() {
return name;
this.canFly = fly;
this.walkSpeed = walkSpeed;
this.flySpeed = flySpeed;
}
/**
@ -40,7 +33,7 @@ public class LimboPlayer {
*
* @return The player's location
*/
public Location getLoc() {
public Location getLocation() {
return loc;
}
@ -62,8 +55,16 @@ public class LimboPlayer {
return group;
}
public boolean isFly() {
return fly;
public boolean isCanFly() {
return canFly;
}
public float getWalkSpeed() {
return walkSpeed;
}
public float getFlySpeed() {
return flySpeed;
}
/**

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
@ -37,6 +38,9 @@ public class RegisterAdminCommand implements ExecutableCommand {
@Inject
private ValidationService validationService;
@Inject
private LimboCache limboCache;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments) {
// Get the player name and password
@ -79,6 +83,7 @@ public class RegisterAdminCommand implements ExecutableCommand {
bukkitService.scheduleSyncDelayedTask(new Runnable() {
@Override
public void run() {
limboCache.restoreData(player);
player.kickPlayer(commandService.retrieveSingle(MessageKey.KICK_FOR_ADMIN_REGISTER));
}
});

View File

@ -9,21 +9,16 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.AuthGroupHandler;
import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.process.Management;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.TeleportationService;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import javax.inject.Inject;
import java.util.List;
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
/**
* Admin command to unregister a player.
*/
@ -45,11 +40,17 @@ public class UnregisterAdminCommand implements ExecutableCommand {
private LimboCache limboCache;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
@Inject
private AuthGroupHandler authGroupHandler;
@Inject
private TeleportationService teleportationService;
@Inject
private Management management;
@Override
public void executeCommand(final CommandSender sender, List<String> arguments) {
@ -74,35 +75,11 @@ public class UnregisterAdminCommand implements ExecutableCommand {
playerCache.removePlayer(playerNameLowerCase);
authGroupHandler.setGroup(target, AuthGroupType.UNREGISTERED);
if (target != null && target.isOnline()) {
if (commandService.getProperty(RegistrationSettings.FORCE)) {
applyUnregisteredEffectsAndTasks(target);
}
commandService.send(target, MessageKey.UNREGISTERED_SUCCESS);
management.performUnregister(target, "dontneed", true);
}
// Show a status message
commandService.send(sender, MessageKey.UNREGISTERED_SUCCESS);
ConsoleLogger.info(sender.getName() + " unregistered " + playerName);
}
/**
* When registration is forced, applies the configured "unregistered effects" to the player as he
* would encounter when joining the server before logging on - reminder task to log in,
* timeout kick, blindness.
*
* @param target the player that was unregistered
*/
private void applyUnregisteredEffectsAndTasks(Player target) {
// TODO #765: Remove use of Utils method and behave according to settings
Utils.teleportToSpawn(target);
limboCache.addLimboPlayer(target);
limboPlayerTaskManager.registerTimeoutTask(target);
limboPlayerTaskManager.registerMessageTask(target.getName(), false);
final int timeout = commandService.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
if (commandService.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
}
}
}

View File

@ -4,7 +4,6 @@ import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.SessionManager;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;

View File

@ -12,6 +12,7 @@ import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.TeleportationService;
import fr.xephi.authme.util.Utils;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -72,6 +73,8 @@ public class AuthMePlayerListener implements Listener {
private OnJoinVerifier onJoinVerifier;
@Inject
private ListenerService listenerService;
@Inject
private TeleportationService teleportationService;
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
@ -191,6 +194,7 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(priority = EventPriority.LOW)
public void onPlayerJoin(PlayerJoinEvent event) {
final Player player = event.getPlayer();
teleportationService.teleportNewPlayerToFirstSpawn(player);
management.performJoin(player);
}
@ -229,6 +233,7 @@ public class AuthMePlayerListener implements Listener {
}
antiBot.handlePlayerJoin(player);
teleportationService.teleportOnJoin(player);
}
@EventHandler(priority = EventPriority.HIGHEST)

View File

@ -24,7 +24,6 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.settings.Settings;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@ -52,8 +51,7 @@ class AuthMeInventoryPacketAdapter extends PacketAdapter {
PacketContainer packet = packetEvent.getPacket();
byte windowId = packet.getIntegers().read(0).byteValue();
if (windowId == PLAYER_INVENTORY && Settings.protectInventoryBeforeLogInEnabled
&& !PlayerCache.getInstance().isAuthenticated(player.getName())) {
if (windowId == PLAYER_INVENTORY && !PlayerCache.getInstance().isAuthenticated(player.getName())) {
packetEvent.setCancelled(true);
}
}
@ -66,10 +64,6 @@ class AuthMeInventoryPacketAdapter extends PacketAdapter {
ProtocolLibrary.getProtocolManager().removePacketListener(this);
}
public void sendInventoryPacket(Player player) {
player.updateInventory();
}
public void sendBlankInventoryPacket(Player player) {
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
PacketContainer inventoryPacket = protocolManager.createPacket(PacketType.Play.Server.WINDOW_ITEMS);

View File

@ -7,7 +7,6 @@ import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.initialization.SettingsDependent;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player;
import javax.inject.Inject;
@ -25,12 +24,10 @@ public class ProtocolLibService implements SettingsDependent, Reloadable {
/* Service */
private boolean isEnabled;
private AuthMe plugin;
private BukkitService bukkitService;
@Inject
ProtocolLibService(AuthMe plugin, BukkitService bukkitService, NewSetting settings) {
ProtocolLibService(AuthMe plugin, NewSetting settings) {
this.plugin = plugin;
this.bukkitService = bukkitService;
loadSettings(settings);
setup();
}
@ -85,17 +82,6 @@ public class ProtocolLibService implements SettingsDependent, Reloadable {
}
}
/**
* Send a packet to the player to give them an inventory.
*
* @param player The player to send the packet to.
*/
public void sendInventoryPacket(Player player) {
if (isEnabled && inventoryPacketAdapter != null) {
inventoryPacketAdapter.sendInventoryPacket(player);
}
}
/**
* Send a packet to the player to give them a blank inventory.
*

View File

@ -2,10 +2,11 @@ package fr.xephi.authme.permission;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.entity.Player;
import javax.inject.Inject;
@ -51,34 +52,61 @@ public class AuthGroupHandler {
switch (group) {
case UNREGISTERED:
// Remove the other group type groups, set the current group
permissionsManager.removeGroups(player, Arrays.asList(Settings.getRegisteredGroup, Settings.getUnloggedinGroup));
permissionsManager.removeGroups(player, Arrays.asList(Settings.getRegisteredGroup, settings.getProperty(SecuritySettings.UNLOGGEDIN_GROUP)));
return permissionsManager.addGroup(player, Settings.unRegisteredGroup);
case REGISTERED:
// Remove the other group type groups, set the current group
permissionsManager.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup, Settings.getUnloggedinGroup));
permissionsManager.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup, settings.getProperty(SecuritySettings.UNLOGGEDIN_GROUP)));
return permissionsManager.addGroup(player, Settings.getRegisteredGroup);
case NOT_LOGGED_IN:
// Remove the other group type groups, set the current group
permissionsManager.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup, Settings.getRegisteredGroup));
return permissionsManager.addGroup(player, Settings.getUnloggedinGroup);
return permissionsManager.addGroup(player, settings.getProperty(SecuritySettings.UNLOGGEDIN_GROUP));
case LOGGED_IN:
// Get the limbo player data
LimboPlayer limbo = limboCache.getLimboPlayer(player.getName().toLowerCase());
if (limbo == null)
// Get the player data
PlayerData data = limboCache.getPlayerData(player.getName().toLowerCase());
if (data == null) {
return false;
}
// Get the players group
String realGroup = limbo.getGroup();
String realGroup = data.getGroup();
// Remove the other group types groups, set the real group
permissionsManager.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup, Settings.getRegisteredGroup, Settings.getUnloggedinGroup));
permissionsManager.removeGroups(player,
Arrays.asList(Settings.unRegisteredGroup, Settings.getRegisteredGroup, settings.getProperty(SecuritySettings.UNLOGGEDIN_GROUP))
);
return permissionsManager.addGroup(player, realGroup);
default:
return false;
}
}
/**
* TODO: This method requires better explanation.
* <p>
* Set the normal group of a player.
*
* @param player The player.
* @param group The normal group.
*
* @return True on success, false on failure.
*/
public boolean addNormal(Player player, String group) {
// Check whether the permissions check is enabled
if (!settings.getProperty(PluginSettings.ENABLE_PERMISSION_CHECK)) {
return false;
}
// Remove old groups
permissionsManager.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup,
Settings.getRegisteredGroup, Settings.getUnloggedinGroup));
// Add the normal group, return the result
return permissionsManager.addGroup(player, group);
}
}

View File

@ -71,11 +71,11 @@ public class SyncProcessManager {
});
}
public void processSyncPlayerQuit(final Player player, final boolean isOp, final boolean needToChange) {
public void processSyncPlayerQuit(final Player player) {
runTask(new Runnable() {
@Override
public void run() {
processSyncronousPlayerQuit.processSyncQuit(player, isOp, needToChange);
processSyncronousPlayerQuit.processSyncQuit(player);
}
});
}

View File

@ -9,7 +9,6 @@ import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.ProtectInventoryEvent;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.permission.PlayerStatePermission;
@ -20,9 +19,8 @@ import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.TeleportationService;
import fr.xephi.authme.util.Utils;
import org.apache.commons.lang.reflect.MethodUtils;
import org.bukkit.GameMode;
@ -63,19 +61,14 @@ public class AsynchronousJoin implements AsynchronousProcess {
@Inject
private PluginHooks pluginHooks;
@Inject
private TeleportationService teleportationService;
@Inject
private BukkitService bukkitService;
@Inject
private ProtocolLibService protocolLibService;
private PlayerDataTaskManager playerDataTaskManager;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
AsynchronousJoin() { }
AsynchronousJoin() {
}
public void processJoin(final Player player) {
@ -122,19 +115,19 @@ public class AsynchronousJoin implements AsynchronousProcess {
return;
}
final boolean isAuthAvailable = database.isAuthAvailable(name);
if (isAuthAvailable) {
limboCache.addPlayerData(player);
service.setGroup(player, AuthGroupType.NOT_LOGGED_IN);
teleportationService.teleportOnJoin(player);
limboCache.updateLimboPlayer(player);
// Protect inventory
if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
ProtectInventoryEvent ev = new ProtectInventoryEvent(player);
bukkitService.callEvent(ev);
if (ev.isCancelled()) {
protocolLibService.sendInventoryPacket(player);
player.updateInventory();
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {
ConsoleLogger.info("ProtectInventoryEvent has been cancelled for " + player.getName() + "...");
}
@ -157,7 +150,9 @@ public class AsynchronousJoin implements AsynchronousProcess {
}
}
} else {
// Not Registered
// Not Registered. Delete old data, load default one.
limboCache.deletePlayerData(player);
limboCache.addPlayerData(player);
// Groups logic
service.setGroup(player, AuthGroupType.UNREGISTERED);
@ -166,13 +161,6 @@ public class AsynchronousJoin implements AsynchronousProcess {
if (!service.getProperty(RegistrationSettings.FORCE)) {
return;
}
teleportationService.teleportOnJoin(player);
}
// The user is not logged in
if (!limboCache.hasLimboPlayer(name)) {
limboCache.addLimboPlayer(player);
}
final int registrationTimeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
@ -200,8 +188,8 @@ public class AsynchronousJoin implements AsynchronousProcess {
});
// Timeout and message task
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, isAuthAvailable);
playerDataTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerMessageTask(name, isAuthAvailable);
}
private boolean isPlayerUnrestricted(String name) {
@ -211,11 +199,12 @@ public class AsynchronousJoin implements AsynchronousProcess {
/**
* Returns whether the name is restricted based on the restriction settings.
*
* @param name The name to check
* @param ip The IP address of the player
* @param name The name to check
* @param ip The IP address of the player
* @param domain The hostname of the IP address
*
* @return True if the name is restricted (IP/domain is not allowed for the given name),
* false if the restrictions are met or if the name has no restrictions to it
* false if the restrictions are met or if the name has no restrictions to it
*/
private boolean isNameRestricted(String name, String ip, String domain) {
if (!service.getProperty(RestrictionSettings.ENABLE_RESTRICTED_USERS)) {
@ -242,7 +231,8 @@ public class AsynchronousJoin implements AsynchronousProcess {
* settings and permissions). If this is the case, the player is kicked.
*
* @param player the player to verify
* @param ip the ip address of the player
* @param ip the ip address of the player
*
* @return true if the verification is OK (no infraction), false if player has been kicked
*/
private boolean validatePlayerCountForIp(final Player player, String ip) {

View File

@ -6,7 +6,7 @@ import fr.xephi.authme.cache.TempbanManager;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.output.MessageKey;
@ -23,11 +23,10 @@ import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
@ -70,24 +69,10 @@ public class AsynchronousLogin implements AsynchronousProcess {
private TempbanManager tempbanManager;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
AsynchronousLogin() { }
/**
* Queries the {@link fr.xephi.authme.cache.CaptchaManager} to
* see if a captcha needs to be entered in order to log in.
*
* @param player The player to check
* @return True if a captcha needs to be entered
*/
private boolean needsCaptcha(Player player) {
final String playerName = player.getName();
return captchaManager.isCaptchaRequired(playerName);
}
/**
* Checks the precondition for authentication (like user known) and returns
* the playerAuth-State
@ -106,7 +91,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
service.send(player, MessageKey.USER_NOT_REGISTERED);
// TODO ljacqu 20160612: Why is the message task being canceled and added again here?
limboPlayerTaskManager.registerMessageTask(name, false);
playerDataTaskManager.registerMessageTask(name, false);
return null;
}
@ -126,7 +111,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
}
AuthMeAsyncPreLoginEvent event = new AuthMeAsyncPreLoginEvent(player);
Bukkit.getServer().getPluginManager().callEvent(event);
bukkitService.callEvent(event);
if (!event.canLogin()) {
return null;
}
@ -142,7 +127,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
final String name = player.getName().toLowerCase();
// If Captcha is required send a message to the player and deny to login
if (needsCaptcha(player)) {
if (captchaManager.isCaptchaRequired(name)) {
service.send(player, MessageKey.USAGE_CAPTCHA, captchaManager.getCaptchaCodeOrGenerateNew(name));
return;
}
@ -197,14 +182,9 @@ public class AsynchronousLogin implements AsynchronousProcess {
// task, we schedule it in the end
// so that we can be sure, and have not to care if it might be
// processed in other order.
LimboPlayer limboPlayer = limboCache.getLimboPlayer(name);
if (limboPlayer != null) {
if (limboPlayer.getTimeoutTask() != null) {
limboPlayer.getTimeoutTask().cancel();
}
if (limboPlayer.getMessageTask() != null) {
limboPlayer.getMessageTask().cancel();
}
PlayerData playerData = limboCache.getPlayerData(name);
if (playerData != null) {
playerData.clearTasks();
}
syncProcessManager.processSyncPlayerLogin(player);
} else if (player.isOnline()) {
@ -224,7 +204,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
service.send(player, MessageKey.WRONG_PASSWORD);
// If the authentication fails check if Captcha is required and send a message to the player
if (needsCaptcha(player)) {
if (captchaManager.isCaptchaRequired(name)) {
service.send(player, MessageKey.USAGE_CAPTCHA, captchaManager.getCaptchaCodeOrGenerateNew(name));
}
}

View File

@ -2,25 +2,16 @@ package fr.xephi.authme.process.login;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
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.protocollib.ProtocolLibService;
import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.TeleportationService;
import org.apache.commons.lang.reflect.MethodUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.LivingEntity;
@ -47,37 +38,20 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
@Inject
private LimboCache limboCache;
@Inject
private DataSource dataSource;
@Inject
private BukkitService bukkitService;
@Inject
private ProtocolLibService protocolLibService;
@Inject
private PluginManager pluginManager;
@Inject
private TeleportationService teleportationService;
ProcessSyncPlayerLogin() { }
private void restoreSpeedEffects(Player player) {
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)
&& service.getProperty(RestrictionSettings.REMOVE_SPEED)) {
player.setWalkSpeed(0.2F);
player.setFlySpeed(0.1F);
}
ProcessSyncPlayerLogin() {
}
private void restoreInventory(Player player) {
RestoreInventoryEvent event = new RestoreInventoryEvent(player);
pluginManager.callEvent(event);
if (!event.isCancelled()) {
protocolLibService.sendInventoryPacket(player);
player.updateInventory();
}
}
@ -94,16 +68,12 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
public void processPlayerLogin(Player player) {
final String name = player.getName().toLowerCase();
// Limbo contains the State of the Player before /login
final LimboPlayer limbo = limboCache.getLimboPlayer(name);
final PlayerAuth auth = dataSource.getAuth(name);
if (limbo != null) {
// Restore Op state and Permission Group
restoreOpState(player, limbo);
service.setGroup(player, AuthGroupType.LOGGED_IN);
teleportationService.teleportOnLogin(player, auth, limbo);
if (limboCache.hasPlayerData(name)) {
limboCache.restoreData(player);
limboCache.deletePlayerData(player);
// do we really need to use location from database for now?
// because LimboCache#restoreData teleport player to last location.
//teleportationService.teleportOnLogin(player, auth, limbo);
if (RESTORE_COLLISIONS && !service.getProperty(KEEP_COLLISIONS_DISABLED)) {
player.setCollidable(true);
}
@ -111,9 +81,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
restoreInventory(player);
}
// Clean up no longer used temporary data
limboCache.deleteLimboPlayer(name);
}
// We can now display the join message (if delayed)
@ -129,7 +96,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
AuthMePlayerListener.joinMessage.remove(name);
}
restoreSpeedEffects(player);
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
player.removePotionEffect(PotionEffectType.BLINDNESS);
}
@ -138,6 +104,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
bukkitService.callEvent(new LoginEvent(player));
player.saveData();
sendBungeeMessage(player);
// Login is done, display welcome message
if (service.getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
if (service.getProperty(RegistrationSettings.BROADCAST_WELCOME_MESSAGE)) {
@ -157,15 +124,11 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
sendTo(player);
}
private void restoreOpState(Player player, LimboPlayer limboPlayer) {
player.setOp(limboPlayer.isOperator());
}
private void sendTo(Player player) {
if(!service.getProperty(HooksSettings.BUNGEECORD)) {
if (!service.getProperty(HooksSettings.BUNGEECORD)) {
return;
}
if(service.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
if (service.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
return;
}
@ -176,7 +139,7 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
}
private void sendBungeeMessage(Player player) {
if(!service.getProperty(HooksSettings.BUNGEECORD)) {
if (!service.getProperty(HooksSettings.BUNGEECORD)) {
return;
}

View File

@ -5,12 +5,10 @@ import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.process.SyncProcessManager;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import org.bukkit.entity.Player;
import javax.inject.Inject;
@ -32,10 +30,8 @@ public class AsynchronousLogout implements AsynchronousProcess {
@Inject
private SyncProcessManager syncProcessManager;
@Inject
private BukkitService bukkitService;
AsynchronousLogout() { }
AsynchronousLogout() {
}
public void logout(final Player player) {
final String name = player.getName().toLowerCase();
@ -43,27 +39,20 @@ public class AsynchronousLogout implements AsynchronousProcess {
service.send(player, MessageKey.NOT_LOGGED_IN);
return;
}
PlayerAuth auth = playerCache.getAuth(name);
database.updateSession(auth);
auth.setQuitLocX(player.getLocation().getX());
auth.setQuitLocY(player.getLocation().getY());
auth.setQuitLocZ(player.getLocation().getZ());
auth.setWorld(player.getWorld().getName());
database.updateQuitLoc(auth);
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
auth.setQuitLocX(player.getLocation().getX());
auth.setQuitLocY(player.getLocation().getY());
auth.setQuitLocZ(player.getLocation().getZ());
auth.setWorld(player.getWorld().getName());
database.updateQuitLoc(auth);
}
limboCache.addPlayerData(player);
playerCache.removePlayer(name);
database.setUnlogged(name);
bukkitService.scheduleSyncDelayedTask(new Runnable() {
@Override
public void run() {
Utils.teleportToSpawn(player);
}
});
if (limboCache.hasLimboPlayer(name)) {
limboCache.deleteLimboPlayer(name);
}
limboCache.addLimboPlayer(player);
service.setGroup(player, AuthGroupType.NOT_LOGGED_IN);
syncProcessManager.processSyncPlayerLogout(player);
}
}

View File

@ -8,12 +8,13 @@ import fr.xephi.authme.cache.SessionManager;
import fr.xephi.authme.events.LogoutEvent;
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
@ -39,12 +40,13 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
private ProtocolLibService protocolLibService;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
@Inject
private SessionManager sessionManager;
ProcessSynchronousPlayerLogout() { }
ProcessSynchronousPlayerLogout() {
}
private void sendBungeeMessage(Player player) {
@ -56,14 +58,6 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
}
private void restoreSpeedEffect(Player player) {
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)
&& service.getProperty(RestrictionSettings.REMOVE_SPEED)) {
player.setFlySpeed(0.0f);
player.setWalkSpeed(0.0f);
}
}
public void processSyncLogout(Player player) {
final String name = player.getName().toLowerCase();
if (sessionManager.hasSession(name)) {
@ -73,18 +67,11 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
protocolLibService.sendBlankInventoryPacket(player);
}
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, true);
playerDataTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerMessageTask(name, true);
applyLogoutEffect(player);
if (player.isInsideVehicle() && player.getVehicle() != null) {
player.getVehicle().eject();
}
final int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
}
player.setOp(false);
restoreSpeedEffect(player);
// Player is now logout... Time to fire event !
bukkitService.callEvent(new LogoutEvent(player));
if (service.getProperty(HooksSettings.BUNGEECORD)) {
@ -94,4 +81,26 @@ public class ProcessSynchronousPlayerLogout implements SynchronousProcess {
ConsoleLogger.info(player.getName() + " logged out");
}
private void applyLogoutEffect(Player player) {
// dismount player
player.leaveVehicle();
// Apply Blindness effect
final int timeout = service.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
if (service.getProperty(RegistrationSettings.APPLY_BLIND_EFFECT)) {
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
}
// Set player's data to unauthenticated
service.setGroup(player, AuthGroupType.NOT_LOGGED_IN);
player.setOp(false);
player.setAllowFlight(false);
// Remove speed
if (!service.getProperty(RestrictionSettings.ALLOW_UNAUTHED_MOVEMENT)
&& service.getProperty(RestrictionSettings.REMOVE_SPEED)) {
player.setFlySpeed(0.0f);
player.setWalkSpeed(0.0f);
}
}
}

View File

@ -4,16 +4,15 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.cache.SessionManager;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.datasource.CacheDataSource;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.process.AsynchronousProcess;
import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.process.SyncProcessManager;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -37,16 +36,20 @@ public class AsynchronousQuit implements AsynchronousProcess {
@Inject
private PlayerCache playerCache;
@Inject
private LimboCache limboCache;
@Inject
private SyncProcessManager syncProcessManager;
@Inject
private SessionManager sessionManager;
AsynchronousQuit() { }
@Inject
private SpawnLoader spawnLoader;
@Inject
private BukkitService bukkitService;
AsynchronousQuit() {
}
public void processQuit(Player player, boolean isKick) {
@ -56,10 +59,9 @@ public class AsynchronousQuit implements AsynchronousProcess {
final String name = player.getName().toLowerCase();
String ip = Utils.getPlayerIp(player);
if (playerCache.isAuthenticated(name)) {
if (service.getProperty(RestrictionSettings.SAVE_QUIT_LOCATION)) {
Location loc = player.getLocation();
Location loc = spawnLoader.getPlayerLocationOrSpawn(player);
PlayerAuth auth = PlayerAuth.builder()
.name(name).location(loc)
.realName(player.getName()).build();
@ -74,24 +76,11 @@ public class AsynchronousQuit implements AsynchronousProcess {
database.updateSession(auth);
}
boolean needToChange = false;
boolean isOp = false;
LimboPlayer limbo = limboCache.getLimboPlayer(name);
if (limbo != null) {
if (!StringUtils.isEmpty(limbo.getGroup())) {
Utils.addNormal(player, limbo.getGroup());
}
needToChange = true;
isOp = limbo.isOperator();
limboCache.deleteLimboPlayer(name);
}
//always unauthenticate the player - use session only for auto logins on the same ip
playerCache.removePlayer(name);
if (plugin.isEnabled() && service.getProperty(PluginSettings.SESSIONS_ENABLED)) {
BukkitTask task = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() {
BukkitTask task = bukkitService.runTaskLaterAsynchronously(new Runnable() {
@Override
public void run() {
@ -110,7 +99,7 @@ public class AsynchronousQuit implements AsynchronousProcess {
database.setUnlogged(name);
if (plugin.isEnabled()) {
syncProcessManager.processSyncPlayerQuit(player, isOp, needToChange);
syncProcessManager.processSyncPlayerQuit(player);
}
// remove player from cache
if (database instanceof CacheDataSource) {

View File

@ -1,15 +1,32 @@
package fr.xephi.authme.process.quit;
import fr.xephi.authme.cache.backup.PlayerDataStorage;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.process.SynchronousProcess;
import org.bukkit.entity.Player;
import javax.inject.Inject;
public class ProcessSyncronousPlayerQuit implements SynchronousProcess {
public void processSyncQuit(Player player, boolean isOp, boolean needToChange) {
if (needToChange) {
player.setOp(isOp);
@Inject
private PlayerDataStorage playerDataStorage;
@Inject
private LimboCache limboCache;
public void processSyncQuit(Player player) {
if (limboCache.hasPlayerData(player.getName())) { // it mean player is not authenticated
limboCache.restoreData(player);
limboCache.removeFromCache(player);
} else {
// Save player's data, so we could retrieve it later on player next join
if (!playerDataStorage.hasData(player)) {
playerDataStorage.saveData(player);
}
}
player.leaveVehicle();
}
}

View File

@ -7,7 +7,7 @@ import fr.xephi.authme.process.ProcessService;
import fr.xephi.authme.process.SynchronousProcess;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.Utils;
import org.bukkit.entity.Player;
@ -20,7 +20,7 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
private ProcessService service;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
ProcessSyncEmailRegister() { }
@ -32,8 +32,8 @@ public class ProcessSyncEmailRegister implements SynchronousProcess {
}
service.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, true);
playerDataTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerMessageTask(name, true);
player.saveData();
if (!service.getProperty(SecuritySettings.REMOVE_SPAM_FROM_CONSOLE)) {

View File

@ -5,10 +5,8 @@ import com.google.common.io.ByteStreams;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.events.LoginEvent;
import fr.xephi.authme.events.RestoreInventoryEvent;
import fr.xephi.authme.listener.protocollib.ProtocolLibService;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.permission.AuthGroupType;
import fr.xephi.authme.process.ProcessService;
@ -18,7 +16,7 @@ import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils;
import org.bukkit.Bukkit;
@ -42,16 +40,14 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
@Inject
private BukkitService bukkitService;
@Inject
private ProtocolLibService protocolLibService;
@Inject
private LimboCache limboCache;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
ProcessSyncPasswordRegister() { }
ProcessSyncPasswordRegister() {
}
private void sendBungeeMessage(Player player) {
@ -69,7 +65,7 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
}
for (String command : service.getProperty(RegistrationSettings.FORCE_REGISTER_COMMANDS_AS_CONSOLE)) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(),
command.replace("%p", player.getName()));
command.replace("%p", player.getName()));
}
}
@ -80,11 +76,9 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
*/
private void requestLogin(Player player) {
final String name = player.getName().toLowerCase();
Utils.teleportToSpawn(player);
limboCache.updateLimboPlayer(player);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, true);
limboCache.updatePlayerData(player);
playerDataTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerMessageTask(name, true);
if (player.isInsideVehicle() && player.getVehicle() != null) {
player.getVehicle().eject();
@ -93,19 +87,16 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
public void processPasswordRegister(Player player) {
final String name = player.getName().toLowerCase();
LimboPlayer limbo = limboCache.getLimboPlayer(name);
if (limbo != null) {
Utils.teleportToSpawn(player);
if (limboCache.hasPlayerData(name)) {
if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
RestoreInventoryEvent event = new RestoreInventoryEvent(player);
bukkitService.callEvent(event);
if (!event.isCancelled()) {
protocolLibService.sendInventoryPacket(player);
player.updateInventory();
}
}
limboCache.deleteLimboPlayer(name);
limboCache.restoreData(player);
limboCache.deletePlayerData(player);
}
if (!Settings.getRegisteredGroup.isEmpty()) {

View File

@ -13,8 +13,8 @@ import fr.xephi.authme.security.PasswordSecurity;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.RegistrationSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.task.LimboPlayerTaskManager;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.task.PlayerDataTaskManager;
import fr.xephi.authme.util.TeleportationService;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
@ -41,7 +41,10 @@ public class AsynchronousUnregister implements AsynchronousProcess {
private LimboCache limboCache;
@Inject
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
@Inject
private TeleportationService teleportationService;
AsynchronousUnregister() { }
@ -56,18 +59,19 @@ public class AsynchronousUnregister implements AsynchronousProcess {
}
if (service.getProperty(RegistrationSettings.FORCE)) {
Utils.teleportToSpawn(player);
teleportationService.teleportOnJoin(player);
player.saveData();
playerCache.removePlayer(player.getName().toLowerCase());
if (!Settings.getRegisteredGroup.isEmpty()) {
service.setGroup(player, AuthGroupType.UNREGISTERED);
}
limboCache.addLimboPlayer(player);
limboPlayerTaskManager.registerTimeoutTask(player);
limboPlayerTaskManager.registerMessageTask(name, false);
limboCache.deletePlayerData(player);
limboCache.addPlayerData(player);
playerDataTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerMessageTask(name, false);
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
ConsoleLogger.info(player.getName() + " unregistered himself");
return; // TODO ljacqu 20160612: Why return here? No blind effect? Player not removed from PlayerCache?
}
if (!Settings.unRegisteredGroup.isEmpty()) {
@ -81,7 +85,7 @@ public class AsynchronousUnregister implements AsynchronousProcess {
player.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, timeout, 2));
}
service.send(player, MessageKey.UNREGISTERED_SUCCESS);
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
ConsoleLogger.info(player.getName() + " unregistered himself");
} else {
service.send(player, MessageKey.WRONG_PASSWORD);
}

View File

@ -3,9 +3,7 @@ package fr.xephi.authme.security.crypts;
/**
* Public interface for custom password encryption methods.
* <p>
* Note that {@link fr.xephi.authme.security.PasswordSecurity} requires classes implementing this interface
* to either have the default constructor or an accessible constructor with one parameter of type
* {@link fr.xephi.authme.settings.NewSetting}.
* Instantiation of these methods is done via automatic dependency injection.
*/
public interface EncryptionMethod {

View File

@ -2,7 +2,6 @@ package fr.xephi.authme.settings;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.settings.domain.Property;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.bukkit.configuration.file.FileConfiguration;
@ -16,18 +15,12 @@ import java.util.List;
public final class Settings {
public static List<String> getUnrestrictedName;
public static boolean isPermissionCheckEnabled;
public static boolean isTeleportToSpawnEnabled;
public static boolean isAllowRestrictedIp;
public static boolean isSaveQuitLocationEnabled;
public static boolean protectInventoryBeforeLogInEnabled;
public static boolean isStopEnabled;
public static boolean reloadSupport;
public static boolean noTeleport;
public static String getUnloggedinGroup;
public static String unRegisteredGroup;
public static String getRegisteredGroup;
public static String defaultWorld;
public static int getNonActivatedGroup;
private static FileConfiguration configFile;
@ -42,20 +35,14 @@ public final class Settings {
}
private static void loadVariables() {
isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK);
isTeleportToSpawnEnabled = load(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN);
isAllowRestrictedIp = load(RestrictionSettings.ENABLE_RESTRICTED_USERS);
isSaveQuitLocationEnabled = load(RestrictionSettings.SAVE_QUIT_LOCATION);
getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP);
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup", "");
getUnrestrictedName = load(RestrictionSettings.UNRESTRICTED_NAMES);
getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup", "");
protectInventoryBeforeLogInEnabled = load(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
defaultWorld = configFile.getString("Purge.defaultWorld", "world");
noTeleport = load(RestrictionSettings.NO_TELEPORT);
}
/**

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.settings;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.initialization.DataFolder;
@ -34,7 +33,6 @@ public class SpawnLoader implements Reloadable {
private final File authMeConfigurationFile;
private final NewSetting settings;
private final PluginHooks pluginHooks;
private final DataSource dataSource;
private FileConfiguration authMeConfiguration;
private String[] spawnPriority;
private Location essentialsSpawn;
@ -43,20 +41,19 @@ public class SpawnLoader implements Reloadable {
* Constructor.
*
* @param pluginFolder The AuthMe data folder
* @param settings The setting instance
* @param pluginHooks The plugin hooks instance
* @param dataSource The plugin auth database instance
* @param settings The setting instance
* @param pluginHooks The plugin hooks instance
* @param dataSource The plugin auth database instance
*/
@Inject
public SpawnLoader(@DataFolder File pluginFolder, NewSetting settings, PluginHooks pluginHooks,
DataSource dataSource) {
SpawnLoader(@DataFolder File pluginFolder, NewSetting settings, PluginHooks pluginHooks,
DataSource dataSource) {
File spawnFile = new File(pluginFolder, "spawn.yml");
// TODO ljacqu 20160312: Check if resource could be copied and handle the case if not
FileUtils.copyFileFromResource(spawnFile, "spawn.yml");
this.authMeConfigurationFile = new File(pluginFolder, "spawn.yml");
this.settings = settings;
this.pluginHooks = pluginHooks;
this.dataSource = dataSource;
reload();
}
@ -83,6 +80,7 @@ public class SpawnLoader implements Reloadable {
* Set the AuthMe spawn point.
*
* @param location The location to use
*
* @return True upon success, false otherwise
*/
public boolean setSpawn(Location location) {
@ -102,6 +100,7 @@ public class SpawnLoader implements Reloadable {
* Set the AuthMe first spawn location.
*
* @param location The location to use
*
* @return True upon success, false otherwise
*/
public boolean setFirstSpawn(Location location) {
@ -140,7 +139,9 @@ public class SpawnLoader implements Reloadable {
* depending on the spawn priority setting.
*
* @param player The player to retrieve the spawn point for
*
* @return The spawn location, or the default spawn location upon failure
*
* @see RestrictionSettings#SPAWN_PRIORITY
*/
public Location getSpawnLocation(Player player) {
@ -166,15 +167,7 @@ public class SpawnLoader implements Reloadable {
spawnLoc = essentialsSpawn;
break;
case "authme":
String playerNameLower = player.getName().toLowerCase();
if (PlayerCache.getInstance().isAuthenticated(playerNameLower)) {
spawnLoc = getSpawn();
} else if (getFirstSpawn() != null && (!player.hasPlayedBefore() ||
!dataSource.isAuthAvailable(playerNameLower))) {
spawnLoc = getFirstSpawn();
} else {
spawnLoc = getSpawn();
}
spawnLoc = getSpawn();
break;
}
if (spawnLoc != null) {
@ -187,8 +180,9 @@ public class SpawnLoader implements Reloadable {
/**
* Save the location under the given prefix.
*
* @param prefix The prefix to save the spawn under
* @param prefix The prefix to save the spawn under
* @param location The location to persist
*
* @return True upon success, false otherwise
*/
private boolean setLocation(String prefix, Location location) {
@ -214,11 +208,26 @@ public class SpawnLoader implements Reloadable {
return false;
}
/**
* Return player's location if player is alive, or player's spawn location if dead.
*
* @param player player to retrieve
*
* @return location of the given player if alive, spawn location if dead.
*/
public Location getPlayerLocationOrSpawn(Player player) {
if (player.isOnline() && player.isDead()) {
return getSpawnLocation(player);
}
return player.getLocation();
}
/**
* Build a {@link Location} object from the given path in the file configuration.
*
* @param configuration The file configuration to read from
* @param pathPrefix The path to get the spawn point from
* @param pathPrefix The path to get the spawn point from
*
* @return Location corresponding to the values in the path
*/
private static Location getLocationFromConfiguration(FileConfiguration configuration, String pathPrefix) {
@ -240,7 +249,8 @@ public class SpawnLoader implements Reloadable {
* under the given path.
*
* @param configuration The file configuration to use
* @param pathPrefix The path to verify
* @param pathPrefix The path to verify
*
* @return True if all spawn fields are present, false otherwise
*/
private static boolean containsAllSpawnFields(FileConfiguration configuration, String pathPrefix) {
@ -257,7 +267,8 @@ public class SpawnLoader implements Reloadable {
* Retrieve a property as a float from the given file configuration.
*
* @param configuration The file configuration to use
* @param path The path of the property to retrieve
* @param path The path of the property to retrieve
*
* @return The float
*/
private static float getFloat(FileConfiguration configuration, String path) {

View File

@ -45,8 +45,8 @@ public class MessageTask implements Runnable {
player.sendMessage(ms);
}
BukkitTask nextTask = bukkitService.runTaskLater(this, interval * TICKS_PER_SECOND);
if (limboCache.hasLimboPlayer(name)) {
limboCache.getLimboPlayer(name).setMessageTask(nextTask);
if (limboCache.hasPlayerData(name)) {
limboCache.getPlayerData(name).setMessageTask(nextTask);
}
return;
}

View File

@ -3,7 +3,7 @@ package fr.xephi.authme.task;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.NewSetting;
@ -18,9 +18,9 @@ import javax.inject.Inject;
import static fr.xephi.authme.util.BukkitService.TICKS_PER_SECOND;
/**
* Registers tasks associated with a LimboPlayer.
* Registers tasks associated with a PlayerData.
*/
public class LimboPlayerTaskManager {
public class PlayerDataTaskManager {
@Inject
private Messages messages;
@ -37,7 +37,8 @@ public class LimboPlayerTaskManager {
@Inject
private PlayerCache playerCache;
LimboPlayerTaskManager() { }
PlayerDataTaskManager() {
}
/**
@ -51,14 +52,14 @@ public class LimboPlayerTaskManager {
final int interval = settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
final MessageKey key = getMessageKey(isRegistered);
if (interval > 0) {
final LimboPlayer limboPlayer = limboCache.getLimboPlayer(name);
if (limboPlayer == null) {
ConsoleLogger.info("LimboPlayer for '" + name + "' is not available");
final PlayerData playerData = limboCache.getPlayerData(name);
if (playerData == null) {
ConsoleLogger.info("PlayerData for '" + name + "' is not available");
} else {
cancelTask(limboPlayer.getMessageTask());
cancelTask(playerData.getMessageTask());
BukkitTask messageTask = bukkitService.runTask(new MessageTask(name, messages.retrieve(key),
interval, bukkitService, limboCache, playerCache));
limboPlayer.setMessageTask(messageTask);
playerData.setMessageTask(messageTask);
}
}
}
@ -71,14 +72,14 @@ public class LimboPlayerTaskManager {
public void registerTimeoutTask(Player player) {
final int timeout = settings.getProperty(RestrictionSettings.TIMEOUT) * TICKS_PER_SECOND;
if (timeout > 0) {
final LimboPlayer limboPlayer = limboCache.getLimboPlayer(player.getName());
if (limboPlayer == null) {
ConsoleLogger.info("LimboPlayer for '" + player.getName() + "' is not available");
final PlayerData playerData = limboCache.getPlayerData(player.getName());
if (playerData == null) {
ConsoleLogger.info("PlayerData for '" + player.getName() + "' is not available");
} else {
cancelTask(limboPlayer.getTimeoutTask());
cancelTask(playerData.getTimeoutTask());
String message = messages.retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR);
BukkitTask task = bukkitService.runTaskLater(new TimeoutTask(player, message, playerCache), timeout);
limboPlayer.setTimeoutTask(task);
playerData.setTimeoutTask(task);
}
}
}

View File

@ -106,6 +106,23 @@ public class BukkitService {
return Bukkit.getScheduler().runTaskAsynchronously(authMe, task);
}
/**
* <b>Asynchronous tasks should never access any API in Bukkit. Great care
* should be taken to assure the thread-safety of asynchronous tasks.</b>
* <p>
* Returns a task that will run asynchronously after the specified number
* of server ticks.
*
* @param task the task to be run
* @param delay the ticks to wait before running the task
* @return a BukkitTask that contains the id number
* @throws IllegalArgumentException if plugin is null
* @throws IllegalArgumentException if task is null
*/
public BukkitTask runTaskLaterAsynchronously(Runnable task, long delay) {
return Bukkit.getScheduler().runTaskLaterAsynchronously(authMe, task, delay);
}
/**
* Broadcast a message to all players.
*

View File

@ -22,7 +22,8 @@ public class FileUtils {
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
*
* @param destinationFile The file to check and copy to (outside of JAR)
* @param resourcePath Absolute path to the resource file (path to file within JAR)
* @param resourcePath Absolute path to the resource file (path to file within JAR)
*
* @return False if the file does not exist and could not be copied, true otherwise
*/
public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
@ -49,4 +50,25 @@ public class FileUtils {
}
return false;
}
/**
* Delete a given directory and all its content.
*
* @param directory The directory to remove
*/
public static void purgeDirectory(File directory) {
if (!directory.isDirectory()) {
return;
}
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File target : files) {
if (target.isDirectory()) {
purgeDirectory(target);
}
target.delete();
}
}
}

View File

@ -2,7 +2,8 @@ package fr.xephi.authme.util;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AbstractTeleportEvent;
import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.events.FirstSpawnTeleportEvent;
@ -39,10 +40,13 @@ public class TeleportationService implements Reloadable {
@Inject
private PlayerCache playerCache;
@Inject
private DataSource dataSource;
private Set<String> spawnOnLoginWorlds;
TeleportationService() { }
TeleportationService() {
}
@PostConstruct
@Override
@ -51,11 +55,20 @@ public class TeleportationService implements Reloadable {
spawnOnLoginWorlds = new HashSet<>(settings.getProperty(RestrictionSettings.FORCE_SPAWN_ON_WORLDS));
}
/**
* Teleports the player according to the settings when he joins.
* <p>
* Note: this is triggered by Bukkit's PlayerLoginEvent, during which you cannot use
* {@link Player#hasPlayedBefore()}: it always returns {@code false}. We trigger teleportation
* from the PlayerLoginEvent and not the PlayerJoinEvent to ensure that the location is overridden
* as fast as possible (cf. <a href="https://github.com/Xephi/AuthMeReloaded/issues/682">AuthMe #682</a>).
*
* @param player the player to process
* @see <a href="https://bukkit.atlassian.net/browse/BUKKIT-3521">BUKKIT-3521: Player.hasPlayedBefore() always false</a>
*/
public void teleportOnJoin(final Player player) {
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
return;
} else if (teleportToFirstSpawn(player)) {
return;
}
if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN) || mustForceSpawnAfterLogin(player.getWorld().getName())) {
@ -63,13 +76,40 @@ public class TeleportationService implements Reloadable {
}
}
public void teleportOnLogin(final Player player, PlayerAuth auth, LimboPlayer limbo) {
/**
* Teleports the player to the first spawn if he is new and the first spawn is configured.
*
* @param player the player to process
*/
public void teleportNewPlayerToFirstSpawn(final Player player) {
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
return;
}
// The world in LimboPlayer is from where the player comes, before any teleportation by AuthMe
String worldName = limbo.getLoc().getWorld().getName();
Location firstSpawn = spawnLoader.getFirstSpawn();
if (firstSpawn == null) {
return;
}
if (!player.hasPlayedBefore() || !dataSource.isAuthAvailable(player.getName())) {
performTeleportation(player, new FirstSpawnTeleportEvent(player, firstSpawn));
}
}
/**
* Teleports the player according to the settings after having successfully logged in.
*
* @param player the player
* @param auth corresponding PlayerAuth object
* @param limbo corresponding PlayerData object
*/
public void teleportOnLogin(final Player player, PlayerAuth auth, PlayerData limbo) {
if (settings.getProperty(RestrictionSettings.NO_TELEPORT)) {
return;
}
// The world in PlayerData is from where the player comes, before any teleportation by AuthMe
String worldName = limbo.getLocation().getWorld().getName();
if (mustForceSpawnAfterLogin(worldName)) {
teleportToSpawn(player, true);
} else if (settings.getProperty(TELEPORT_UNAUTHED_TO_SPAWN)) {
@ -77,7 +117,7 @@ public class TeleportationService implements Reloadable {
Location location = buildLocationFromAuth(player, auth);
teleportBackFromSpawn(player, location);
} else {
teleportBackFromSpawn(player, limbo.getLoc());
teleportBackFromSpawn(player, limbo.getLocation());
}
}
}
@ -95,19 +135,6 @@ public class TeleportationService implements Reloadable {
return new Location(world, auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ());
}
private boolean teleportToFirstSpawn(final Player player) {
if (player.hasPlayedBefore()) {
return false;
}
Location firstSpawn = spawnLoader.getFirstSpawn();
if (firstSpawn == null) {
return false;
}
performTeleportation(player, new FirstSpawnTeleportEvent(player, firstSpawn));
return true;
}
private void teleportBackFromSpawn(final Player player, final Location location) {
performTeleportation(player, new AuthMeTeleportEvent(player, location));
}
@ -122,7 +149,7 @@ public class TeleportationService implements Reloadable {
* by external listeners). Note that not teleportation is performed if the event's location is empty.
*
* @param player the player to teleport
* @param event the event to emit and according to which to teleport
* @param event the event to emit and according to which to teleport
*/
private void performTeleportation(final Player player, final AbstractTeleportEvent event) {
bukkitService.scheduleSyncDelayedTask(new Runnable() {

View File

@ -1,15 +1,10 @@
package fr.xephi.authme.util;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.events.AuthMeTeleportEvent;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.settings.Settings;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.regex.Pattern;
/**
@ -17,41 +12,9 @@ import java.util.regex.Pattern;
*/
public final class Utils {
private static AuthMe plugin = AuthMe.getInstance();
private Utils() {
}
/**
* TODO: This method requires better explanation.
* <p>
* Set the normal group of a player.
*
* @param player The player.
* @param group The normal group.
*
* @return True on success, false on failure.
*/
public static boolean addNormal(Player player, String group) {
if (!Settings.isPermissionCheckEnabled) {
return false;
}
// Get the permissions manager, and make sure it's valid
PermissionsManager permsMan = plugin.getPermissionsManager();
if (permsMan == null) {
ConsoleLogger.showError("Failed to access permissions manager instance, aborting.");
return false;
}
// Remove old groups
permsMan.removeGroups(player, Arrays.asList(Settings.unRegisteredGroup,
Settings.getRegisteredGroup, Settings.getUnloggedinGroup));
// Add the normal group, return the result
return permsMan.addGroup(player, group);
}
@Deprecated
public static boolean isUnrestricted(Player player) {
// TODO ljacqu 20160602: Checking for Settings.isAllowRestrictedIp is wrong! Nothing in the config suggests
@ -60,19 +23,16 @@ public final class Utils {
&& Settings.getUnrestrictedName.contains(player.getName().toLowerCase());
}
@Deprecated
public static void teleportToSpawn(Player player) {
if (Settings.isTeleportToSpawnEnabled && !Settings.noTeleport) {
Location spawn = plugin.getSpawnLocation(player);
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, spawn);
plugin.getServer().getPluginManager().callEvent(tpEvent);
if (!tpEvent.isCancelled()) {
player.teleport(tpEvent.getTo());
}
}
}
/**
* 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 (Exception ignore) {
@ -80,6 +40,13 @@ public final class Utils {
}
}
/**
* Compile Pattern sneaky without throwing Exception.
*
* @param pattern pattern string to compile
*
* @return the given regex compiled into Pattern object.
*/
public static Pattern safePatternCompile(String pattern) {
try {
return Pattern.compile(pattern);

View File

@ -2,6 +2,7 @@ package fr.xephi.authme.command.executable.authme;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.output.MessageKey;
@ -54,6 +55,9 @@ public class RegisterAdminCommandTest {
@Mock
private ValidationService validationService;
@Mock
private LimboCache limboCache;
@BeforeClass
public static void setUpLogger() {
TestHelper.setupLogger();

View File

@ -3,7 +3,7 @@ package fr.xephi.authme.task;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.NewSetting;
@ -28,13 +28,13 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Test for {@link LimboPlayerTaskManager}.
* Test for {@link PlayerDataTaskManager}.
*/
@RunWith(MockitoJUnitRunner.class)
public class LimboPlayerTaskManagerTest {
public class PlayerDataTaskManagerTest {
@InjectMocks
private LimboPlayerTaskManager limboPlayerTaskManager;
private PlayerDataTaskManager playerDataTaskManager;
@Mock
private Messages messages;
@ -60,8 +60,8 @@ public class LimboPlayerTaskManagerTest {
public void shouldRegisterMessageTask() {
// given
String name = "bobby";
LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(limboCache.getLimboPlayer(name)).willReturn(limboPlayer);
PlayerData playerData = mock(PlayerData.class);
given(limboCache.getPlayerData(name)).willReturn(playerData);
MessageKey key = MessageKey.REGISTER_EMAIL_MESSAGE;
given(messages.retrieve(key)).willReturn(new String[]{"Please register!"});
BukkitTask bukkiTask = mock(BukkitTask.class);
@ -70,10 +70,10 @@ public class LimboPlayerTaskManagerTest {
given(settings.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
// when
limboPlayerTaskManager.registerMessageTask(name, false);
playerDataTaskManager.registerMessageTask(name, false);
// then
verify(limboPlayer).setMessageTask(bukkiTask);
verify(playerData).setMessageTask(bukkiTask);
verify(messages).retrieve(key);
}
@ -81,14 +81,14 @@ public class LimboPlayerTaskManagerTest {
public void shouldNotScheduleTaskForMissingLimboPlayer() {
// given
String name = "ghost";
given(limboCache.getLimboPlayer(name)).willReturn(null);
given(limboCache.getPlayerData(name)).willReturn(null);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(5);
// when
limboPlayerTaskManager.registerMessageTask(name, true);
playerDataTaskManager.registerMessageTask(name, true);
// then
verify(limboCache).getLimboPlayer(name);
verify(limboCache).getPlayerData(name);
verifyZeroInteractions(bukkitService);
verifyZeroInteractions(messages);
}
@ -97,28 +97,28 @@ public class LimboPlayerTaskManagerTest {
public void shouldNotScheduleTaskForZeroAsInterval() {
// given
String name = "Tester1";
LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(limboCache.getLimboPlayer(name)).willReturn(limboPlayer);
PlayerData playerData = mock(PlayerData.class);
given(limboCache.getPlayerData(name)).willReturn(playerData);
BukkitTask bukkiTask = mock(BukkitTask.class);
given(bukkitService.runTask(any(MessageTask.class))).willReturn(bukkiTask);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(0);
// when
limboPlayerTaskManager.registerMessageTask(name, true);
playerDataTaskManager.registerMessageTask(name, true);
// then
verifyZeroInteractions(limboPlayer, bukkitService);
verifyZeroInteractions(playerData, bukkitService);
}
@Test
public void shouldCancelExistingMessageTask() {
// given
LimboPlayer limboPlayer = mock(LimboPlayer.class);
PlayerData playerData = mock(PlayerData.class);
BukkitTask existingMessageTask = mock(BukkitTask.class);
given(limboPlayer.getMessageTask()).willReturn(existingMessageTask);
given(playerData.getMessageTask()).willReturn(existingMessageTask);
String name = "bobby";
given(limboCache.getLimboPlayer(name)).willReturn(limboPlayer);
given(limboCache.getPlayerData(name)).willReturn(playerData);
given(messages.retrieve(MessageKey.REGISTER_EMAIL_MESSAGE))
.willReturn(new String[]{"Please register", "Use /register"});
@ -128,10 +128,10 @@ public class LimboPlayerTaskManagerTest {
given(settings.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
// when
limboPlayerTaskManager.registerMessageTask(name, false);
playerDataTaskManager.registerMessageTask(name, false);
// then
verify(limboPlayer).setMessageTask(bukkiTask);
verify(playerData).setMessageTask(bukkiTask);
verify(messages).retrieve(MessageKey.REGISTER_EMAIL_MESSAGE);
verify(existingMessageTask).cancel();
}
@ -142,17 +142,17 @@ public class LimboPlayerTaskManagerTest {
String name = "l33tPlayer";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(limboCache.getLimboPlayer(name)).willReturn(limboPlayer);
PlayerData playerData = mock(PlayerData.class);
given(limboCache.getPlayerData(name)).willReturn(playerData);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(30);
BukkitTask bukkitTask = mock(BukkitTask.class);
given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when
limboPlayerTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerTimeoutTask(player);
// then
verify(limboPlayer).setTimeoutTask(bukkitTask);
verify(playerData).setTimeoutTask(bukkitTask);
verify(bukkitService).runTaskLater(any(TimeoutTask.class), eq(600L)); // 30 * TICKS_PER_SECOND
verify(messages).retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR);
}
@ -163,11 +163,11 @@ public class LimboPlayerTaskManagerTest {
String name = "Phantom_";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
given(limboCache.getLimboPlayer(name)).willReturn(null);
given(limboCache.getPlayerData(name)).willReturn(null);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(27);
// when
limboPlayerTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerTimeoutTask(player);
// then
verifyZeroInteractions(bukkitService, messages);
@ -179,15 +179,15 @@ public class LimboPlayerTaskManagerTest {
String name = "snail";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = mock(LimboPlayer.class);
given(limboCache.getLimboPlayer(name)).willReturn(limboPlayer);
PlayerData playerData = mock(PlayerData.class);
given(limboCache.getPlayerData(name)).willReturn(playerData);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(0);
// when
limboPlayerTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerTimeoutTask(player);
// then
verifyZeroInteractions(limboPlayer, bukkitService);
verifyZeroInteractions(playerData, bukkitService);
}
@Test
@ -196,20 +196,20 @@ public class LimboPlayerTaskManagerTest {
String name = "l33tPlayer";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
LimboPlayer limboPlayer = mock(LimboPlayer.class);
PlayerData playerData = mock(PlayerData.class);
BukkitTask existingTask = mock(BukkitTask.class);
given(limboPlayer.getTimeoutTask()).willReturn(existingTask);
given(limboCache.getLimboPlayer(name)).willReturn(limboPlayer);
given(playerData.getTimeoutTask()).willReturn(existingTask);
given(limboCache.getPlayerData(name)).willReturn(playerData);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);
BukkitTask bukkitTask = mock(BukkitTask.class);
given(bukkitService.runTaskLater(any(TimeoutTask.class), anyLong())).willReturn(bukkitTask);
// when
limboPlayerTaskManager.registerTimeoutTask(player);
playerDataTaskManager.registerTimeoutTask(player);
// then
verify(existingTask).cancel();
verify(limboPlayer).setTimeoutTask(bukkitTask);
verify(playerData).setTimeoutTask(bukkitTask);
verify(bukkitService).runTaskLater(any(TimeoutTask.class), eq(360L)); // 18 * TICKS_PER_SECOND
verify(messages).retrieveSingle(MessageKey.LOGIN_TIMEOUT_ERROR);
}

View File

@ -126,6 +126,7 @@ public class PurgeServiceTest {
verifyScheduledPurgeTask(null, "alpha", "charlie");
}
@SuppressWarnings("unchecked")
@Test
public void shouldRecognizeNoPlayersToPurge() {
// given

View File

@ -2,7 +2,7 @@ package fr.xephi.authme.util;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.cache.limbo.LimboPlayer;
import fr.xephi.authme.cache.limbo.PlayerData;
import fr.xephi.authme.events.FirstSpawnTeleportEvent;
import fr.xephi.authme.events.SpawnTeleportEvent;
import fr.xephi.authme.settings.NewSetting;
@ -92,7 +92,7 @@ public class TeleportationServiceTest {
given(spawnLoader.getFirstSpawn()).willReturn(firstSpawn);
// when
teleportationService.teleportOnJoin(player);
teleportationService.teleportNewPlayerToFirstSpawn(player);
runSyncDelayedTask(bukkitService);
// then
@ -107,7 +107,6 @@ public class TeleportationServiceTest {
// given
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(true);
given(player.isOnline()).willReturn(true);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
@ -135,7 +134,7 @@ public class TeleportationServiceTest {
given(spawnLoader.getFirstSpawn()).willReturn(null);
// when
teleportationService.teleportOnJoin(player);
teleportationService.teleportNewPlayerToFirstSpawn(player);
// then
verify(player, never()).teleport(any(Location.class));
@ -145,10 +144,39 @@ public class TeleportationServiceTest {
}
@Test
public void shouldTeleportPlayerDueToForcedWorld() {
public void shouldNotTeleportPlayerToFirstSpawnIfNoTeleportEnabled() {
// given
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(false);
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(true);
// when
teleportationService.teleportNewPlayerToFirstSpawn(player);
// then
verify(player, never()).teleport(any(Location.class));
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldNotTeleportNotNewPlayerToFirstSpawn() {
// given
Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(true);
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(false);
// when
teleportationService.teleportNewPlayerToFirstSpawn(player);
// then
verify(player, never()).teleport(any(Location.class));
verifyZeroInteractions(bukkitService);
}
@Test
public void shouldTeleportPlayerDueToForcedWorld() {
// given
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
World playerWorld = mock(World.class);
@ -174,7 +202,6 @@ public class TeleportationServiceTest {
public void shouldNotTeleportPlayerForRemovedLocationInEvent() {
// given
final Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(true);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
@ -201,7 +228,6 @@ public class TeleportationServiceTest {
public void shouldNotTeleportPlayerForCanceledEvent() {
// given
final Player player = mock(Player.class);
given(player.hasPlayedBefore()).willReturn(true);
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
given(settings.getProperty(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN)).willReturn(true);
@ -224,7 +250,6 @@ public class TeleportationServiceTest {
verify(player, never()).teleport(any(Location.class));
}
// ---------
// LOGIN
// ---------
@ -234,7 +259,7 @@ public class TeleportationServiceTest {
given(settings.getProperty(RestrictionSettings.NO_TELEPORT)).willReturn(true);
Player player = mock(Player.class);
PlayerAuth auth = mock(PlayerAuth.class);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -252,10 +277,10 @@ public class TeleportationServiceTest {
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
PlayerAuth auth = mock(PlayerAuth.class);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limboLocation.getWorld().getName()).willReturn("forced1");
given(limbo.getLoc()).willReturn(limboLocation);
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -276,10 +301,10 @@ public class TeleportationServiceTest {
Location spawn = mockLocation();
given(spawnLoader.getSpawnLocation(player)).willReturn(spawn);
PlayerAuth auth = mock(PlayerAuth.class);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limboLocation.getWorld().getName()).willReturn("Forced1"); // different case
given(limbo.getLoc()).willReturn(limboLocation);
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -303,9 +328,9 @@ public class TeleportationServiceTest {
Player player = mock(Player.class);
given(player.isOnline()).willReturn(true);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limbo.getLoc()).willReturn(limboLocation);
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -332,9 +357,9 @@ public class TeleportationServiceTest {
given(player.isOnline()).willReturn(true);
World world = mock(World.class);
given(player.getWorld()).willReturn(world);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
Location limboLocation = mockLocation();
given(limbo.getLoc()).willReturn(limboLocation);
given(limbo.getLocation()).willReturn(limboLocation);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -360,9 +385,9 @@ public class TeleportationServiceTest {
given(player.isOnline()).willReturn(true);
World world = mock(World.class);
given(player.getWorld()).willReturn(world);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
Location location = mockLocation();
given(limbo.getLoc()).willReturn(location);
given(limbo.getLocation()).willReturn(location);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -385,9 +410,9 @@ public class TeleportationServiceTest {
given(player.isOnline()).willReturn(true);
World world = mock(World.class);
given(player.getWorld()).willReturn(world);
LimboPlayer limbo = mock(LimboPlayer.class);
PlayerData limbo = mock(PlayerData.class);
Location location = mockLocation();
given(limbo.getLoc()).willReturn(location);
given(limbo.getLocation()).willReturn(location);
// when
teleportationService.teleportOnLogin(player, auth, limbo);
@ -397,6 +422,12 @@ public class TeleportationServiceTest {
verify(player).teleport(location);
}
private static void assertCorrectLocation(Location location, PlayerAuth auth, World world) {
assertThat(location.getX(), equalTo(auth.getQuitLocX()));
assertThat(location.getY(), equalTo(auth.getQuitLocY()));
assertThat(location.getZ(), equalTo(auth.getQuitLocZ()));
assertThat(location.getWorld(), equalTo(world));
}
// We check that the World in Location is set, this method creates a mock World in Location for us
private static Location mockLocation() {
@ -412,11 +443,4 @@ public class TeleportationServiceTest {
.build();
}
private void assertCorrectLocation(Location location, PlayerAuth auth, World world) {
assertThat(location.getX(), equalTo(auth.getQuitLocX()));
assertThat(location.getY(), equalTo(auth.getQuitLocY()));
assertThat(location.getZ(), equalTo(auth.getQuitLocZ()));
assertThat(location.getWorld(), equalTo(world));
}
}

View File

@ -90,4 +90,10 @@ public class UtilsTest {
// then
assertThat(result, equalTo(name));
}
@Test
public void shouldHavePrivateConstructorOnly() {
// given / when / then
TestHelper.validateHasOnlyPrivateEmptyConstructor(Utils.class);
}
}

View File

@ -1,60 +0,0 @@
digraph G {
"PermissionsManager" -> "ValidationService";
"NewSetting" -> "ValidationService";
"DataSource" -> "ValidationService";
"BukkitService" -> "AntiBot";
"PermissionsManager" -> "AntiBot";
"NewSetting" -> "AntiBot";
"Messages" -> "AntiBot";
"BukkitService" -> "TeleportationService";
"PlayerCache" -> "TeleportationService";
"NewSetting" -> "TeleportationService";
"Messages" -> "TeleportationService";
"SpawnLoader" -> "TeleportationService";
"BukkitService" -> "SynchronousProcess";
"PluginManager" -> "SynchronousProcess";
"AuthMe" -> "SynchronousProcess";
"TeleportationService" -> "SynchronousProcess";
"LimboPlayerTaskManager" -> "SynchronousProcess";
"ProcessService" -> "SynchronousProcess";
"LimboCache" -> "SynchronousProcess";
"DataSource" -> "SynchronousProcess";
"BukkitService" -> "TempbanManager";
"Messages" -> "TempbanManager";
"NewSetting" -> "TempbanManager";
"BukkitService" -> "LimboPlayerTaskManager";
"PlayerCache" -> "LimboPlayerTaskManager";
"Messages" -> "LimboPlayerTaskManager";
"NewSetting" -> "LimboPlayerTaskManager";
"LimboCache" -> "LimboPlayerTaskManager";
"PluginManager" -> "PasswordSecurity";
"AuthMeServiceInitializer" -> "PasswordSecurity";
"NewSetting" -> "PasswordSecurity";
"DataSource" -> "PasswordSecurity";
"PluginManager" -> "PluginHooks";
"Server" -> "PermissionsManager";
"PluginManager" -> "PermissionsManager";
"PermissionsManager" -> "LimboCache";
"SpawnLoader" -> "LimboCache";
"@DataFolder" -> "SpawnLoader";
"NewSetting" -> "SpawnLoader";
"PluginHooks" -> "SpawnLoader";
"DataSource" -> "SpawnLoader";
"BukkitService" -> "AsynchronousProcess";
"CaptchaManager" -> "AsynchronousProcess";
"SyncProcessManager" -> "AsynchronousProcess";
"TempbanManager" -> "AsynchronousProcess";
"PlayerCache" -> "AsynchronousProcess";
"PasswordSecurity" -> "AsynchronousProcess";
"LimboCache" -> "AsynchronousProcess";
"DataSource" -> "AsynchronousProcess";
"AuthMe" -> "AsynchronousProcess";
"TeleportationService" -> "AsynchronousProcess";
"LimboPlayerTaskManager" -> "AsynchronousProcess";
"PermissionsManager" -> "AsynchronousProcess";
"ValidationService" -> "AsynchronousProcess";
"ProcessService" -> "AsynchronousProcess";
"PluginHooks" -> "AsynchronousProcess";
"AuthMe" -> "BukkitService";
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 266 KiB