Merge branch 'games647-balancedPurge'

This commit is contained in:
Gabriele C 2016-05-16 16:28:30 +02:00
commit 156b0a40ed
12 changed files with 299 additions and 149 deletions

View File

@ -44,6 +44,11 @@ import fr.xephi.authme.settings.SettingsMigrationService;
import fr.xephi.authme.settings.SpawnLoader;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.settings.properties.EmailSettings;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.settings.properties.PurgeSettings;
@ -51,6 +56,7 @@ import fr.xephi.authme.settings.properties.RestrictionSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
import fr.xephi.authme.settings.propertymap.PropertyMap;
import fr.xephi.authme.task.PurgeTask;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.CollectionUtils;
import fr.xephi.authme.util.FileUtils;
@ -58,6 +64,18 @@ import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.MigrationService;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import org.apache.logging.log4j.LogManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
@ -70,20 +88,6 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
import static fr.xephi.authme.settings.properties.EmailSettings.RECALL_PLAYERS;
/**
* The AuthMe main class.
*/
@ -671,33 +675,22 @@ public class AuthMe extends JavaPlugin {
if (!newSettings.getProperty(PurgeSettings.USE_AUTO_PURGE) || autoPurging) {
return;
}
autoPurging = true;
getServer().getScheduler().runTaskAsynchronously(this, new Runnable() {
@Override
public void run() {
ConsoleLogger.info("AutoPurging the Database...");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -newSettings.getProperty(PurgeSettings.DAYS_BEFORE_REMOVE_PLAYER));
long until = calendar.getTimeInMillis();
List<String> cleared = database.autoPurgeDatabase(until);
if (CollectionUtils.isEmpty(cleared)) {
return;
}
ConsoleLogger.info("AutoPurging the Database: " + cleared.size() + " accounts removed!");
if (newSettings.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES) && pluginHooks.isEssentialsAvailable())
dataManager.purgeEssentials(cleared);
if (newSettings.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
dataManager.purgeDat(cleared);
if (newSettings.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
dataManager.purgeLimitedCreative(cleared);
if (newSettings.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
dataManager.purgeAntiXray(cleared);
if (newSettings.getProperty(PurgeSettings.REMOVE_PERMISSIONS))
dataManager.purgePermissions(cleared);
ConsoleLogger.info("AutoPurge Finished!");
autoPurging = false;
}
});
ConsoleLogger.info("AutoPurging the Database...");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -newSettings.getProperty(PurgeSettings.DAYS_BEFORE_REMOVE_PLAYER));
long until = calendar.getTimeInMillis();
Set<String> cleared = database.autoPurgeDatabase(until);
if (CollectionUtils.isEmpty(cleared)) {
return;
}
ConsoleLogger.info("AutoPurging the Database: " + cleared.size() + " accounts removed!");
ConsoleLogger.info("Purging user accounts...");
new PurgeTask(plugin, Bukkit.getConsoleSender(), cleared, true, Bukkit.getOfflinePlayers())
.runTaskTimer(plugin, 0, 1);
}
// Return the spawn location of a player
@ -808,4 +801,7 @@ public class AuthMe extends JavaPlugin {
return pluginHooks;
}
public void notifyAutoPurgeEnd() {
this.autoPurging = false;
}
}

View File

@ -6,16 +6,14 @@ import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.util.BukkitService;
import fr.xephi.authme.util.Utils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import javax.inject.Inject;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static fr.xephi.authme.util.StringUtils.makePath;
import java.util.Set;
/**
*/
@ -34,25 +32,14 @@ public class DataManager {
DataManager() { }
private List<OfflinePlayer> getOfflinePlayers(List<String> names) {
List<OfflinePlayer> result = new ArrayList<>();
for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {
for (String name : names) {
if (name.equalsIgnoreCase(op.getName())) {
result.add(op);
}
}
}
return result;
}
public void purgeAntiXray(List<String> cleared) {
public void purgeAntiXray(Set<String> cleared) {
int i = 0;
File dataFolder = new File("." + File.separator + "plugins" + File.separator + "AntiXRayData"
+ File.separator + "PlayerData");
if (!dataFolder.exists() || !dataFolder.isDirectory()) {
return;
}
for (String file : dataFolder.list()) {
if (cleared.contains(file.toLowerCase())) {
File playerFile = new File(dataFolder, file);
@ -61,10 +48,11 @@ public class DataManager {
}
}
}
ConsoleLogger.info("AutoPurge: Removed " + i + " AntiXRayData Files");
}
public synchronized void purgeLimitedCreative(List<String> cleared) {
public synchronized void purgeLimitedCreative(Set<String> cleared) {
int i = 0;
File dataFolder = new File("." + File.separator + "plugins" + File.separator + "LimitedCreative"
+ File.separator + "inventories");
@ -101,17 +89,18 @@ public class DataManager {
ConsoleLogger.info("AutoPurge: Removed " + i + " LimitedCreative Survival, Creative and Adventure files");
}
public synchronized void purgeDat(List<String> cleared) {
public synchronized void purgeDat(Set<OfflinePlayer> cleared) {
int i = 0;
File dataFolder = new File(server.getWorldContainer(),
makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players"));
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
for (OfflinePlayer player : offlinePlayers) {
File playerFile = new File(dataFolder, Utils.getUUIDorName(player) + ".dat");
File dataFolder = new File(server.getWorldContainer()
, makePath(settings.getProperty(PurgeSettings.DEFAULT_WORLD), "players"));
for (OfflinePlayer offlinePlayer : cleared) {
File playerFile = new File(dataFolder, Utils.getUUIDorName(offlinePlayer) + ".dat");
if (playerFile.delete()) {
i++;
}
}
ConsoleLogger.info("AutoPurge: Removed " + i + " .dat Files");
}
@ -120,7 +109,7 @@ public class DataManager {
*
* @param cleared List of String
*/
public void purgeEssentials(List<String> cleared) {
public void purgeEssentials(Set<OfflinePlayer> cleared) {
int i = 0;
File essentialsDataFolder = pluginHooks.getEssentialsDataFolder();
if (essentialsDataFolder == null) {
@ -132,9 +121,9 @@ public class DataManager {
if (!userDataFolder.exists() || !userDataFolder.isDirectory()) {
return;
}
List<OfflinePlayer> offlinePlayers = getOfflinePlayers(cleared);
for (OfflinePlayer player : offlinePlayers) {
File playerFile = new File(userDataFolder, Utils.getUUIDorName(player) + ".yml");
for (OfflinePlayer offlinePlayer : cleared) {
File playerFile = new File(userDataFolder, Utils.getUUIDorName(offlinePlayer) + ".yml");
if (playerFile.exists() && playerFile.delete()) {
i++;
}
@ -145,10 +134,12 @@ public class DataManager {
// TODO: What is this method for? Is it correct?
// TODO: Make it work with OfflinePlayers group data.
public synchronized void purgePermissions(List<String> cleared) {
for (String name : cleared) {
public synchronized void purgePermissions(Set<OfflinePlayer> cleared) {
for (OfflinePlayer offlinePlayer : cleared) {
String name = offlinePlayer.getName();
permissionsManager.removeAllGroups(bukkitService.getPlayerExact(name));
}
ConsoleLogger.info("AutoPurge: Removed permissions from " + cleared.size() + " player(s).");
}
}

View File

@ -4,15 +4,18 @@ import fr.xephi.authme.AuthMe;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.task.PurgeTask;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
/**
* Command for purging data of banned players. Depending on the settings
@ -23,9 +26,6 @@ public class PurgeBannedPlayersCommand implements ExecutableCommand {
@Inject
private DataSource dataSource;
@Inject
private PluginHooks pluginHooks;
@Inject
private AuthMe plugin;
@ -35,24 +35,18 @@ public class PurgeBannedPlayersCommand implements ExecutableCommand {
@Override
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
// Get the list of banned players
List<String> bannedPlayers = new ArrayList<>();
for (OfflinePlayer offlinePlayer : bukkitService.getBannedPlayers()) {
bannedPlayers.add(offlinePlayer.getName().toLowerCase());
Set<String> namedBanned = new HashSet<>();
Set<OfflinePlayer> bannedPlayers = bukkitService.getBannedPlayers();
for (OfflinePlayer offlinePlayer : bannedPlayers) {
namedBanned.add(offlinePlayer.getName().toLowerCase());
}
//todo: note this should may run async because it may executes a SQL-Query
// Purge the banned players
dataSource.purgeBanned(bannedPlayers);
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)
&& pluginHooks.isEssentialsAvailable())
plugin.dataManager.purgeEssentials(bannedPlayers);
if (commandService.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
plugin.dataManager.purgeDat(bannedPlayers);
if (commandService.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
plugin.dataManager.purgeLimitedCreative(bannedPlayers);
if (commandService.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
plugin.dataManager.purgeAntiXray(bannedPlayers);
dataSource.purgeBanned(namedBanned);
// Show a status message
sender.sendMessage("[AuthMe] Database has been purged correctly");
sender.sendMessage(ChatColor.GOLD + "Purging user accounts...");
new PurgeTask(plugin, sender, namedBanned, bannedPlayers).runTaskTimer(plugin, 0, 1);
}
}

View File

@ -5,13 +5,15 @@ import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.hooks.PluginHooks;
import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.task.PurgeTask;
import fr.xephi.authme.util.BukkitService;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Calendar;
import java.util.List;
import java.util.Set;
/**
* Command for purging the data of players which have not been since for a given number
@ -27,6 +29,9 @@ public class PurgeCommand implements ExecutableCommand {
@Inject
private PluginHooks pluginHooks;
@Inject
private BukkitService bukkitService;
@Inject
private AuthMe plugin;
@ -56,24 +61,13 @@ public class PurgeCommand implements ExecutableCommand {
calendar.add(Calendar.DATE, -days);
long until = calendar.getTimeInMillis();
//todo: note this should may run async because it may executes a SQL-Query
// Purge the data, get the purged values
List<String> purged = dataSource.autoPurgeDatabase(until);
Set<String> purged = dataSource.autoPurgeDatabase(until);
// Show a status message
sender.sendMessage(ChatColor.GOLD + "Deleted " + purged.size() + " user accounts");
// Purge other data
if (commandService.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)
&& pluginHooks.isEssentialsAvailable())
plugin.dataManager.purgeEssentials(purged);
if (commandService.getProperty(PurgeSettings.REMOVE_PLAYER_DAT))
plugin.dataManager.purgeDat(purged);
if (commandService.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES))
plugin.dataManager.purgeLimitedCreative(purged);
if (commandService.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE))
plugin.dataManager.purgeAntiXray(purged);
// Show a status message
sender.sendMessage(ChatColor.GREEN + "[AuthMe] Database has been purged correctly");
sender.sendMessage(ChatColor.GOLD + "Purging user accounts...");
new PurgeTask(plugin, sender, purged).runTaskTimer(plugin, 0, 1);
}
}

View File

@ -1,11 +1,5 @@
package fr.xephi.authme.datasource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@ -20,8 +14,13 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
import fr.xephi.authme.security.crypts.HashedPassword;
/**
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class CacheDataSource implements DataSource {
private final DataSource source;
@ -140,11 +139,12 @@ public class CacheDataSource implements DataSource {
}
@Override
public List<String> autoPurgeDatabase(long until) {
List<String> cleared = source.autoPurgeDatabase(until);
public Set<String> autoPurgeDatabase(long until) {
Set<String> cleared = source.autoPurgeDatabase(until);
for (String name : cleared) {
cachedAuths.invalidate(name);
}
return cleared;
}
@ -190,7 +190,7 @@ public class CacheDataSource implements DataSource {
}
@Override
public synchronized void purgeBanned(final List<String> banned) {
public synchronized void purgeBanned(final Set<String> banned) {
source.purgeBanned(banned);
cachedAuths.invalidateAll(banned);
}

View File

@ -5,6 +5,7 @@ import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.security.crypts.HashedPassword;
import java.util.List;
import java.util.Set;
/**
* Interface for manipulating {@link PlayerAuth} objects from a data source.
@ -75,7 +76,7 @@ public interface DataSource extends Reloadable {
* @param until The minimum last login
* @return The account names that have been removed
*/
List<String> autoPurgeDatabase(long until);
Set<String> autoPurgeDatabase(long until);
/**
* Remove a user record from the database.
@ -127,7 +128,7 @@ public interface DataSource extends Reloadable {
*
* @param banned the list of players to delete
*/
void purgeBanned(List<String> banned);
void purgeBanned(Set<String> banned);
/**
* Return the data source type.

View File

@ -17,7 +17,9 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Deprecated flat file datasource. The only method guaranteed to work is {@link FlatFile#getAllAuths()}
@ -227,11 +229,11 @@ public class FlatFile implements DataSource {
}
@Override
public List<String> autoPurgeDatabase(long until) {
public Set<String> autoPurgeDatabase(long until) {
BufferedReader br = null;
BufferedWriter bw = null;
ArrayList<String> lines = new ArrayList<>();
List<String> cleared = new ArrayList<>();
Set<String> cleared = new HashSet<>();
try {
br = new BufferedReader(new FileReader(source));
String line;
@ -256,6 +258,7 @@ public class FlatFile implements DataSource {
silentClose(br);
silentClose(bw);
}
return cleared;
}
@ -414,7 +417,7 @@ public class FlatFile implements DataSource {
}
@Override
public void purgeBanned(List<String> banned) {
public void purgeBanned(Set<String> banned) {
BufferedReader br = null;
BufferedWriter bw = null;
ArrayList<String> lines = new ArrayList<>();

View File

@ -1,16 +1,5 @@
package fr.xephi.authme.datasource;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import com.google.common.annotations.VisibleForTesting;
import com.zaxxer.hikari.HikariDataSource;
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
@ -27,8 +16,19 @@ import fr.xephi.authme.settings.properties.HooksSettings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.StringUtils;
/**
*/
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class MySQL implements DataSource {
private final String host;
@ -611,8 +611,8 @@ public class MySQL implements DataSource {
}
@Override
public synchronized List<String> autoPurgeDatabase(long until) {
List<String> list = new ArrayList<>();
public synchronized Set<String> autoPurgeDatabase(long until) {
Set<String> list = new HashSet<>();
String select = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
String delete = "DELETE FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
try (Connection con = getConnection();
@ -629,6 +629,7 @@ public class MySQL implements DataSource {
} catch (SQLException ex) {
logSqlException(ex);
}
return list;
}
@ -739,7 +740,7 @@ public class MySQL implements DataSource {
}
@Override
public synchronized void purgeBanned(List<String> banned) {
public synchronized void purgeBanned(Set<String> banned) {
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
for (String name : banned) {

View File

@ -7,7 +7,9 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.common.annotations.VisibleForTesting;
@ -291,8 +293,8 @@ public class SQLite implements DataSource {
}
@Override
public List<String> autoPurgeDatabase(long until) {
List<String> list = new ArrayList<>();
public Set<String> autoPurgeDatabase(long until) {
Set<String> list = new HashSet<>();
String select = "SELECT " + col.NAME + " FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
String delete = "DELETE FROM " + tableName + " WHERE " + col.LAST_LOGIN + "<?;";
try (PreparedStatement selectPst = con.prepareStatement(select);
@ -308,6 +310,7 @@ public class SQLite implements DataSource {
} catch (SQLException ex) {
logSqlException(ex);
}
return list;
}
@ -441,7 +444,7 @@ public class SQLite implements DataSource {
}
@Override
public void purgeBanned(List<String> banned) {
public void purgeBanned(Set<String> banned) {
String sql = "DELETE FROM " + tableName + " WHERE " + col.NAME + "=?;";
try (PreparedStatement pst = con.prepareStatement(sql)) {
for (String name : banned) {

View File

@ -0,0 +1,158 @@
package fr.xephi.authme.task;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.PurgeSettings;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
public class PurgeTask extends BukkitRunnable {
//how many players we should check for each tick
private static final int INTERVALL_CHECK = 5;
private final AuthMe plugin;
private final NewSetting newSetting;
private final UUID sender;
private final Set<String> toPurge;
private final OfflinePlayer[] offlinePlayers;
private final boolean autoPurging;
private final int totalPurgeCount;
private int currentPage = 0;
public PurgeTask(AuthMe plugin, CommandSender sender, Set<String> purged) {
this(plugin, sender, purged, false, Bukkit.getOfflinePlayers());
}
public PurgeTask(AuthMe plugin, CommandSender sender, Set<String> purged, Set<OfflinePlayer> offlinePlayers) {
this(plugin, sender, purged, false
, offlinePlayers.toArray(new OfflinePlayer[offlinePlayers.size()]));
}
public PurgeTask(AuthMe plugin, CommandSender sender, Set<String> purged
, boolean autoPurge, OfflinePlayer[] offlinePlayers) {
this.plugin = plugin;
this.newSetting = plugin.getSettings();
if (sender instanceof Player) {
this.sender = ((Player) sender).getUniqueId();
} else {
this.sender = null;
}
this.toPurge = purged;
this.totalPurgeCount = purged.size();
this.autoPurging = autoPurge;
this.offlinePlayers = offlinePlayers;
//this is commented out because I assume all players in the database already have an lowercase name
// toPurge = new HashSet<>(purged.size());
//make a new list with lowercase names to make the username test based on a hash
// for (String username : purged) {
// toPurge.add(username.toLowerCase());
// }
}
@Override
public void run() {
if (toPurge.isEmpty()) {
//everything was removed
finish();
return;
}
Set<OfflinePlayer> playerPortion = new HashSet<OfflinePlayer>(INTERVALL_CHECK);
Set<String> namePortion = new HashSet<String>(INTERVALL_CHECK);
for (int i = 0; i < INTERVALL_CHECK; i++) {
int nextPosition = (currentPage * INTERVALL_CHECK) + i;
if (offlinePlayers.length >= nextPosition) {
//no more offline players on this page
break;
}
OfflinePlayer offlinePlayer = offlinePlayers[nextPosition];
String offlineName = offlinePlayer.getName();
//remove to speed up later lookups
if (toPurge.remove(offlineName.toLowerCase())) {
playerPortion.add(offlinePlayer);
namePortion.add(offlinePlayer.getName());
}
}
if (!toPurge.isEmpty() && playerPortion.isEmpty()) {
ConsoleLogger.info("Finished lookup up offlinePlayers. Begin looking purging player names only");
//we went through all offlineplayers but there are still names remaining
namePortion.addAll(toPurge);
toPurge.clear();
}
currentPage++;
purgeData(playerPortion, namePortion);
if (currentPage % 20 == 0) {
int completed = totalPurgeCount - toPurge.size();
sendMessage("[AuthMe] Purge progress " + completed + '/' + totalPurgeCount);
}
}
private void purgeData(Set<OfflinePlayer> playerPortion, Set<String> namePortion) {
// Purge other data
if (newSetting.getProperty(PurgeSettings.REMOVE_ESSENTIALS_FILES)
&& plugin.getPluginHooks().isEssentialsAvailable()) {
plugin.dataManager.purgeEssentials(playerPortion);
}
if (newSetting.getProperty(PurgeSettings.REMOVE_PLAYER_DAT)) {
plugin.dataManager.purgeDat(playerPortion);
}
if (newSetting.getProperty(PurgeSettings.REMOVE_LIMITED_CREATIVE_INVENTORIES)) {
plugin.dataManager.purgeLimitedCreative(namePortion);
}
if (newSetting.getProperty(PurgeSettings.REMOVE_ANTI_XRAY_FILE)) {
plugin.dataManager.purgeAntiXray(namePortion);
}
if (newSetting.getProperty(PurgeSettings.REMOVE_PERMISSIONS)) {
plugin.dataManager.purgePermissions(playerPortion);
}
}
private void finish() {
cancel();
// Show a status message
sendMessage(ChatColor.GREEN + "[AuthMe] Database has been purged correctly");
ConsoleLogger.info("AutoPurge Finished!");
if (autoPurging) {
plugin.notifyAutoPurgeEnd();
}
}
private void sendMessage(String message) {
if (sender == null) {
Bukkit.getConsoleSender().sendMessage(message);
} else {
Player player = Bukkit.getPlayer(sender);
if (player != null) {
player.sendMessage(message);
}
}
}
}

View File

@ -10,6 +10,8 @@ import java.util.List;
import static fr.xephi.authme.AuthMeMatchers.equalToHash;
import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData;
import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
@ -221,7 +223,7 @@ public abstract class AbstractDataSourceIntegrationTest {
public void shouldDeletePlayers() {
// given
DataSource dataSource = getDataSource();
List<String> playersToDelete = Arrays.asList("bobby", "doesNotExist");
Set<String> playersToDelete = new HashSet<>(Arrays.asList("bobby", "doesNotExist"));
assumeThat(dataSource.getAccountsRegistered(), equalTo(2));
// when

View File

@ -32,6 +32,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -192,8 +193,8 @@ public abstract class AbstractResourceClosingTest {
for (Class<?> paramType : method.getParameterTypes()) {
// Checking List.class == paramType instead of Class#isAssignableFrom means we really only accept List,
// but that is a sensible assumption and makes our life much easier later on when juggling with Type
Object param = (List.class == paramType)
? getTypedList(method.getGenericParameterTypes()[index])
Object param = Collection.class.isAssignableFrom(paramType)
? getTypedCollection(method.getGenericParameterTypes()[index])
: PARAM_VALUES.get(paramType);
Preconditions.checkNotNull(param, "No param type for " + paramType);
params.add(param);
@ -208,15 +209,21 @@ public abstract class AbstractResourceClosingTest {
* @param type The list type to process and build a test list for
* @return Test list with sample elements of the correct type
*/
private static List<?> getTypedList(Type type) {
private static Collection<?> getTypedCollection(Type type) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Preconditions.checkArgument(List.class == parameterizedType.getRawType(), type + " should be a List");
Preconditions.checkArgument(Collection.class.isAssignableFrom((Class<?>) parameterizedType.getRawType()),
type + " should extend from Collection");
Type genericType = parameterizedType.getActualTypeArguments()[0];
Object element = PARAM_VALUES.get(genericType);
Preconditions.checkNotNull(element, "No sample element for list of generic type " + genericType);
return Arrays.asList(element, element, element);
if (List.class == parameterizedType.getRawType()) {
return Arrays.asList(element, element, element);
} else if (Set.class == parameterizedType.getRawType()) {
return new HashSet<>(Arrays.asList(element, element, element));
}
throw new IllegalStateException("Unknown collection type " + parameterizedType.getRawType());
}
throw new IllegalStateException("Cannot build list for unexpected Type: " + type);
}