AuthMe 3.0
//Changes 3.0:// * Repackaging from uk.org.whoami.authme to fr.xephi.authme, please developpers, update! * Rewrite some of parts of the plugin * Some code was already perfect , also did not change it :p * Full support for phpbb3 * Add full support for WordPress + passwordHash: WORDPRESS * Completely rewrite Management system for inventories and tp issues, Thanks to : [[http://dev.bukkit.org/profiles/Possible/|Possible]] * Rework on /passpartu command * Completely rewrite the password encryption method * Add a way for developers to add their own Password Encryption Method on AuthMe via event way (please see fr.xephi.authme.events.PasswordEncryptionEvent) * Add an auto purge with players.dat removing method and essentials files removing ( if you want authme to hook with an another plugin let me know ) * Complete Hook with BungeeCord by removing the /server command before login * message_lang.yml will never be overwritten with English Strings , but correctly update the message_lang.yml when needed to * Fix a lot of issues mentioned in tickets , commants , or by mp, Thanks for all your reports!
This commit is contained in:
@@ -0,0 +1,600 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.earth2me.essentials.Essentials;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
|
||||
import me.muizers.Notifications.Notifications;
|
||||
import net.citizensnpcs.Citizens;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
|
||||
import com.onarandombox.MultiverseCore.MultiverseCore;
|
||||
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.commands.AdminCommand;
|
||||
import fr.xephi.authme.commands.CaptchaCommand;
|
||||
import fr.xephi.authme.commands.ChangePasswordCommand;
|
||||
import fr.xephi.authme.commands.EmailCommand;
|
||||
import fr.xephi.authme.commands.LoginCommand;
|
||||
import fr.xephi.authme.commands.LogoutCommand;
|
||||
import fr.xephi.authme.commands.PasspartuCommand;
|
||||
import fr.xephi.authme.commands.RegisterCommand;
|
||||
import fr.xephi.authme.commands.UnregisterCommand;
|
||||
import fr.xephi.authme.datasource.CacheDataSource;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.FileDataSource;
|
||||
import fr.xephi.authme.datasource.MySQLDataSource;
|
||||
import fr.xephi.authme.datasource.SqliteDataSource;
|
||||
import fr.xephi.authme.listener.AuthMeBlockListener;
|
||||
import fr.xephi.authme.listener.AuthMeChestShopListener;
|
||||
import fr.xephi.authme.listener.AuthMeEntityListener;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.listener.AuthMeSpoutListener;
|
||||
import fr.xephi.authme.plugin.manager.BungeeCordMessage;
|
||||
import fr.xephi.authme.plugin.manager.CitizensCommunicator;
|
||||
import fr.xephi.authme.plugin.manager.CombatTagComunicator;
|
||||
import fr.xephi.authme.plugin.manager.EssSpawn;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.PlayersLogs;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import fr.xephi.authme.threads.FlatFileThread;
|
||||
import fr.xephi.authme.threads.MySQLThread;
|
||||
import fr.xephi.authme.threads.SQLiteThread;
|
||||
|
||||
|
||||
public class AuthMe extends JavaPlugin {
|
||||
|
||||
public DataSource database = null;
|
||||
private Settings settings;
|
||||
private Messages m;
|
||||
private PlayersLogs pllog;
|
||||
public static Server server;
|
||||
public static Plugin authme;
|
||||
public static Permission permission;
|
||||
private static AuthMe instance;
|
||||
private Utils utils = Utils.getInstance();
|
||||
private JavaPlugin plugin;
|
||||
private FileCache playerBackup = new FileCache();
|
||||
public CitizensCommunicator citizens;
|
||||
public SendMailSSL mail = null;
|
||||
public int CitizensVersion = 0;
|
||||
public int CombatTag = 0;
|
||||
public double ChestShop = 0;
|
||||
public boolean BungeeCord = false;
|
||||
public Essentials ess;
|
||||
public Notifications notifications;
|
||||
public API api;
|
||||
public Management management;
|
||||
public HashMap<String, Integer> captcha = new HashMap<String, Integer>();
|
||||
public HashMap<String, String> cap = new HashMap<String, String>();
|
||||
public HashMap<String, String> realIp = new HashMap<String, String>();
|
||||
public MultiverseCore multiverse = null;
|
||||
public Location essentialsSpawn;
|
||||
public Thread databaseThread = null;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
authme = instance;
|
||||
|
||||
citizens = new CitizensCommunicator(this);
|
||||
|
||||
settings = new Settings(this);
|
||||
settings.loadConfigOptions();
|
||||
|
||||
setMessages(Messages.getInstance());
|
||||
pllog = PlayersLogs.getInstance();
|
||||
|
||||
server = getServer();
|
||||
|
||||
//Set Console Filter
|
||||
if (Settings.removePassword)
|
||||
Bukkit.getLogger().setFilter(new ConsoleFilter());
|
||||
|
||||
//Load MailApi
|
||||
if(!Settings.getmailAccount.isEmpty() && !Settings.getmailPassword.isEmpty())
|
||||
mail = new SendMailSSL(this);
|
||||
|
||||
//Check Citizens Version
|
||||
citizensVersion();
|
||||
|
||||
//Check Combat Tag Version
|
||||
combatTag();
|
||||
|
||||
//Check Notifications
|
||||
checkNotifications();
|
||||
|
||||
//Check Multiverse
|
||||
checkMultiverse();
|
||||
|
||||
//Check ChestShop
|
||||
checkChestShop();
|
||||
|
||||
//Check Essentials
|
||||
checkEssentials();
|
||||
|
||||
/*
|
||||
* Back style on start if avaible
|
||||
*/
|
||||
if(Settings.isBackupActivated && Settings.isBackupOnStart) {
|
||||
Boolean Backup = new PerformBackup(this).DoBackup();
|
||||
if(Backup) ConsoleLogger.info("Backup Complete");
|
||||
else ConsoleLogger.showError("Error while making Backup");
|
||||
}
|
||||
|
||||
/*
|
||||
* Backend MYSQL - FILE - SQLITE
|
||||
*/
|
||||
switch (Settings.getDataSource) {
|
||||
case FILE:
|
||||
if (Settings.useMultiThreading) {
|
||||
FlatFileThread fileThread = new FlatFileThread();
|
||||
fileThread.run();
|
||||
database = fileThread;
|
||||
databaseThread = fileThread;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
database = new FileDataSource();
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use FLAT FILE... SHUTDOWN...");
|
||||
server.shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
this.getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case MYSQL:
|
||||
if (Settings.useMultiThreading) {
|
||||
MySQLThread sqlThread = new MySQLThread();
|
||||
sqlThread.run();
|
||||
database = sqlThread;
|
||||
databaseThread = sqlThread;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
database = new MySQLDataSource();
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use MySQL... Please input correct MySQL informations ! SHUTDOWN...");
|
||||
server.shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
this.getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SQLITE:
|
||||
if (Settings.useMultiThreading) {
|
||||
SQLiteThread sqliteThread = new SQLiteThread();
|
||||
sqliteThread.run();
|
||||
database = sqliteThread;
|
||||
databaseThread = sqliteThread;
|
||||
break;
|
||||
}
|
||||
try {
|
||||
database = new SqliteDataSource();
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use SQLITE... ! SHUTDOWN...");
|
||||
server.shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
this.getServer().getPluginManager().disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (Settings.isCachingEnabled) {
|
||||
database = new CacheDataSource(this, database);
|
||||
}
|
||||
|
||||
// Setup API
|
||||
api = new API(this, database);
|
||||
|
||||
// Setup Management
|
||||
management = new Management(database, this);
|
||||
|
||||
PluginManager pm = getServer().getPluginManager();
|
||||
if (pm.isPluginEnabled("Spout")) {
|
||||
pm.registerEvents(new AuthMeSpoutListener(database), this);
|
||||
ConsoleLogger.info("Successfully hook with Spout!");
|
||||
}
|
||||
pm.registerEvents(new AuthMePlayerListener(this,database),this);
|
||||
pm.registerEvents(new AuthMeBlockListener(database, this),this);
|
||||
pm.registerEvents(new AuthMeEntityListener(database, this),this);
|
||||
if (ChestShop != 0) {
|
||||
pm.registerEvents(new AuthMeChestShopListener(database, this), this);
|
||||
ConsoleLogger.info("Successfully hook with ChestShop!");
|
||||
}
|
||||
if (Settings.bungee) {
|
||||
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordMessage(this));
|
||||
}
|
||||
|
||||
//Find Permissions
|
||||
if (pm.getPlugin("Vault") != null) {
|
||||
RegisteredServiceProvider<Permission> permissionProvider =
|
||||
getServer().getServicesManager().getRegistration(net.milkbowl.vault.permission.Permission.class);
|
||||
if (permissionProvider != null) {
|
||||
permission = permissionProvider.getProvider();
|
||||
ConsoleLogger.info("Vault plugin detected, hook with " + permission.getName() + " system");
|
||||
}
|
||||
else {
|
||||
ConsoleLogger.showError("Vault plugin is detected but not the permissions plugin!");
|
||||
}
|
||||
}
|
||||
|
||||
this.getCommand("authme").setExecutor(new AdminCommand(this, database));
|
||||
this.getCommand("register").setExecutor(new RegisterCommand(database, this));
|
||||
this.getCommand("login").setExecutor(new LoginCommand(this));
|
||||
this.getCommand("changepassword").setExecutor(new ChangePasswordCommand(database, this));
|
||||
this.getCommand("logout").setExecutor(new LogoutCommand(this,database));
|
||||
this.getCommand("unregister").setExecutor(new UnregisterCommand(this, database));
|
||||
this.getCommand("passpartu").setExecutor(new PasspartuCommand(this));
|
||||
this.getCommand("email").setExecutor(new EmailCommand(this, database));
|
||||
this.getCommand("captcha").setExecutor(new CaptchaCommand(this));
|
||||
|
||||
if(!Settings.isForceSingleSessionEnabled) {
|
||||
ConsoleLogger.showError("ATTENTION by disabling ForceSingleSession, your server protection is set to low");
|
||||
}
|
||||
|
||||
if (Settings.reloadSupport)
|
||||
try {
|
||||
if (!new File(getDataFolder() + File.separator + "players.yml").exists()) {
|
||||
pllog = new PlayersLogs();
|
||||
}
|
||||
onReload();
|
||||
if (server.getOnlinePlayers().length < 1) {
|
||||
try {
|
||||
PlayersLogs.players.clear();
|
||||
pllog.save();
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
}
|
||||
if (Settings.usePurge)
|
||||
autoPurge();
|
||||
ConsoleLogger.info("Authme " + this.getDescription().getVersion() + " enabled");
|
||||
}
|
||||
|
||||
private void checkChestShop() {
|
||||
if (!Settings.chestshop) {
|
||||
this.ChestShop = 0;
|
||||
return;
|
||||
}
|
||||
if (this.getServer().getPluginManager().isPluginEnabled("ChestShop")) {
|
||||
try {
|
||||
String ver = com.Acrobot.ChestShop.ChestShop.getVersion();
|
||||
try {
|
||||
double version = Double.valueOf(ver.split(" ")[0]);
|
||||
if (version >= 3.50) {
|
||||
this.ChestShop = version;
|
||||
} else {
|
||||
ConsoleLogger.showError("Please Update your ChestShop version!");
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
try {
|
||||
double version = Double.valueOf(ver.split("t")[0]);
|
||||
if (version >= 3.50) {
|
||||
this.ChestShop = version;
|
||||
} else {
|
||||
ConsoleLogger.showError("Please Update your ChestShop version!");
|
||||
}
|
||||
} catch (NumberFormatException nfee) {
|
||||
}
|
||||
}
|
||||
} catch (NullPointerException npe) {}
|
||||
catch (NoClassDefFoundError ncdfe) {}
|
||||
catch (ClassCastException cce) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkMultiverse() {
|
||||
if(!Settings.multiverse) {
|
||||
multiverse = null;
|
||||
return;
|
||||
}
|
||||
if (this.getServer().getPluginManager().getPlugin("Multiverse-Core") != null && this.getServer().getPluginManager().getPlugin("Multiverse-Core").isEnabled()) {
|
||||
try {
|
||||
multiverse = (MultiverseCore) this.getServer().getPluginManager().getPlugin("Multiverse-Core");
|
||||
ConsoleLogger.info("Hook with Multiverse-Core for SpawnLocations");
|
||||
} catch (NullPointerException npe) {
|
||||
multiverse = null;
|
||||
} catch (ClassCastException cce) {
|
||||
multiverse = null;
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
multiverse = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkEssentials() {
|
||||
if (this.getServer().getPluginManager().getPlugin("Essentials") != null && this.getServer().getPluginManager().getPlugin("Essentials").isEnabled()) {
|
||||
try {
|
||||
ess = (Essentials) this.getServer().getPluginManager().getPlugin("Essentials");
|
||||
ConsoleLogger.info("Hook with Essentials plugin");
|
||||
} catch (NullPointerException npe) {
|
||||
ess = null;
|
||||
} catch (ClassCastException cce) {
|
||||
ess = null;
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
ess = null;
|
||||
}
|
||||
}
|
||||
if (this.getServer().getPluginManager().getPlugin("EssentialsSpawn") != null && this.getServer().getPluginManager().getPlugin("EssentialsSpawn").isEnabled()) {
|
||||
this.essentialsSpawn = new EssSpawn().getLocation();
|
||||
ConsoleLogger.info("Hook with EssentialsSpawn plugin");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkNotifications() {
|
||||
if (!Settings.notifications) {
|
||||
this.notifications = null;
|
||||
return;
|
||||
}
|
||||
if (this.getServer().getPluginManager().getPlugin("Notifications") != null && this.getServer().getPluginManager().getPlugin("Notifications").isEnabled()) {
|
||||
this.notifications = (Notifications) this.getServer().getPluginManager().getPlugin("Notifications");
|
||||
ConsoleLogger.info("Successfully hook with Notifications");
|
||||
} else {
|
||||
this.notifications = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void combatTag() {
|
||||
if (this.getServer().getPluginManager().getPlugin("CombatTag") != null && this.getServer().getPluginManager().getPlugin("CombatTag").isEnabled()) {
|
||||
this.CombatTag = 1;
|
||||
} else {
|
||||
this.CombatTag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void citizensVersion() {
|
||||
if (this.getServer().getPluginManager().getPlugin("Citizens") != null && this.getServer().getPluginManager().getPlugin("Citizens").isEnabled()) {
|
||||
Citizens cit = (Citizens) this.getServer().getPluginManager().getPlugin("Citizens");
|
||||
String ver = cit.getDescription().getVersion();
|
||||
String[] args = ver.split("\\.");
|
||||
if (args[0].contains("1")) {
|
||||
this.CitizensVersion = 1;
|
||||
} else {
|
||||
this.CitizensVersion = 2;
|
||||
}
|
||||
} else {
|
||||
this.CitizensVersion = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
if (Bukkit.getOnlinePlayers() != null)
|
||||
for(Player player : Bukkit.getOnlinePlayers()) {
|
||||
this.savePlayer(player);
|
||||
}
|
||||
pllog.save();
|
||||
|
||||
if (database != null) {
|
||||
database.close();
|
||||
}
|
||||
|
||||
if (databaseThread != null) {
|
||||
databaseThread.interrupt();
|
||||
}
|
||||
|
||||
if(Settings.isBackupActivated && Settings.isBackupOnStop) {
|
||||
Boolean Backup = new PerformBackup(this).DoBackup();
|
||||
if(Backup) ConsoleLogger.info("Backup Complete");
|
||||
else ConsoleLogger.showError("Error while making Backup");
|
||||
}
|
||||
ConsoleLogger.info("Authme " + this.getDescription().getVersion() + " disabled");
|
||||
}
|
||||
|
||||
private void onReload() {
|
||||
try {
|
||||
if (Bukkit.getServer().getOnlinePlayers() != null && !PlayersLogs.players.isEmpty()) {
|
||||
for (Player player : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if (PlayersLogs.players.contains(player.getName())) {
|
||||
String name = player.getName().toLowerCase();
|
||||
PlayerAuth pAuth = database.getAuth(name);
|
||||
if(pAuth == null)
|
||||
break;
|
||||
PlayerAuth auth = new PlayerAuth(name, pAuth.getHash(), pAuth.getIp(), new Date().getTime());
|
||||
database.updateSession(auth);
|
||||
PlayerCache.getInstance().addPlayer(auth);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
} catch (NullPointerException ex) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static AuthMe getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void savePlayer(Player player) throws IllegalStateException, NullPointerException {
|
||||
try {
|
||||
if ((citizens.isNPC(player, this)) || (Utils.getInstance().isUnrestricted(player)) || (CombatTagComunicator.isNPC(player))) {
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) { }
|
||||
try {
|
||||
String name = player.getName().toLowerCase();
|
||||
if ((PlayerCache.getInstance().isAuthenticated(name)) && (!player.isDead()) &&
|
||||
(Settings.isSaveQuitLocationEnabled.booleanValue())) {
|
||||
final PlayerAuth auth = new PlayerAuth(player.getName().toLowerCase(), (int)player.getLocation().getX(), (int)player.getLocation().getY(), (int)player.getLocation().getZ(), player.getWorld().getName());
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
database.updateQuitLoc(auth);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name))
|
||||
{
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (Settings.protectInventoryBeforeLogInEnabled.booleanValue()) {
|
||||
player.getInventory().setArmorContents(limbo.getArmour());
|
||||
player.getInventory().setContents(limbo.getInventory());
|
||||
}
|
||||
if (!limbo.getLoc().getChunk().isLoaded()) {
|
||||
limbo.getLoc().getChunk().load();
|
||||
}
|
||||
player.teleport(limbo.getLoc());
|
||||
this.utils.addNormal(player, limbo.getGroup());
|
||||
player.setOp(limbo.getOperator());
|
||||
this.plugin.getServer().getScheduler().cancelTask(limbo.getTimeoutTaskId());
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
if (this.playerBackup.doesCacheExist(name)) {
|
||||
this.playerBackup.removeCache(name);
|
||||
}
|
||||
}
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
player.saveData();
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
}
|
||||
|
||||
public CitizensCommunicator getCitizensCommunicator() {
|
||||
return citizens;
|
||||
}
|
||||
|
||||
public void setMessages(Messages m) {
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
public Messages getMessages() {
|
||||
return m;
|
||||
}
|
||||
|
||||
public Player generateKickPlayer(Player[] players) {
|
||||
Player player = null;
|
||||
int i;
|
||||
for (i = 0 ; i <= players.length ; i++) {
|
||||
Random rdm = new Random();
|
||||
int a = rdm.nextInt(players.length);
|
||||
if (!(authmePermissible(players[a], "authme.vip"))) {
|
||||
player = players[a];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player == null) {
|
||||
for (Player p : players) {
|
||||
if (!(authmePermissible(p, "authme.vip"))) {
|
||||
player = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean authmePermissible(Player player, String perm) {
|
||||
if (player.hasPermission(perm))
|
||||
return true;
|
||||
else if (permission != null) {
|
||||
return permission.playerHas(player, perm);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean authmePermissible(CommandSender sender, String perm) {
|
||||
if (sender.hasPermission(perm)) return true;
|
||||
else if (permission != null) {
|
||||
return permission.has(sender, perm);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void autoPurge() {
|
||||
if (!Settings.usePurge) {
|
||||
return;
|
||||
}
|
||||
long days = Settings.purgeDelay * 86400000;
|
||||
long until = new Date().getTime() - days;
|
||||
List<String> cleared = this.database.autoPurgeDatabase(until);
|
||||
ConsoleLogger.info("AutoPurgeDatabase : " + cleared.size() + " accounts removed.");
|
||||
if (cleared.isEmpty())
|
||||
return;
|
||||
if (Settings.purgeEssentialsFile && this.ess != null)
|
||||
purgeEssentials(cleared);
|
||||
if (Settings.purgePlayerDat)
|
||||
purgeDat(cleared);
|
||||
}
|
||||
|
||||
private void purgeDat(List<String> cleared) {
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
org.bukkit.OfflinePlayer player = Bukkit.getOfflinePlayer(name);
|
||||
if (player == null) continue;
|
||||
String playerName = player.getName();
|
||||
File playerFile = new File (this.getServer().getWorldContainer() + File.separator + Settings.defaultWorld + File.separator + "players" + File.separator + playerName + ".dat");
|
||||
if (playerFile.exists()) {
|
||||
playerFile.delete();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " .dat Files");
|
||||
}
|
||||
|
||||
private void purgeEssentials(List<String> cleared) {
|
||||
int i = 0;
|
||||
for (String name : cleared) {
|
||||
File playerFile = new File(this.ess.getDataFolder() + File.separator + "userdata" + File.separator + name + ".yml");
|
||||
if (playerFile.exists()) {
|
||||
playerFile.delete();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("AutoPurgeDatabase : Remove " + i + " EssentialsFiles");
|
||||
}
|
||||
|
||||
public Location getSpawnLocation(World world) {
|
||||
Location spawnLoc = world.getSpawnLocation();
|
||||
if (multiverse != null) {
|
||||
try {
|
||||
spawnLoc = multiverse.getMVWorldManager().getMVWorld(world).getSpawnLocation();
|
||||
} catch (NullPointerException npe) {
|
||||
} catch (ClassCastException cce) {
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
}
|
||||
}
|
||||
if (essentialsSpawn != null) {
|
||||
spawnLoc = essentialsSpawn;
|
||||
}
|
||||
if (Spawn.getInstance().getLocation() != null)
|
||||
spawnLoc = Spawn.getInstance().getLocation();
|
||||
return spawnLoc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.util.logging.Filter;
|
||||
import java.util.logging.LogRecord;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class ConsoleFilter implements Filter {
|
||||
|
||||
public ConsoleFilter() {}
|
||||
|
||||
@Override
|
||||
public boolean isLoggable(LogRecord record) {
|
||||
try {
|
||||
if (record == null || record.getMessage() == null) return true;
|
||||
String logM = record.getMessage().toLowerCase();
|
||||
if (!logM.contains("issued server command:")) return true;
|
||||
if (!logM.contains("/login ") && !logM.contains("/l ") && !logM.contains("/reg ") && !logM.contains("/changepassword ") && !logM.contains("/unregister ")
|
||||
&& !logM.contains("/authme register ") && !logM.contains("/authme changepassword ")&& !logM.contains("/authme reg ")&& !logM.contains("/authme cp ") && !logM.contains("/register ")) return true;
|
||||
String playername = record.getMessage().split(" ")[0];
|
||||
record.setMessage(playername + " issued an AuthMe command!");
|
||||
return true;
|
||||
} catch (NullPointerException npe) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class ConsoleLogger {
|
||||
|
||||
private static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
public static void info(String message) {
|
||||
if (AuthMe.getInstance().isEnabled()) {
|
||||
log.info("[AuthMe] " + message);
|
||||
if (Settings.useLogging) {
|
||||
Calendar date = Calendar.getInstance();
|
||||
final String actually = "[" + DateFormat.getDateInstance().format(date.getTime()) + ", " + date.get(Calendar.HOUR_OF_DAY) + ":" + date.get(Calendar.MINUTE) + ":" + date.get(Calendar.SECOND) + "] " + message;
|
||||
Bukkit.getScheduler().runTaskAsynchronously(AuthMe.getInstance(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
writeLog(actually);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void showError(String message) {
|
||||
if (AuthMe.getInstance().isEnabled()) {
|
||||
log.severe("[AuthMe] ERROR: " + message);
|
||||
if (Settings.useLogging) {
|
||||
Calendar date = Calendar.getInstance();
|
||||
final String actually = "[" + DateFormat.getDateInstance().format(date.getTime()) + ", " + date.get(Calendar.HOUR_OF_DAY) + ":" + date.get(Calendar.MINUTE) + ":" + date.get(Calendar.SECOND) + "] ERROR : " + message;
|
||||
Bukkit.getScheduler().runTaskAsynchronously(AuthMe.getInstance(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
writeLog(actually);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeLog(String string) {
|
||||
try {
|
||||
FileWriter fw = new FileWriter(AuthMe.getInstance().getDataFolder() + File.separator + "authme.log", true);
|
||||
BufferedWriter w = null;
|
||||
w = new BufferedWriter(fw);
|
||||
w.write(string);
|
||||
w.newLine();
|
||||
w.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,436 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import me.muizers.Notifications.Notification;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
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.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.events.LoginEvent;
|
||||
import fr.xephi.authme.events.RestoreInventoryEvent;
|
||||
import fr.xephi.authme.events.SpawnTeleportEvent;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.PlayersLogs;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @authors Xephi59, <a href="http://dev.bukkit.org/profiles/Possible/">Possible</a>
|
||||
*
|
||||
*/
|
||||
public class Management {
|
||||
private Messages m = Messages.getInstance();
|
||||
private PlayersLogs pllog = PlayersLogs.getInstance();
|
||||
private Utils utils = Utils.getInstance();
|
||||
private FileCache playerCache = new FileCache();
|
||||
private DataSource database;
|
||||
public AuthMe plugin;
|
||||
public static RandomString rdm = new RandomString(Settings.captchaLength);
|
||||
public PluginManager pm;
|
||||
|
||||
public Management(DataSource database, AuthMe plugin) {
|
||||
this.database = database;
|
||||
this.plugin = plugin;
|
||||
this.pm = plugin.getServer().getPluginManager();
|
||||
}
|
||||
|
||||
public void performLogin(final Player player, final String password, final boolean passpartu) {
|
||||
if (passpartu) {
|
||||
// Passpartu-Login Bypasses Password-Authentication.
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new AsyncronousPasspartuLogin(player));
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new AsyncronousLogin(player, password));
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncronousLogin implements Runnable {
|
||||
protected Player player;
|
||||
protected String name;
|
||||
protected String password;
|
||||
|
||||
public AsyncronousLogin(Player player, String password) {
|
||||
this.player = player;
|
||||
this.password = password;
|
||||
name = player.getName().toLowerCase();
|
||||
}
|
||||
|
||||
protected String getIP() {
|
||||
String ip = player.getAddress().getAddress().getHostAddress();
|
||||
if (Settings.bungee) {
|
||||
if (plugin.realIp.containsKey(name))
|
||||
ip = plugin.realIp.get(name);
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
protected boolean needsCaptcha() {
|
||||
if (Settings.useCaptcha) {
|
||||
if (!plugin.captcha.containsKey(name)) {
|
||||
plugin.captcha.put(name, 1);
|
||||
} else {
|
||||
int i = plugin.captcha.get(name) + 1;
|
||||
plugin.captcha.remove(name);
|
||||
plugin.captcha.put(name, i);
|
||||
}
|
||||
if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) > Settings.maxLoginTry) {
|
||||
player.sendMessage(m._("need_captcha"));
|
||||
plugin.cap.put(name, rdm.nextString());
|
||||
player.sendMessage("Type : /captcha " + plugin.cap.get(name));
|
||||
return true;
|
||||
} else if (plugin.captcha.containsKey(name) && plugin.captcha.get(name) > Settings.maxLoginTry) {
|
||||
try {
|
||||
plugin.captcha.remove(name);
|
||||
plugin.cap.remove(name);
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the precondition for authentication (like user known) and returns the playerAuth-State
|
||||
*/
|
||||
protected PlayerAuth preAuth() {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("logged_in"));
|
||||
return null;
|
||||
}
|
||||
if (!database.isAuthAvailable(name)) {
|
||||
player.sendMessage(m._("user_unknown"));
|
||||
return null;
|
||||
}
|
||||
PlayerAuth pAuth = database.getAuth(name);
|
||||
if (pAuth == null) {
|
||||
player.sendMessage(m._("user_unknown"));
|
||||
return null;
|
||||
}
|
||||
if (!Settings.getMySQLColumnGroup.isEmpty() && pAuth.getGroupId() == Settings.getNonActivatedGroup) {
|
||||
player.sendMessage(m._("vb_nonActiv"));
|
||||
return null;
|
||||
}
|
||||
return pAuth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth pAuth = preAuth();
|
||||
if (pAuth == null || needsCaptcha())
|
||||
return;
|
||||
|
||||
String hash = pAuth.getHash();
|
||||
String email = pAuth.getEmail();
|
||||
boolean passwordVerified = true;
|
||||
try {
|
||||
passwordVerified = PasswordSecurity.comparePasswordWithHash(password, hash, name);
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
player.sendMessage(m._("error"));
|
||||
return;
|
||||
}
|
||||
if (passwordVerified && player.isOnline()) {
|
||||
PlayerAuth auth = new PlayerAuth(name, hash, getIP(), new Date().getTime(), email);
|
||||
database.updateSession(auth);
|
||||
|
||||
/*
|
||||
* Little Work Around under Registration Group Switching for
|
||||
* admins that add Registration thru a web Scripts.
|
||||
*/
|
||||
if (Settings.isPermissionCheckEnabled
|
||||
&& AuthMe.permission.playerInGroup(player, Settings.unRegisteredGroup)
|
||||
&& !Settings.unRegisteredGroup.isEmpty()) {
|
||||
AuthMe.permission
|
||||
.playerRemoveGroup(player.getWorld(), player.getName(), Settings.unRegisteredGroup);
|
||||
AuthMe.permission.playerAddGroup(player.getWorld(), player.getName(), Settings.getRegisteredGroup);
|
||||
}
|
||||
|
||||
pllog.addPlayer(player);
|
||||
|
||||
if (Settings.useCaptcha) {
|
||||
if (plugin.captcha.containsKey(name)) {
|
||||
plugin.captcha.remove(name);
|
||||
}
|
||||
if (plugin.cap.containsKey(name)) {
|
||||
plugin.cap.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
player.setNoDamageTicks(0);
|
||||
player.sendMessage(m._("login"));
|
||||
|
||||
displayOtherAccounts(auth);
|
||||
|
||||
if (!Settings.noConsoleSpam)
|
||||
ConsoleLogger.info(player.getName() + " logged in!");
|
||||
|
||||
if (plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " logged in!"));
|
||||
}
|
||||
|
||||
// makes player isLoggedin via API
|
||||
PlayerCache.getInstance().addPlayer(auth);
|
||||
|
||||
// As the scheduling executes the Task most likely after the current 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.
|
||||
ProcessSyncronousPlayerLogin syncronousPlayerLogin = new ProcessSyncronousPlayerLogin(player);
|
||||
if (syncronousPlayerLogin.getLimbo() != null) {
|
||||
player.getServer().getScheduler().cancelTask(syncronousPlayerLogin.getLimbo().getTimeoutTaskId());
|
||||
player.getServer().getScheduler().cancelTask(syncronousPlayerLogin.getLimbo().getMessageTaskId());
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, syncronousPlayerLogin);
|
||||
} else if (player.isOnline()) {
|
||||
if (!Settings.noConsoleSpam)
|
||||
ConsoleLogger.info(player.getName() + " used the wrong password");
|
||||
if (Settings.isKickOnWrongPasswordEnabled) {
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (AuthMePlayerListener.gameMode != null && AuthMePlayerListener.gameMode.containsKey(name)) {
|
||||
player.setGameMode(GameMode.getByValue(AuthMePlayerListener.gameMode.get(name)));
|
||||
}
|
||||
player.kickPlayer(m._("wrong_pwd"));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
player.sendMessage(m._("wrong_pwd"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ConsoleLogger.showError("Player " + name + " wasn't online during login process, aborted... ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AsyncronousPasspartuLogin extends AsyncronousLogin implements Runnable {
|
||||
public AsyncronousPasspartuLogin(Player player) {
|
||||
super(player, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth pAuth = preAuth();
|
||||
if (pAuth == null)
|
||||
return;
|
||||
|
||||
String hash = pAuth.getHash();
|
||||
String email = pAuth.getEmail();
|
||||
|
||||
PlayerAuth auth = new PlayerAuth(name, hash, getIP(), new Date().getTime(), email);
|
||||
database.updateSession(auth);
|
||||
|
||||
/*
|
||||
* Little Work Around under Registration Group Switching for
|
||||
* admins that add Registration thru a web Scripts.
|
||||
*/
|
||||
if (Settings.isPermissionCheckEnabled
|
||||
&& AuthMe.permission.playerInGroup(player, Settings.unRegisteredGroup)
|
||||
&& !Settings.unRegisteredGroup.isEmpty()) {
|
||||
AuthMe.permission
|
||||
.playerRemoveGroup(player.getWorld(), player.getName(), Settings.unRegisteredGroup);
|
||||
AuthMe.permission.playerAddGroup(player.getWorld(), player.getName(), Settings.getRegisteredGroup);
|
||||
}
|
||||
|
||||
pllog.addPlayer(player);
|
||||
|
||||
if (Settings.useCaptcha) {
|
||||
if (plugin.captcha.containsKey(name)) {
|
||||
plugin.captcha.remove(name);
|
||||
}
|
||||
if (plugin.cap.containsKey(name)) {
|
||||
plugin.cap.remove(name);
|
||||
}
|
||||
}
|
||||
|
||||
player.setNoDamageTicks(0);
|
||||
player.sendMessage(m._("login"));
|
||||
|
||||
displayOtherAccounts(auth);
|
||||
|
||||
if (!Settings.noConsoleSpam)
|
||||
ConsoleLogger.info(player.getName() + " logged in!");
|
||||
|
||||
if (plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " logged in!"));
|
||||
}
|
||||
|
||||
// makes player isLoggedin via API
|
||||
PlayerCache.getInstance().addPlayer(auth);
|
||||
|
||||
// As the scheduling executes the Task most likely after the current 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.
|
||||
ProcessSyncronousPlayerLogin syncronousPlayerLogin = new ProcessSyncronousPlayerLogin(player);
|
||||
if (syncronousPlayerLogin.getLimbo() != null) {
|
||||
player.getServer().getScheduler().cancelTask(syncronousPlayerLogin.getLimbo().getTimeoutTaskId());
|
||||
player.getServer().getScheduler().cancelTask(syncronousPlayerLogin.getLimbo().getMessageTaskId());
|
||||
}
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, syncronousPlayerLogin);
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessSyncronousPlayerLogin implements Runnable {
|
||||
private LimboPlayer limbo;
|
||||
private Player player;
|
||||
private String name;
|
||||
private PlayerAuth auth;
|
||||
public ProcessSyncronousPlayerLogin(Player player) {
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
this.auth = database.getAuth(name);
|
||||
}
|
||||
|
||||
public LimboPlayer getLimbo() {
|
||||
return limbo;
|
||||
}
|
||||
|
||||
protected void restoreOpState() {
|
||||
player.setOp(limbo.getOperator());
|
||||
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
|
||||
player.setAllowFlight(limbo.isFlying());
|
||||
player.setFlying(limbo.isFlying());
|
||||
}
|
||||
}
|
||||
protected void packQuitLocation() {
|
||||
utils.packCoords(auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ(), auth.getWorld(), player);
|
||||
}
|
||||
protected void teleportBackFromSpawn() {
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, limbo.getLoc());
|
||||
pm.callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
Location fLoc = tpEvent.getTo();
|
||||
if (!fLoc.getChunk().isLoaded()) {
|
||||
fLoc.getChunk().load();
|
||||
}
|
||||
player.teleport(fLoc);
|
||||
}
|
||||
}
|
||||
protected void teleportToSpawn() {
|
||||
Location spawnL = plugin.getSpawnLocation(player.getWorld());
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawnL, true);
|
||||
pm.callEvent(tpEvent);
|
||||
if (!tpEvent.isCancelled()) {
|
||||
Location fLoc = tpEvent.getTo();
|
||||
if (!fLoc.getChunk().isLoaded()) {
|
||||
fLoc.getChunk().load();
|
||||
}
|
||||
player.teleport(fLoc);
|
||||
}
|
||||
}
|
||||
protected void restoreInventory() {
|
||||
RestoreInventoryEvent event = new RestoreInventoryEvent(player, limbo.getInventory(), limbo.getArmour());
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
API.setPlayerInventory(player, event.getInventory(), event.getArmor());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Limbo contains the State of the Player before /login
|
||||
if (limbo != null) {
|
||||
// Op & Flying
|
||||
restoreOpState();
|
||||
|
||||
/*
|
||||
* Restore Inventories and GameMode
|
||||
* We need to restore them before teleport the player
|
||||
* Cause in AuthMePlayerListener, we call ProtectInventoryEvent after Teleporting
|
||||
* Also it's the current world inventory !
|
||||
*/
|
||||
if (!Settings.forceOnlyAfterLogin) {
|
||||
player.setGameMode(GameMode.getByValue(limbo.getGameMode()));
|
||||
// Inventory - Make it after restore GameMode , cause we need to restore the
|
||||
// right inventory in the right gamemode
|
||||
if (Settings.protectInventoryBeforeLogInEnabled && player.hasPlayedBefore()) {
|
||||
restoreInventory();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Inventory - Make it before force the survival GameMode to cancel all
|
||||
// inventory problem
|
||||
if (Settings.protectInventoryBeforeLogInEnabled && player.hasPlayedBefore()) {
|
||||
restoreInventory();
|
||||
}
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
}
|
||||
|
||||
// Teleport
|
||||
if (Settings.isTeleportToSpawnEnabled && !Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName())) {
|
||||
if (Settings.isSaveQuitLocationEnabled && auth.getQuitLocY() != 0) {
|
||||
packQuitLocation();
|
||||
} else {
|
||||
teleportBackFromSpawn();
|
||||
}
|
||||
} else if (Settings.isForceSpawnLocOnJoinEnabled && Settings.getForcedWorlds.contains(player.getWorld().getName())) {
|
||||
teleportToSpawn();
|
||||
} else if (Settings.isSaveQuitLocationEnabled && auth.getQuitLocY() != 0) {
|
||||
packQuitLocation();
|
||||
} else {
|
||||
teleportBackFromSpawn();
|
||||
}
|
||||
|
||||
// Re-Force Survival GameMode if we need due to world change specification
|
||||
if (Settings.isForceSurvivalModeEnabled)
|
||||
player.setGameMode(GameMode.SURVIVAL);
|
||||
|
||||
// Cleanup no longer used temporary data
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
if (playerCache.doesCacheExist(name)) {
|
||||
playerCache.removeCache(name);
|
||||
}
|
||||
}
|
||||
// The Loginevent now fires (as intended) after everything is processed
|
||||
Bukkit.getServer().getPluginManager().callEvent(new LoginEvent(player, true));
|
||||
player.saveData();
|
||||
}
|
||||
}
|
||||
|
||||
private void displayOtherAccounts(PlayerAuth auth) {
|
||||
if (!Settings.displayOtherAccounts) {
|
||||
return;
|
||||
}
|
||||
if (auth == null) {
|
||||
return;
|
||||
}
|
||||
if (this.database.getAllAuthsByName(auth).isEmpty() || this.database.getAllAuthsByName(auth) == null) {
|
||||
return;
|
||||
}
|
||||
if (this.database.getAllAuthsByName(auth).size() == 1) {
|
||||
return;
|
||||
}
|
||||
List<String> accountList = this.database.getAllAuthsByName(auth);
|
||||
String message = "[AuthMe] ";
|
||||
int i = 0;
|
||||
for (String account : accountList) {
|
||||
i++;
|
||||
message = message + account;
|
||||
if (i != accountList.size()) {
|
||||
message = message + ", ";
|
||||
} else {
|
||||
message = message + ".";
|
||||
}
|
||||
}
|
||||
for (Player player : AuthMe.getInstance().getServer().getOnlinePlayers()) {
|
||||
if (plugin.authmePermissible(player, "authme.seeOtherAccounts")) {
|
||||
player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has "
|
||||
+ String.valueOf(accountList.size()) + " accounts");
|
||||
player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author stefano
|
||||
*/
|
||||
public class PerformBackup {
|
||||
|
||||
private String dbName = Settings.getMySQLDatabase;
|
||||
private String dbUserName = Settings.getMySQLUsername;
|
||||
private String dbPassword = Settings.getMySQLPassword;
|
||||
private String tblname = Settings.getMySQLTablename;
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm");
|
||||
String dateString = format.format( new Date() );
|
||||
private String path = AuthMe.getInstance().getDataFolder()+"/backups/backup"+dateString;
|
||||
private AuthMe instance;
|
||||
|
||||
public PerformBackup(AuthMe instance) {
|
||||
this.setInstance(instance);
|
||||
}
|
||||
|
||||
public boolean DoBackup() {
|
||||
|
||||
switch(Settings.getDataSource) {
|
||||
case FILE: return FileBackup("auths.db");
|
||||
|
||||
case MYSQL: return MySqlBackup();
|
||||
|
||||
case SQLITE: return FileBackup(Settings.getMySQLDatabase+".db");
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean MySqlBackup() {
|
||||
File dirBackup = new File(AuthMe.getInstance().getDataFolder()+"/backups");
|
||||
|
||||
if(!dirBackup.exists())
|
||||
dirBackup.mkdir();
|
||||
if(checkWindows(Settings.backupWindowsPath)) {
|
||||
String executeCmd = Settings.backupWindowsPath+"\\bin\\mysqldump.exe -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path+".sql";
|
||||
Process runtimeProcess;
|
||||
try {
|
||||
runtimeProcess = Runtime.getRuntime().exec(executeCmd);
|
||||
int processComplete = runtimeProcess.waitFor();
|
||||
if (processComplete == 0) {
|
||||
ConsoleLogger.info("Backup created successfully");
|
||||
return true;
|
||||
} else {
|
||||
ConsoleLogger.info("Could not create the backup");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
String executeCmd = "mysqldump -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path+".sql";
|
||||
Process runtimeProcess;
|
||||
try {
|
||||
runtimeProcess = Runtime.getRuntime().exec(executeCmd);
|
||||
int processComplete = runtimeProcess.waitFor();
|
||||
if (processComplete == 0) {
|
||||
ConsoleLogger.info("Backup created successfully");
|
||||
return true;
|
||||
} else {
|
||||
ConsoleLogger.info("Could not create the backup");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean FileBackup(String backend) {
|
||||
File dirBackup = new File(AuthMe.getInstance().getDataFolder()+"/backups");
|
||||
|
||||
if(!dirBackup.exists())
|
||||
dirBackup.mkdir();
|
||||
|
||||
try {
|
||||
copy(new File("plugins/AuthMe/"+backend),new File(path+".db"));
|
||||
return true;
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we are under Windows and correct location
|
||||
* of mysqldump.exe otherwise return error.
|
||||
*/
|
||||
private boolean checkWindows(String windowsPath) {
|
||||
String isWin = System.getProperty("os.name").toLowerCase();
|
||||
if(isWin.indexOf("win") >= 0) {
|
||||
if(new File(windowsPath+"\\bin\\mysqldump.exe").exists()) {
|
||||
return true;
|
||||
} else {
|
||||
ConsoleLogger.showError("Mysql Windows Path is incorrect please check it");
|
||||
return true;
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyr src bytefile into dst file
|
||||
*/
|
||||
void copy(File src, File dst) throws IOException {
|
||||
InputStream in = new FileInputStream(src);
|
||||
OutputStream out = new FileOutputStream(dst);
|
||||
|
||||
// Transfer bytes from in to out
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
while ((len = in.read(buf)) > 0) {
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
in.close();
|
||||
out.close();
|
||||
}
|
||||
|
||||
public void setInstance(AuthMe instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public AuthMe getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class SendMailSSL {
|
||||
|
||||
public AuthMe instance;
|
||||
|
||||
public SendMailSSL(AuthMe instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
public void main(final PlayerAuth auth, final String newPass) {
|
||||
|
||||
String sendername;
|
||||
|
||||
if (Settings.getmailSenderName.isEmpty() || Settings.getmailSenderName == null) {
|
||||
sendername = Settings.getmailAccount;
|
||||
} else {
|
||||
sendername = Settings.getmailSenderName;
|
||||
}
|
||||
|
||||
Properties props = new Properties();
|
||||
props.put("mail.smtp.host", Settings.getmailSMTP);
|
||||
props.put("mail.smtp.socketFactory.port", String.valueOf(Settings.getMailPort));
|
||||
props.put("mail.smtp.socketFactory.class",
|
||||
"javax.net.ssl.SSLSocketFactory");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.port", String.valueOf(Settings.getMailPort));
|
||||
|
||||
Session session = Session.getInstance(props,
|
||||
new javax.mail.Authenticator() {
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(Settings.getmailAccount,Settings.getmailPassword);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
final Message message = new MimeMessage(session);
|
||||
try {
|
||||
message.setFrom(new InternetAddress(Settings.getmailAccount, sendername));
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
message.setFrom(new InternetAddress(Settings.getmailAccount));
|
||||
}
|
||||
message.setRecipients(Message.RecipientType.TO,
|
||||
InternetAddress.parse(auth.getEmail()));
|
||||
message.setSubject(Settings.getMailSubject);
|
||||
message.setSentDate(new Date());
|
||||
String text = Settings.getMailText;
|
||||
text = text.replaceAll("<playername>", auth.getNickname());
|
||||
text = text.replaceAll("<servername>", instance.getServer().getServerName());
|
||||
text = text.replaceAll("<generatedpass>", newPass);
|
||||
message.setContent(text, "text/html");
|
||||
Bukkit.getScheduler().runTaskAsynchronously(instance, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Transport.send(message);
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
if(!Settings.noConsoleSpam)
|
||||
ConsoleLogger.info("Email sent to : " + auth.getNickname());
|
||||
} catch (MessagingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.events.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
public class Utils {
|
||||
private String currentGroup;
|
||||
private static Utils singleton;
|
||||
private String unLoggedGroup = Settings.getUnloggedinGroup;
|
||||
int id;
|
||||
|
||||
public void setGroup(Player player, groupType group) {
|
||||
if (!player.isOnline())
|
||||
return;
|
||||
if(!Settings.isPermissionCheckEnabled)
|
||||
return;
|
||||
|
||||
switch(group) {
|
||||
case UNREGISTERED: {
|
||||
currentGroup = AuthMe.permission.getPrimaryGroup(player);
|
||||
AuthMe.permission.playerRemoveGroup(player, currentGroup);
|
||||
AuthMe.permission.playerAddGroup(player, Settings.unRegisteredGroup);
|
||||
break;
|
||||
}
|
||||
case REGISTERED: {
|
||||
currentGroup = AuthMe.permission.getPrimaryGroup(player);
|
||||
AuthMe.permission.playerRemoveGroup(player, currentGroup);
|
||||
AuthMe.permission.playerAddGroup(player, Settings.getRegisteredGroup);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
public String removeAll(Player player) {
|
||||
if(!Utils.getInstance().useGroupSystem()){
|
||||
return null;
|
||||
}
|
||||
if( !Settings.getJoinPermissions.isEmpty() ) {
|
||||
hasPermOnJoin(player);
|
||||
}
|
||||
this.currentGroup = AuthMe.permission.getPrimaryGroup(player.getWorld(),player.getName().toString());
|
||||
if(AuthMe.permission.playerRemoveGroup(player.getWorld(),player.getName().toString(), currentGroup) && AuthMe.permission.playerAddGroup(player.getWorld(),player.getName().toString(),this.unLoggedGroup)) {
|
||||
return currentGroup;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean addNormal(Player player, String group) {
|
||||
if(!Utils.getInstance().useGroupSystem()){
|
||||
return false;
|
||||
}
|
||||
if(AuthMe.permission.playerRemoveGroup(player.getWorld(),player.getName().toString(),this.unLoggedGroup) && AuthMe.permission.playerAddGroup(player.getWorld(),player.getName().toString(),group)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String hasPermOnJoin(Player player) {
|
||||
Iterator<String> iter = Settings.getJoinPermissions.iterator();
|
||||
while (iter.hasNext()) {
|
||||
String permission = iter.next();
|
||||
if(AuthMe.permission.playerHas(player, permission)){
|
||||
AuthMe.permission.playerAddTransient(player, permission);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isUnrestricted(Player player) {
|
||||
if(Settings.getUnrestrictedName.isEmpty() || Settings.getUnrestrictedName == null)
|
||||
return false;
|
||||
if(Settings.getUnrestrictedName.contains(player.getName()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Utils getInstance() {
|
||||
singleton = new Utils();
|
||||
return singleton;
|
||||
}
|
||||
|
||||
private boolean useGroupSystem() {
|
||||
if(Settings.isPermissionCheckEnabled && !Settings.getUnloggedinGroup.isEmpty()) {
|
||||
return true;
|
||||
} return false;
|
||||
}
|
||||
|
||||
public void packCoords(int x, int y, int z, String w, final Player pl)
|
||||
{
|
||||
World theWorld;
|
||||
if (w.equals("unavailableworld")) {
|
||||
theWorld = pl.getWorld();
|
||||
} else {
|
||||
theWorld = Bukkit.getWorld(w);
|
||||
}
|
||||
if (theWorld == null)
|
||||
theWorld = pl.getWorld();
|
||||
final World world = theWorld;
|
||||
final int fY = y;
|
||||
final Location locat = new Location(world, x, y + 0.4D, z);
|
||||
final Location loc = locat.getBlock().getLocation();
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(AuthMe.getInstance(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(pl, loc);
|
||||
AuthMe.getInstance().getServer().getPluginManager().callEvent(tpEvent);
|
||||
if(!tpEvent.isCancelled()) {
|
||||
if (!tpEvent.getTo().getChunk().isLoaded())
|
||||
tpEvent.getTo().getChunk().load();
|
||||
pl.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
id = Bukkit.getScheduler().scheduleSyncRepeatingTask(AuthMe.getInstance(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run() {
|
||||
int current = (int)pl.getLocation().getY();
|
||||
World currentWorld = pl.getWorld();
|
||||
if (current != fY && world.getName() == currentWorld.getName()) {
|
||||
pl.teleport(loc);
|
||||
}
|
||||
}
|
||||
}, 1L, 20L);
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(AuthMe.getInstance(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run() {
|
||||
Bukkit.getScheduler().cancelTask(id);
|
||||
}
|
||||
}, 60L);
|
||||
}
|
||||
|
||||
/*
|
||||
* Random Token for passpartu
|
||||
*
|
||||
*/
|
||||
public boolean obtainToken() {
|
||||
File file = new File("plugins/AuthMe/passpartu.token");
|
||||
if (file.exists())
|
||||
file.delete();
|
||||
|
||||
FileWriter writer = null;
|
||||
try {
|
||||
file.createNewFile();
|
||||
writer = new FileWriter(file);
|
||||
String token = generateToken();
|
||||
writer.write(token + ":" + System.currentTimeMillis() / 1000 + API.newline);
|
||||
writer.flush();
|
||||
ConsoleLogger.info("[AuthMe] Security passpartu token: "+ token);
|
||||
writer.close();
|
||||
return true;
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read Token
|
||||
*/
|
||||
public boolean readToken(String inputToken) {
|
||||
File file = new File("plugins/AuthMe/passpartu.token");
|
||||
|
||||
if (!file.exists())
|
||||
return false;
|
||||
|
||||
if (inputToken.isEmpty())
|
||||
return false;
|
||||
Scanner reader = null;
|
||||
try {
|
||||
reader = new Scanner(file);
|
||||
while (reader.hasNextLine()) {
|
||||
final String line = reader.nextLine();
|
||||
if (line.contains(":")) {
|
||||
String[] tokenInfo = line.split(":");
|
||||
if(tokenInfo[0].equals(inputToken) && System.currentTimeMillis()/1000-30 <= Integer.parseInt(tokenInfo[1]) ) {
|
||||
file.delete();
|
||||
reader.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
reader.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate Random Token
|
||||
*/
|
||||
private String generateToken() {
|
||||
// obtain new random token
|
||||
Random rnd = new Random ();
|
||||
char[] arr = new char[5];
|
||||
for (int i=0; i<5; i++) {
|
||||
int n = rnd.nextInt (36);
|
||||
arr[i] = (char) (n < 10 ? '0'+n : 'a'+n-10);
|
||||
}
|
||||
return new String(arr);
|
||||
}
|
||||
|
||||
public enum groupType {
|
||||
UNREGISTERED, REGISTERED, NOTLOGGEDIN, LOGGEDIN
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package fr.xephi.authme.api;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.plugin.manager.CombatTagComunicator;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class API {
|
||||
|
||||
public static final String newline = System.getProperty("line.separator");
|
||||
public static AuthMe instance;
|
||||
public static DataSource database;
|
||||
|
||||
public API(AuthMe instance, DataSource database) {
|
||||
API.instance = instance;
|
||||
API.database = database;
|
||||
}
|
||||
/**
|
||||
* Hook into AuthMe
|
||||
* @return AuthMe instance
|
||||
*/
|
||||
public static AuthMe hookAuthMe() {
|
||||
Plugin plugin = Bukkit.getServer().getPluginManager().getPlugin("AuthMe");
|
||||
if (plugin == null && !(plugin instanceof AuthMe)) {
|
||||
return null;
|
||||
}
|
||||
return (AuthMe) plugin;
|
||||
}
|
||||
|
||||
public AuthMe getPlugin() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @return true if player is authenticate
|
||||
*/
|
||||
public static boolean isAuthenticated(Player player) {
|
||||
return PlayerCache.getInstance().isAuthenticated(player.getName().toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @return true if player is a npc
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isaNPC(Player player) {
|
||||
if (instance.getCitizensCommunicator().isNPC(player, instance))
|
||||
return true;
|
||||
return CombatTagComunicator.isNPC(player);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @return true if player is a npc
|
||||
*/
|
||||
public boolean isNPC(Player player) {
|
||||
if (instance.getCitizensCommunicator().isNPC(player, instance))
|
||||
return true;
|
||||
return CombatTagComunicator.isNPC(player);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param player
|
||||
* @return true if the player is unrestricted
|
||||
*/
|
||||
public static boolean isUnrestricted(Player player) {
|
||||
return Utils.getInstance().isUnrestricted(player);
|
||||
}
|
||||
|
||||
public static Location getLastLocation(Player player) {
|
||||
try {
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(player.getName().toLowerCase());
|
||||
|
||||
if (auth != null) {
|
||||
Location loc = new Location(Bukkit.getWorld(auth.getWorld()), auth.getQuitLocX(), auth.getQuitLocY() , auth.getQuitLocZ());
|
||||
return loc;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
} catch (NullPointerException ex) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setPlayerInventory(Player player, ItemStack[] content, ItemStack[] armor) {
|
||||
try {
|
||||
player.getInventory().setContents(content);
|
||||
player.getInventory().setArmorContents(armor);
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param playerName
|
||||
* @return true if player is registered
|
||||
*/
|
||||
public static boolean isRegistered(String playerName) {
|
||||
String player = playerName.toLowerCase();
|
||||
return database.isAuthAvailable(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String playerName, String passwordToCheck
|
||||
* @return true if the password is correct , false else
|
||||
*/
|
||||
public static boolean checkPassword(String playerName, String passwordToCheck) {
|
||||
if (!isRegistered(playerName)) return false;
|
||||
String player = playerName.toLowerCase();
|
||||
PlayerAuth auth = database.getAuth(player);
|
||||
try {
|
||||
return PasswordSecurity.comparePasswordWithHash(passwordToCheck, auth.getHash(), player);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a player
|
||||
* @param String playerName, String password
|
||||
* @return true if the player is register correctly
|
||||
*/
|
||||
public static boolean registerPlayer(String playerName, String password) {
|
||||
try {
|
||||
String name = playerName.toLowerCase();
|
||||
String hash = PasswordSecurity.getHash(Settings.getPasswordHash, password, name);
|
||||
if (isRegistered(name)) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth auth = new PlayerAuth(name, hash, "198.18.0.1", 0);
|
||||
if (!database.saveAuth(auth)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
package fr.xephi.authme.cache.auth;
|
||||
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
public class PlayerAuth {
|
||||
|
||||
private String nickname;
|
||||
private String hash;
|
||||
private String ip = "198.18.0.1";
|
||||
private long lastLogin;
|
||||
private int x = 0;
|
||||
private int y = 0;
|
||||
private int z = 0;
|
||||
private String world = "world";
|
||||
private String salt = "";
|
||||
private String vBhash = null;
|
||||
private int groupId;
|
||||
private String email = "your@email.com";
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin, String email) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, int x, int y, int z, String world) {
|
||||
this.nickname = nickname;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin, int x, int y, int z, String world, String email) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String salt, int groupId, String ip, long lastLogin, int x, int y, int z, String world, String email) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
this.salt = salt;
|
||||
this.groupId = groupId;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String salt, int groupId , String ip, long lastLogin) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.salt = salt;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String salt, String ip, long lastLogin) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String salt, String ip, long lastLogin, int x, int y, int z, String world, String email) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
this.salt = salt;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public PlayerAuth(String nickname, String hash, String ip, long lastLogin, int x, int y, int z, String world) {
|
||||
this.nickname = nickname;
|
||||
this.hash = hash;
|
||||
this.ip = ip;
|
||||
this.lastLogin = lastLogin;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.world = world;
|
||||
this.email = "your@email.com";
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
if(!salt.isEmpty() && Settings.getPasswordHash == HashAlgorithm.MD5VB) {
|
||||
vBhash = "$MD5vb$"+salt+"$"+hash;
|
||||
return vBhash;
|
||||
}
|
||||
else {
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
public String getSalt() {
|
||||
return this.salt;
|
||||
}
|
||||
|
||||
public int getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public int getQuitLocX() {
|
||||
return x;
|
||||
}
|
||||
public int getQuitLocY() {
|
||||
return y;
|
||||
}
|
||||
public int getQuitLocZ() {
|
||||
return z;
|
||||
}
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
public void setQuitLocX(int x) {
|
||||
this.x = x;
|
||||
}
|
||||
public void setQuitLocY(int y) {
|
||||
this.y = y;
|
||||
}
|
||||
public void setQuitLocZ(int z) {
|
||||
this.z = z;
|
||||
}
|
||||
public long getLastLogin() {
|
||||
return lastLogin;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public void setLastLogin(long lastLogin) {
|
||||
this.lastLogin = lastLogin;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public void setSalt(String salt) {
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof PlayerAuth)) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth other = (PlayerAuth) obj;
|
||||
return other.getIp().equals(this.ip) && other.getNickname().equals(this.nickname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hashCode = 7;
|
||||
hashCode = 71 * hashCode + (this.nickname != null ? this.nickname.hashCode() : 0);
|
||||
hashCode = 71 * hashCode + (this.ip != null ? this.ip.hashCode() : 0);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public void setWorld(String world) {
|
||||
this.world = world;
|
||||
}
|
||||
|
||||
public String getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String s = "Player : " + nickname + " ! IP : " + ip + " ! LastLogin : " + lastLogin + " ! LastPosition : " + x + "," + y + "," + z + "," + world
|
||||
+ " ! Email : " + email + " ! Hash : " + hash + " ! Salt : " + salt;
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package fr.xephi.authme.cache.auth;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PlayerCache {
|
||||
|
||||
private static PlayerCache singleton = null;
|
||||
private HashMap<String, PlayerAuth> cache;
|
||||
|
||||
private PlayerCache() {
|
||||
cache = new HashMap<String, PlayerAuth>();
|
||||
}
|
||||
|
||||
public void addPlayer(PlayerAuth auth) {
|
||||
cache.put(auth.getNickname().toLowerCase(), auth);
|
||||
}
|
||||
|
||||
public void updatePlayer(PlayerAuth auth) {
|
||||
cache.remove(auth.getNickname().toLowerCase());
|
||||
cache.put(auth.getNickname().toLowerCase(), auth);
|
||||
}
|
||||
|
||||
public void removePlayer(String user) {
|
||||
cache.remove(user.toLowerCase());
|
||||
}
|
||||
|
||||
public boolean isAuthenticated(String user) {
|
||||
return cache.containsKey(user.toLowerCase());
|
||||
}
|
||||
|
||||
public PlayerAuth getAuth(String user) {
|
||||
return cache.get(user.toLowerCase());
|
||||
}
|
||||
|
||||
public static PlayerCache getInstance() {
|
||||
if (singleton == null) {
|
||||
singleton = new PlayerCache();
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package fr.xephi.authme.cache.backup;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class DataFileCache {
|
||||
|
||||
private ItemStack[] inventory;
|
||||
private ItemStack[] armor;
|
||||
private String group;
|
||||
private boolean operator;
|
||||
private boolean flying;
|
||||
|
||||
public DataFileCache(ItemStack[] inventory, ItemStack[] armor){
|
||||
this.inventory = inventory;
|
||||
this.armor = armor;
|
||||
}
|
||||
|
||||
public DataFileCache(ItemStack[] inventory, ItemStack[] armor, String group, boolean operator, boolean flying){
|
||||
this.inventory = inventory;
|
||||
this.armor = armor;
|
||||
this.group = group;
|
||||
this.operator = operator;
|
||||
this.flying = flying;
|
||||
}
|
||||
|
||||
public ItemStack[] getInventory(){
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public ItemStack[] getArmour(){
|
||||
return armor;
|
||||
}
|
||||
|
||||
public String getGroup(){
|
||||
return group;
|
||||
}
|
||||
|
||||
public boolean getOperator(){
|
||||
return operator;
|
||||
}
|
||||
|
||||
public boolean isFlying(){
|
||||
return flying;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package fr.xephi.authme.cache.backup;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
||||
import java.util.Scanner;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import fr.xephi.authme.api.API;
|
||||
|
||||
public class FileCache {
|
||||
|
||||
public FileCache() {
|
||||
final File folder = new File("cache");
|
||||
if (!folder.exists()) {
|
||||
folder.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void createCache(String playername, DataFileCache playerData, String group, boolean operator, boolean flying) {
|
||||
final File file = new File("cache/" + playername
|
||||
+ ".cache");
|
||||
|
||||
if (file.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileWriter writer = null;
|
||||
try {
|
||||
file.createNewFile();
|
||||
|
||||
writer = new FileWriter(file);
|
||||
|
||||
String s = group+";";
|
||||
if (operator)
|
||||
s = s + "1";
|
||||
else s = s + "0";
|
||||
|
||||
// line format Group|OperatorStatus|isFlying
|
||||
if(flying)
|
||||
writer.write(s+";1" + API.newline);
|
||||
else writer.write(s+";0" + API.newline);
|
||||
writer.flush();
|
||||
|
||||
ItemStack[] invstack = playerData.getInventory();
|
||||
|
||||
for (int i = 0; i < invstack.length; i++) {
|
||||
|
||||
int itemid = 0;
|
||||
int amount = 0;
|
||||
int durability = 0;
|
||||
String enchList = "";
|
||||
if (invstack[i] != null) {
|
||||
itemid = invstack[i].getTypeId();
|
||||
amount = invstack[i].getAmount();
|
||||
durability = invstack[i].getDurability();
|
||||
for(Enchantment e : invstack[i].getEnchantments().keySet()) {
|
||||
enchList = enchList.concat(e.getName()+":"+invstack[i].getEnchantmentLevel(e)+":");
|
||||
}
|
||||
}
|
||||
writer.write("i" + ":" + itemid + ":" + amount + ":"
|
||||
+ durability + ":"+ enchList + "\r\n");
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
ItemStack[] armorstack = playerData.getArmour();
|
||||
|
||||
for (int i = 0; i < armorstack.length; i++) {
|
||||
int itemid = 0;
|
||||
int amount = 0;
|
||||
int durability = 0;
|
||||
String enchList = "";
|
||||
if (armorstack[i] != null) {
|
||||
itemid = armorstack[i].getTypeId();
|
||||
amount = armorstack[i].getAmount();
|
||||
durability = armorstack[i].getDurability();
|
||||
for(Enchantment e : armorstack[i].getEnchantments().keySet()) {
|
||||
enchList = enchList.concat(e.getName()+":"+armorstack[i].getEnchantmentLevel(e)+":");
|
||||
}
|
||||
}
|
||||
writer.write("w" + ":" + itemid + ":" + amount + ":"
|
||||
+ durability + ":"+ enchList + "\r\n");
|
||||
writer.flush();
|
||||
}
|
||||
writer.close();
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public DataFileCache readCache(String playername) {
|
||||
final File file = new File("cache/" + playername
|
||||
+ ".cache");
|
||||
|
||||
ItemStack[] stacki = new ItemStack[36];
|
||||
ItemStack[] stacka = new ItemStack[4];
|
||||
String group = null;
|
||||
boolean op = false;
|
||||
boolean flying = false;
|
||||
if (!file.exists()) {
|
||||
return new DataFileCache(stacki, stacka);
|
||||
}
|
||||
|
||||
Scanner reader = null;
|
||||
try {
|
||||
reader = new Scanner(file);
|
||||
|
||||
int i = 0;
|
||||
int a = 0;
|
||||
while (reader.hasNextLine()) {
|
||||
final String line = reader.nextLine();
|
||||
|
||||
if (!line.contains(":")) {
|
||||
// the fist line represent the player group, operator status and flying status
|
||||
final String[] playerInfo = line.split(";");
|
||||
group = playerInfo[0];
|
||||
|
||||
if (Integer.parseInt(playerInfo[1]) == 1) {
|
||||
op = true;
|
||||
} else op = false;
|
||||
if (playerInfo.length > 2) {
|
||||
if (Integer.parseInt(playerInfo[2]) == 1)
|
||||
flying = true;
|
||||
else flying = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
final String[] in = line.split(":");
|
||||
if (!in[0].equals("i") && !in[0].equals("w")) {
|
||||
continue;
|
||||
}
|
||||
// can enchant item? size ofstring in file - 4 all / 2 = number of enchant
|
||||
if (in[0].equals("i")) {
|
||||
stacki[i] = new ItemStack(Integer.parseInt(in[1]),
|
||||
Integer.parseInt(in[2]), Short.parseShort((in[3])));
|
||||
if(in.length > 4 && !in[4].isEmpty()) {
|
||||
for(int k=4;k<in.length-1;k++) {
|
||||
stacki[i].addUnsafeEnchantment(Enchantment.getByName(in[k]) ,Integer.parseInt(in[k+1]));
|
||||
k++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
} else {
|
||||
stacka[a] = new ItemStack(Integer.parseInt(in[1]),
|
||||
Integer.parseInt(in[2]), Short.parseShort((in[3])));
|
||||
if(in.length > 4 && !in[4].isEmpty()) {
|
||||
for(int k=4;k<in.length-1;k++) {
|
||||
stacka[a].addUnsafeEnchantment(Enchantment.getByName(in[k]) ,Integer.parseInt(in[k+1]));
|
||||
k++;
|
||||
}
|
||||
}
|
||||
a++;
|
||||
}
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
return new DataFileCache(stacki, stacka, group, op, flying);
|
||||
}
|
||||
|
||||
public void removeCache(String playername) {
|
||||
final File file = new File("cache/" + playername
|
||||
+ ".cache");
|
||||
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean doesCacheExist(String playername) {
|
||||
final File file = new File("cache/" + playername
|
||||
+ ".cache");
|
||||
|
||||
if (file.exists()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package fr.xephi.authme.cache.limbo;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.api.API;
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
import fr.xephi.authme.events.ResetInventoryEvent;
|
||||
import fr.xephi.authme.events.StoreInventoryEvent;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class LimboCache {
|
||||
|
||||
private static LimboCache singleton = null;
|
||||
public HashMap<String, LimboPlayer> cache;
|
||||
private FileCache playerData = new FileCache();
|
||||
public AuthMe plugin;
|
||||
|
||||
private LimboCache(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.cache = new HashMap<String, LimboPlayer>();
|
||||
}
|
||||
|
||||
public void addLimboPlayer(Player player) {
|
||||
String name = player.getName().toLowerCase();
|
||||
Location loc = player.getLocation();
|
||||
int gameMode = player.getGameMode().getValue();
|
||||
ItemStack[] arm;
|
||||
ItemStack[] inv;
|
||||
boolean operator;
|
||||
String playerGroup = "";
|
||||
boolean flying;
|
||||
|
||||
if (playerData.doesCacheExist(name)) {
|
||||
StoreInventoryEvent event = new StoreInventoryEvent(player, playerData);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled() && event.getInventory() != null && event.getArmor() != null) {
|
||||
inv = event.getInventory();
|
||||
arm = event.getArmor();
|
||||
} else {
|
||||
inv = null;
|
||||
arm = null;
|
||||
}
|
||||
playerGroup = playerData.readCache(name).getGroup();
|
||||
operator = playerData.readCache(name).getOperator();
|
||||
flying = playerData.readCache(name).isFlying();
|
||||
} else {
|
||||
StoreInventoryEvent event = new StoreInventoryEvent(player);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled() && event.getInventory() != null && event.getArmor() != null) {
|
||||
inv = event.getInventory();
|
||||
arm = event.getArmor();
|
||||
} else {
|
||||
inv = null;
|
||||
arm = null;
|
||||
}
|
||||
if(player.isOp())
|
||||
operator = true;
|
||||
else operator = false;
|
||||
if(player.isFlying())
|
||||
flying = true;
|
||||
else flying = false;
|
||||
}
|
||||
|
||||
if(Settings.isForceSurvivalModeEnabled) {
|
||||
if(Settings.isResetInventoryIfCreative && gameMode != 0 ) {
|
||||
ResetInventoryEvent event = new ResetInventoryEvent(player);
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
if (!event.isCancelled()) {
|
||||
API.setPlayerInventory(player, new ItemStack[36], new ItemStack[4]);
|
||||
player.sendMessage("Your inventory has been cleaned!");
|
||||
}
|
||||
}
|
||||
gameMode = 0;
|
||||
}
|
||||
if(player.isDead()) {
|
||||
loc = plugin.getSpawnLocation(player.getWorld());
|
||||
}
|
||||
try {
|
||||
if(cache.containsKey(name) && playerGroup.isEmpty()) {
|
||||
LimboPlayer groupLimbo = cache.get(name);
|
||||
playerGroup = groupLimbo.getGroup();
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
}
|
||||
cache.put(player.getName().toLowerCase(), new LimboPlayer(name, loc, inv, arm, gameMode, operator, playerGroup, flying));
|
||||
}
|
||||
|
||||
public void addLimboPlayer(Player player, String group) {
|
||||
cache.put(player.getName().toLowerCase(), new LimboPlayer(player.getName().toLowerCase(), group));
|
||||
}
|
||||
|
||||
public void deleteLimboPlayer(String name) {
|
||||
cache.remove(name);
|
||||
}
|
||||
|
||||
public LimboPlayer getLimboPlayer(String name) {
|
||||
return cache.get(name);
|
||||
}
|
||||
|
||||
public boolean hasLimboPlayer(String name) {
|
||||
return cache.containsKey(name);
|
||||
}
|
||||
|
||||
public static LimboCache getInstance() {
|
||||
if (singleton == null) {
|
||||
singleton = new LimboCache(AuthMe.getInstance());
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
public void updateLimboPlayer(Player player) {
|
||||
if (this.hasLimboPlayer(player.getName().toLowerCase())) {
|
||||
this.deleteLimboPlayer(player.getName().toLowerCase());
|
||||
}
|
||||
this.addLimboPlayer(player);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package fr.xephi.authme.cache.limbo;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class LimboPlayer {
|
||||
|
||||
private String name;
|
||||
private ItemStack[] inventory;
|
||||
private ItemStack[] armour;
|
||||
private Location loc = null;
|
||||
private int timeoutTaskId = -1;
|
||||
private int messageTaskId = -1;
|
||||
private int gameMode = 0;
|
||||
private boolean operator = false;
|
||||
private String group = null;
|
||||
private boolean flying = false;
|
||||
|
||||
public LimboPlayer(String name, Location loc, ItemStack[] inventory, ItemStack[] armour, int gameMode, boolean operator, String group, boolean flying) {
|
||||
this.name = name;
|
||||
this.loc = loc;
|
||||
this.inventory = inventory;
|
||||
this.armour = armour;
|
||||
this.gameMode = gameMode;
|
||||
this.operator = operator;
|
||||
this.group = group;
|
||||
this.flying = flying;
|
||||
}
|
||||
|
||||
public LimboPlayer(String name, Location loc, int gameMode, boolean operator, String group, boolean flying) {
|
||||
this.name = name;
|
||||
this.loc = loc;
|
||||
this.gameMode = gameMode;
|
||||
this.operator = operator;
|
||||
this.group = group;
|
||||
this.flying = flying;
|
||||
}
|
||||
|
||||
public LimboPlayer(String name, String group) {
|
||||
this.name = name;
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Location getLoc() {
|
||||
return loc;
|
||||
}
|
||||
|
||||
public ItemStack[] getArmour() {
|
||||
return armour;
|
||||
}
|
||||
|
||||
public ItemStack[] getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public void setArmour(ItemStack[] armour) {
|
||||
this.armour = armour;
|
||||
}
|
||||
|
||||
public void setInventory(ItemStack[] inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
public int getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
public boolean getOperator() {
|
||||
return operator;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
return group;
|
||||
}
|
||||
|
||||
public void setTimeoutTaskId(int i) {
|
||||
this.timeoutTaskId = i;
|
||||
}
|
||||
|
||||
public int getTimeoutTaskId() {
|
||||
return timeoutTaskId;
|
||||
}
|
||||
|
||||
public void setMessageTaskId(int messageTaskId) {
|
||||
this.messageTaskId = messageTaskId;
|
||||
}
|
||||
|
||||
public int getMessageTaskId() {
|
||||
return messageTaskId;
|
||||
}
|
||||
|
||||
public boolean isFlying() {
|
||||
return flying;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.converter.FlatToSql;
|
||||
import fr.xephi.authme.converter.FlatToSqlite;
|
||||
import fr.xephi.authme.converter.RakamakConverter;
|
||||
import fr.xephi.authme.converter.xAuthToFlat;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import fr.xephi.authme.settings.SpoutCfg;
|
||||
|
||||
|
||||
public class AdminCommand implements CommandExecutor {
|
||||
|
||||
public AuthMe plugin;
|
||||
private Messages m = Messages.getInstance();
|
||||
private SpoutCfg s = SpoutCfg.getInstance();
|
||||
public DataSource database;
|
||||
|
||||
public AdminCommand(AuthMe plugin, DataSource database) {
|
||||
this.database = database;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage("Usage: /authme reload - Reload the config");
|
||||
sender.sendMessage("/authme register <playername> <password> - Register a player");
|
||||
sender.sendMessage("/authme changepassword <playername> <password> - Change player password");
|
||||
sender.sendMessage("/authme unregister <playername> - Unregister a player");
|
||||
sender.sendMessage("/authme purge <days> - Purge Database");
|
||||
sender.sendMessage("/authme version - Get AuthMe version infos");
|
||||
sender.sendMessage("/authme lastlogin <playername> - Display Date about the Player's LastLogin");
|
||||
sender.sendMessage("/authme accounts <playername> - Display all player's accounts");
|
||||
sender.sendMessage("/authme setSpawn - Set AuthMe spawn to your current pos");
|
||||
sender.sendMessage("/authme spawn - Teleport you to the AuthMe SpawnPoint");
|
||||
sender.sendMessage("/authme chgemail <playername> <email> - Change player email");
|
||||
sender.sendMessage("/authme getemail <playername> - Get player email");
|
||||
return true;
|
||||
}
|
||||
|
||||
if((sender instanceof ConsoleCommandSender) && args[0].equalsIgnoreCase("passpartuToken")) {
|
||||
if(args.length > 1) {
|
||||
System.out.println("[AuthMe] command usage: /authme passpartuToken");
|
||||
return true;
|
||||
}
|
||||
if(Utils.getInstance().obtainToken()) {
|
||||
System.out.println("[AuthMe] You have 30s for insert this token ingame with /passpartu [token]");
|
||||
} else {
|
||||
System.out.println("[AuthMe] Security error on passpartu token, redo it. ");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme.admin." + args[0].toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("version")) {
|
||||
sender.sendMessage("AuthMe Version: "+AuthMe.getInstance().getDescription().getVersion());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args[0].equalsIgnoreCase("purge")) {
|
||||
if (args.length != 2) {
|
||||
sender.sendMessage("Usage: /authme purge <DAYS>");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
long days = Long.parseLong(args[1]) * 86400000;
|
||||
long until = new Date().getTime() - days;
|
||||
sender.sendMessage("Deleted " + database.purgeDatabase(until) + " user accounts");
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
sender.sendMessage("Usage: /authme purge <DAYS>");
|
||||
return true;
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("reload")) {
|
||||
database.reload();
|
||||
File newConfigFile = new File("plugins/AuthMe","config.yml");
|
||||
if (!newConfigFile.exists()) {
|
||||
InputStream fis = getClass().getResourceAsStream("/config.yml");
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(newConfigFile);
|
||||
byte[] buf = new byte[1024];
|
||||
int i = 0;
|
||||
|
||||
while ((i = fis.read(buf)) != -1) {
|
||||
fos.write(buf, 0, i);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, "Failed to load config from JAR");
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
YamlConfiguration newConfig = YamlConfiguration.loadConfiguration(newConfigFile);
|
||||
Settings.reloadConfigOptions(newConfig);
|
||||
m.reLoad();
|
||||
s.reLoad();
|
||||
sender.sendMessage(m._("reload"));
|
||||
} else if (args[0].equalsIgnoreCase("lastlogin")) {
|
||||
if (args.length != 2) {
|
||||
sender.sendMessage("Usage: /authme lastlogin <playername>");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
if (database.getAuth(args[1].toLowerCase()) != null) {
|
||||
PlayerAuth player = database.getAuth(args[1].toLowerCase());
|
||||
long lastLogin = player.getLastLogin();
|
||||
Date d = new Date(lastLogin);
|
||||
final long diff = System.currentTimeMillis() - lastLogin;
|
||||
final String msg = (int)(diff / 86400000) + " days " + (int)(diff / 3600000 % 24) + " hours " + (int)(diff / 60000 % 60) + " mins " + (int)(diff / 1000 % 60) + " secs.";
|
||||
String lastIP = player.getIp();
|
||||
sender.sendMessage("[AuthMe] " + args[1].toLowerCase() + " lastlogin : " + d.toString());
|
||||
sender.sendMessage("[AuthMe] The player : " + player.getNickname() + " is unlogged since " + msg);
|
||||
sender.sendMessage("[AuthMe] LastPlayer IP : " + lastIP);
|
||||
} else {
|
||||
sender.sendMessage("This player does not exist");
|
||||
return true;
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
sender.sendMessage("This player does not exist");
|
||||
return true;
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("accounts")) {
|
||||
if (args.length != 2) {
|
||||
sender.sendMessage("Usage: /authme accounts <playername>");
|
||||
sender.sendMessage("Or: /authme accounts <ip>");
|
||||
return true;
|
||||
}
|
||||
if (!args[1].contains(".")) {
|
||||
final CommandSender fSender = sender;
|
||||
final String[] arguments = args;
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PlayerAuth pAuth = null;
|
||||
String message = "[AuthMe] ";
|
||||
try {
|
||||
pAuth = database.getAuth(arguments[1].toLowerCase());
|
||||
} catch (NullPointerException npe){
|
||||
fSender.sendMessage("[AuthMe] This player is unknown");
|
||||
return;
|
||||
}
|
||||
if (pAuth != null) {
|
||||
List<String> accountList = database.getAllAuthsByName(pAuth);
|
||||
if (accountList.isEmpty() || accountList == null) {
|
||||
fSender.sendMessage("[AuthMe] This player is unknown");
|
||||
return;
|
||||
}
|
||||
if (accountList.size() == 1) {
|
||||
fSender.sendMessage("[AuthMe] " + arguments[1] + " is a single account player");
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
for (String account : accountList) {
|
||||
i++;
|
||||
message = message + account;
|
||||
if (i != accountList.size()) {
|
||||
message = message + ", ";
|
||||
} else {
|
||||
message = message + ".";
|
||||
}
|
||||
}
|
||||
fSender.sendMessage("[AuthMe] " + arguments[1] + " has " + String.valueOf(accountList.size()) + " accounts");
|
||||
fSender.sendMessage(message);
|
||||
} else {
|
||||
fSender.sendMessage("[AuthMe] This player is unknown");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
} else {
|
||||
final CommandSender fSender = sender;
|
||||
final String[] arguments = args;
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String message = "[AuthMe] ";
|
||||
if (arguments[1] != null) {
|
||||
List<String> accountList = database.getAllAuthsByIp(arguments[1]);
|
||||
if (accountList.isEmpty() || accountList == null) {
|
||||
fSender.sendMessage("[AuthMe] Please put a valid IP");
|
||||
return;
|
||||
}
|
||||
if (accountList.size() == 1) {
|
||||
fSender.sendMessage("[AuthMe] " + arguments[1] + " is a single account player");
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
for (String account : accountList) {
|
||||
i++;
|
||||
message = message + account;
|
||||
if (i != accountList.size()) {
|
||||
message = message + ", ";
|
||||
} else {
|
||||
message = message + ".";
|
||||
}
|
||||
}
|
||||
fSender.sendMessage("[AuthMe] " + arguments[1] + " has " + String.valueOf(accountList.size()) + " accounts");
|
||||
fSender.sendMessage(message);
|
||||
} else {
|
||||
fSender.sendMessage("[AuthMe] Please put a valid IP");
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("register") || args[0].equalsIgnoreCase("reg")) {
|
||||
if (args.length != 3) {
|
||||
sender.sendMessage("Usage: /authme register playername password");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
String name = args[1].toLowerCase();
|
||||
String hash = PasswordSecurity.getHash(Settings.getPasswordHash, args[2], name);
|
||||
if (database.isAuthAvailable(name)) {
|
||||
sender.sendMessage(m._("user_regged"));
|
||||
return true;
|
||||
}
|
||||
PlayerAuth auth = new PlayerAuth(name, hash, "198.18.0.1", 0);
|
||||
auth.setSalt(PasswordSecurity.userSalt.get(name));
|
||||
if (!database.saveAuth(auth)) {
|
||||
sender.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
database.updateSalt(auth);
|
||||
sender.sendMessage(m._("registered"));
|
||||
ConsoleLogger.info(args[1] + " registered");
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
sender.sendMessage(m._("error"));
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("convertflattosql")) {
|
||||
try {
|
||||
FlatToSql.FlatToSqlConverter();
|
||||
if (sender instanceof Player)
|
||||
sender.sendMessage("[AuthMe] FlatFile converted to authme.sql file");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NullPointerException ex) {
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("flattosqlite")) {
|
||||
try {
|
||||
String s = FlatToSqlite.convert();
|
||||
if (sender instanceof Player)
|
||||
sender.sendMessage(s);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NullPointerException ex) {
|
||||
System.out.println(ex.getMessage());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("xauthimport")) {
|
||||
xAuthToFlat converter = new xAuthToFlat(plugin, database);
|
||||
if (converter.convert(sender)) {
|
||||
sender.sendMessage("[AuthMe] Successfull convert from xAuth database");
|
||||
} else {
|
||||
sender.sendMessage("[AuthMe] Error while trying to convert from xAuth database");
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("getemail")) {
|
||||
if (args.length != 2) {
|
||||
sender.sendMessage("Usage: /authme getemail playername");
|
||||
return true;
|
||||
}
|
||||
String playername = args[1].toLowerCase();
|
||||
PlayerAuth getAuth = database.getAuth(playername);
|
||||
if (getAuth == null) {
|
||||
sender.sendMessage("This player does not exist");
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage("[AuthMe] " + args[1] + " email : " + getAuth.getEmail());
|
||||
return true;
|
||||
} else if (args[0].equalsIgnoreCase("chgemail")) {
|
||||
if (args.length != 3) {
|
||||
sender.sendMessage("Usage: /authme chgemail playername email");
|
||||
return true;
|
||||
}
|
||||
String playername = args[1].toLowerCase();
|
||||
PlayerAuth getAuth = database.getAuth(playername);
|
||||
if (getAuth == null) {
|
||||
sender.sendMessage("This player does not exist");
|
||||
return true;
|
||||
}
|
||||
getAuth.setEmail(args[2]);
|
||||
if (!database.updateEmail(getAuth)) {
|
||||
sender.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
if (PlayerCache.getInstance().getAuth(playername) != null)
|
||||
PlayerCache.getInstance().updatePlayer(getAuth);
|
||||
return true;
|
||||
} else if (args[0].equalsIgnoreCase("convertfromrakamak")) {
|
||||
try {
|
||||
RakamakConverter.RakamakConvert();
|
||||
if (sender instanceof Player)
|
||||
sender.sendMessage("[AuthMe] Rakamak database converted to auths.db");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NullPointerException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("setspawn")) {
|
||||
try {
|
||||
if (sender instanceof Player) {
|
||||
if (Spawn.getInstance().setSpawn(((Player) sender).getLocation()))
|
||||
sender.sendMessage("[AuthMe] Correctly define new spawn");
|
||||
else sender.sendMessage("[AuthMe] SetSpawn fail , please retry");
|
||||
} else {
|
||||
sender.sendMessage("[AuthMe] Please use that command in game");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("purgebannedplayers")) {
|
||||
List<String> bannedPlayers = new ArrayList<String>();
|
||||
for (OfflinePlayer off : plugin.getServer().getBannedPlayers()) {
|
||||
bannedPlayers.add(off.getName().toLowerCase());
|
||||
}
|
||||
final List<String> bP = bannedPlayers;
|
||||
if (database instanceof Thread) {
|
||||
database.purgeBanned(bP);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
database.purgeBanned(bP);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("spawn")) {
|
||||
try {
|
||||
if (sender instanceof Player) {
|
||||
if (Spawn.getInstance().getLocation() != null)
|
||||
((Player) sender).teleport(Spawn.getInstance().getLocation());
|
||||
else sender.sendMessage("[AuthMe] Spawn fail , please try to define the spawn");
|
||||
} else {
|
||||
sender.sendMessage("[AuthMe] Please use that command in game");
|
||||
}
|
||||
} catch (NullPointerException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("changepassword") || args[0].equalsIgnoreCase("cp")) {
|
||||
if (args.length != 3) {
|
||||
sender.sendMessage("Usage: /authme changepassword playername newpassword");
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
String name = args[1].toLowerCase();
|
||||
String hash = PasswordSecurity.getHash(Settings.getPasswordHash, args[2], name);
|
||||
PlayerAuth auth = null;
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
auth = PlayerCache.getInstance().getAuth(name);
|
||||
} else if (database.isAuthAvailable(name)) {
|
||||
auth = database.getAuth(name);
|
||||
} else {
|
||||
sender.sendMessage(m._("unknown_user"));
|
||||
return true;
|
||||
}
|
||||
auth.setHash(hash);
|
||||
auth.setSalt(PasswordSecurity.userSalt.get(name));
|
||||
if (!database.updatePassword(auth)) {
|
||||
sender.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
database.updateSalt(auth);
|
||||
sender.sendMessage("pwd_changed");
|
||||
ConsoleLogger.info(args[1] + "'s password changed");
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
sender.sendMessage(m._("error"));
|
||||
}
|
||||
} else if (args[0].equalsIgnoreCase("unregister") || args[0].equalsIgnoreCase("unreg") || args[0].equalsIgnoreCase("del") ) {
|
||||
if (args.length != 2) {
|
||||
sender.sendMessage("Usage: /authme unregister playername");
|
||||
return true;
|
||||
}
|
||||
String name = args[1].toLowerCase();
|
||||
if (!database.removeAuth(name)) {
|
||||
sender.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
sender.sendMessage("unregistered");
|
||||
ConsoleLogger.info(args[1] + " unregistered");
|
||||
} else {
|
||||
sender.sendMessage("Usage: /authme reload|register playername password|changepassword playername password|unregister playername");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class CaptchaCommand implements CommandExecutor {
|
||||
|
||||
public AuthMe plugin;
|
||||
private Messages m = Messages.getInstance();
|
||||
public static RandomString rdm = new RandomString(Settings.captchaLength);
|
||||
|
||||
public CaptchaCommand(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd,
|
||||
String label, String[] args) {
|
||||
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (args.length == 0) {
|
||||
player.sendMessage(m._("usage_captcha"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("logged_in"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(player, "authme." + label.toLowerCase())) {
|
||||
player.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Settings.useCaptcha) {
|
||||
player.sendMessage(m._("usage_log"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!plugin.cap.containsKey(name)) {
|
||||
player.sendMessage(m._("usage_log"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Settings.useCaptcha && !args[0].equals(plugin.cap.get(name))) {
|
||||
plugin.cap.remove(name);
|
||||
plugin.cap.put(name, rdm.nextString());
|
||||
player.sendMessage(m._("wrong_captcha").replaceAll("THE_CAPTCHA", plugin.cap.get(name)));
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
plugin.captcha.remove(name);
|
||||
plugin.cap.remove(name);
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
player.sendMessage(m._("valid_captcha"));
|
||||
player.sendMessage(m._("login_msg"));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import me.muizers.Notifications.Notification;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class ChangePasswordCommand implements CommandExecutor {
|
||||
|
||||
private Messages m = Messages.getInstance();
|
||||
private DataSource database;
|
||||
public AuthMe plugin;
|
||||
|
||||
public ChangePasswordCommand(DataSource database, AuthMe plugin) {
|
||||
this.database = database;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme." + label.toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
String name = player.getName().toLowerCase();
|
||||
if (!PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("not_logged_in"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length != 2) {
|
||||
player.sendMessage(m._("usage_changepassword"));
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
String hashnew = PasswordSecurity.getHash(Settings.getPasswordHash, args[1], name);
|
||||
|
||||
if (PasswordSecurity.comparePasswordWithHash(args[0], PlayerCache.getInstance().getAuth(name).getHash(), name)) {
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
|
||||
auth.setHash(hashnew);
|
||||
auth.setSalt(PasswordSecurity.userSalt.get(name));
|
||||
if (!database.updatePassword(auth)) {
|
||||
player.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
database.updateSalt(auth);
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
player.sendMessage(m._("pwd_changed"));
|
||||
ConsoleLogger.info(player.getName() + " changed his password");
|
||||
if(plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " change his password!"));
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(m._("wrong_pwd"));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
sender.sendMessage(m._("error"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class EmailCommand implements CommandExecutor {
|
||||
|
||||
public AuthMe plugin;
|
||||
private DataSource data;
|
||||
private Messages m = Messages.getInstance();
|
||||
|
||||
public EmailCommand(AuthMe plugin, DataSource data) {
|
||||
this.plugin = plugin;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme." + label.toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (args.length == 0) {
|
||||
player.sendMessage(m._("usage_email_add"));
|
||||
player.sendMessage(m._("usage_email_change"));
|
||||
player.sendMessage(m._("usage_email_recovery"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args[0].equalsIgnoreCase("add")) {
|
||||
if (args.length != 3) {
|
||||
player.sendMessage(m._("usage_email_add"));
|
||||
return true;
|
||||
}
|
||||
if(args[1].equals(args[2]) && PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
|
||||
if (auth.getEmail() == null || (!auth.getEmail().equals("your@email.com") && !auth.getEmail().isEmpty())) {
|
||||
player.sendMessage("usage_email_change");
|
||||
return true;
|
||||
}
|
||||
if (!args[1].contains("@")) {
|
||||
player.sendMessage(m._("email_invalid"));
|
||||
return true;
|
||||
}
|
||||
auth.setEmail(args[1]);
|
||||
if (!data.updateEmail(auth)) {
|
||||
player.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
player.sendMessage(m._("email_added"));
|
||||
player.sendMessage(auth.getEmail());
|
||||
} else if (PlayerCache.getInstance().isAuthenticated(name)){
|
||||
player.sendMessage(m._("email_confirm"));
|
||||
} else {
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
player.sendMessage(m._("login_msg"));
|
||||
} else {
|
||||
player.sendMessage(m._("reg_email_msg"));
|
||||
}
|
||||
}
|
||||
} else if(args[0].equalsIgnoreCase("change") && args.length == 3 ) {
|
||||
if(PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
|
||||
if (auth.getEmail() == null || auth.getEmail().equals("your@email.com") || auth.getEmail().isEmpty()) {
|
||||
player.sendMessage(m._("usage_email_add"));
|
||||
return true;
|
||||
}
|
||||
if (!args[1].equals(auth.getEmail())) {
|
||||
player.sendMessage(m._("old_email_invalid"));
|
||||
return true;
|
||||
}
|
||||
if (!args[2].contains("@")) {
|
||||
player.sendMessage(m._("new_email_invalid"));
|
||||
return true;
|
||||
}
|
||||
auth.setEmail(args[2]);
|
||||
if (!data.updateEmail(auth)) {
|
||||
player.sendMessage(m._("bad_database_email"));
|
||||
return true;
|
||||
}
|
||||
PlayerCache.getInstance().updatePlayer(auth);
|
||||
player.sendMessage(m._("email_changed"));
|
||||
player.sendMessage(m._("email_defined") + auth.getEmail());
|
||||
} else if (PlayerCache.getInstance().isAuthenticated(name)){
|
||||
player.sendMessage(m._("email_confirm"));
|
||||
} else {
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
player.sendMessage(m._("login_msg"));
|
||||
} else {
|
||||
player.sendMessage(m._("reg_email_msg"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(args[0].equalsIgnoreCase("recovery")) {
|
||||
if (args.length != 2) {
|
||||
player.sendMessage(m._("usage_email_recovery"));
|
||||
return true;
|
||||
}
|
||||
if (plugin.mail == null) {
|
||||
player.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
if (data.isAuthAvailable(name)) {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("logged_in"));
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
RandomString rand = new RandomString(Settings.getRecoveryPassLength);
|
||||
String thePass = rand.nextString();
|
||||
String hashnew = PasswordSecurity.getHash(Settings.getPasswordHash, thePass, name);
|
||||
PlayerAuth auth = null;
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
auth = PlayerCache.getInstance().getAuth(name);
|
||||
} else if (data.isAuthAvailable(name)) {
|
||||
auth = data.getAuth(name);
|
||||
} else {
|
||||
sender.sendMessage(m._("unknown_user"));
|
||||
return true;
|
||||
}
|
||||
if (Settings.getmailAccount.equals("") || Settings.getmailAccount.isEmpty()) {
|
||||
player.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!args[1].equalsIgnoreCase(auth.getEmail())) {
|
||||
player.sendMessage(m._("email_invalid"));
|
||||
return true;
|
||||
}
|
||||
final String finalhashnew = hashnew;
|
||||
final PlayerAuth finalauth = auth;
|
||||
if (data instanceof Thread) {
|
||||
finalauth.setHash(hashnew);
|
||||
data.updatePassword(auth);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finalauth.setHash(finalhashnew);
|
||||
data.updatePassword(finalauth);
|
||||
}
|
||||
});
|
||||
}
|
||||
plugin.mail.main(auth, thePass);
|
||||
player.sendMessage(m._("email_send"));
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
sender.sendMessage(m._("error"));
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
ConsoleLogger.showError(ncdfe.getMessage());
|
||||
sender.sendMessage(m._("error"));
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(m._("reg_email_msg"));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
|
||||
|
||||
public class LoginCommand implements CommandExecutor {
|
||||
|
||||
private AuthMe plugin;
|
||||
private Messages m = Messages.getInstance();
|
||||
|
||||
public LoginCommand(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, final String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Player player = (Player) sender;
|
||||
|
||||
if (args.length == 0) {
|
||||
player.sendMessage(m._("usage_log"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(player, "authme." + label.toLowerCase())) {
|
||||
player.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
plugin.management.performLogin(player, args[0], false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import me.muizers.Notifications.Notification;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.DataFileCache;
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.events.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.PlayersLogs;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
|
||||
|
||||
public class LogoutCommand implements CommandExecutor {
|
||||
|
||||
private Messages m = Messages.getInstance();
|
||||
private PlayersLogs pllog = PlayersLogs.getInstance();
|
||||
private AuthMe plugin;
|
||||
private DataSource database;
|
||||
private Utils utils = Utils.getInstance();
|
||||
private FileCache playerBackup = new FileCache();
|
||||
|
||||
public LogoutCommand(AuthMe plugin, DataSource database) {
|
||||
this.plugin = plugin;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme." + label.toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (!PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("not_logged_in"));
|
||||
return true;
|
||||
}
|
||||
|
||||
PlayerAuth auth = PlayerCache.getInstance().getAuth(name);
|
||||
auth.setIp("198.18.0.1");
|
||||
database.updateSession(auth);
|
||||
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
|
||||
LimboCache.getInstance().addLimboPlayer(player , utils.removeAll(player));
|
||||
LimboCache.getInstance().addLimboPlayer(player);
|
||||
if(Settings.protectInventoryBeforeLogInEnabled) {
|
||||
player.getInventory().setArmorContents(new ItemStack[4]);
|
||||
player.getInventory().setContents(new ItemStack[36]);
|
||||
// create cache file for handling lost of inventories on unlogged in status
|
||||
DataFileCache playerData = new DataFileCache(player.getInventory().getContents(),player.getInventory().getArmorContents());
|
||||
playerBackup.createCache(name, playerData, LimboCache.getInstance().getLimboPlayer(name).getGroup(),LimboCache.getInstance().getLimboPlayer(name).getOperator(),LimboCache.getInstance().getLimboPlayer(name).isFlying());
|
||||
}
|
||||
if (Settings.isTeleportToSpawnEnabled) {
|
||||
Location spawnLoc = player.getWorld().getSpawnLocation();
|
||||
if (plugin.essentialsSpawn != null) {
|
||||
spawnLoc = plugin.essentialsSpawn;
|
||||
}
|
||||
if (Spawn.getInstance().getLocation() != null)
|
||||
spawnLoc = Spawn.getInstance().getLocation();
|
||||
AuthMeTeleportEvent tpEvent = new AuthMeTeleportEvent(player, spawnLoc);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if(!tpEvent.isCancelled()) {
|
||||
if (!tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).isLoaded()) {
|
||||
tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).load();
|
||||
}
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
|
||||
int delay = Settings.getRegistrationTimeout * 20;
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler sched = sender.getServer().getScheduler();
|
||||
if (delay != 0) {
|
||||
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name), delay);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id.getTaskId());
|
||||
}
|
||||
BukkitTask msgT = sched.runTask(plugin, new MessageTask(plugin, name, m._("login_msg"), interval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT.getTaskId());
|
||||
try {
|
||||
if (PlayersLogs.players.contains(player.getName())) {
|
||||
PlayersLogs.players.remove(player.getName());
|
||||
pllog.save();
|
||||
}
|
||||
if (player.isInsideVehicle())
|
||||
player.getVehicle().eject();
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
player.sendMessage(m._("logout"));
|
||||
ConsoleLogger.info(player.getDisplayName() + " logged out");
|
||||
if(plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " logged out!"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author stefano
|
||||
*/
|
||||
public class PasspartuCommand implements CommandExecutor {
|
||||
private Utils utils = new Utils();
|
||||
public AuthMe plugin;
|
||||
private Messages m;
|
||||
|
||||
public PasspartuCommand(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme." + label.toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(sender.getName().toLowerCase())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((sender instanceof Player) && args.length == 1) {
|
||||
if(utils.readToken(args[0])) {
|
||||
//bypass login!
|
||||
plugin.management.performLogin((Player) sender, "dontneed", true);
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage("Time is expired or Token is Wrong!");
|
||||
return true;
|
||||
}
|
||||
sender.sendMessage("usage: /passpartu token");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Date;
|
||||
|
||||
import me.muizers.Notifications.Notification;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.Utils;
|
||||
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.DataSource;
|
||||
import fr.xephi.authme.events.RegisterTeleportEvent;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.PlayersLogs;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
|
||||
|
||||
public class RegisterCommand implements CommandExecutor {
|
||||
|
||||
private Messages m = Messages.getInstance();
|
||||
private PlayersLogs pllog = PlayersLogs.getInstance();
|
||||
private DataSource database;
|
||||
public boolean isFirstTimeJoin;
|
||||
public PlayerAuth auth;
|
||||
public AuthMe plugin;
|
||||
|
||||
public RegisterCommand(DataSource database, AuthMe plugin) {
|
||||
this.database = database;
|
||||
this.isFirstTimeJoin = false;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme." + label.toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
final Player player = (Player) sender;
|
||||
final String name = player.getName().toLowerCase();
|
||||
String ipA = player.getAddress().getAddress().getHostAddress();
|
||||
|
||||
if (Settings.bungee) {
|
||||
if (plugin.realIp.containsKey(name))
|
||||
ipA = plugin.realIp.get(name);
|
||||
}
|
||||
|
||||
final String ip = ipA;
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("logged_in"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Settings.isRegistrationEnabled) {
|
||||
player.sendMessage(m._("reg_disabled"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (database.isAuthAvailable(player.getName().toLowerCase())) {
|
||||
player.sendMessage(m._("user_regged"));
|
||||
if (pllog.getStringList("players").contains(player.getName())) {
|
||||
pllog.getStringList("players").remove(player.getName());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Settings.getmaxRegPerIp > 0 ){
|
||||
if(!plugin.authmePermissible(sender, "authme.allow2accounts") && database.getAllAuthsByIp(ipA).size() >= Settings.getmaxRegPerIp) {
|
||||
player.sendMessage(m._("max_reg"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if(Settings.emailRegistration && !Settings.getmailAccount.isEmpty()) {
|
||||
if(!args[0].contains("@")) {
|
||||
player.sendMessage(m._("usage_reg"));
|
||||
return true;
|
||||
}
|
||||
if(Settings.doubleEmailCheck) {
|
||||
if(args.length < 2) {
|
||||
player.sendMessage(m._("usage_reg"));
|
||||
return true;
|
||||
}
|
||||
if(!args[0].equals(args[1])) {
|
||||
player.sendMessage(m._("usage_reg"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final String email = args[0];
|
||||
if(Settings.getmaxRegPerEmail > 0) {
|
||||
if (!plugin.authmePermissible(sender, "authme.allow2accounts") && database.getAllAuthsByEmail(email).size() >= Settings.getmaxRegPerEmail) {
|
||||
player.sendMessage(m._("max_reg"));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
RandomString rand = new RandomString(Settings.getRecoveryPassLength);
|
||||
final String thePass = rand.nextString();
|
||||
if (!thePass.isEmpty()) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (PasswordSecurity.userSalt.containsKey(name)) {
|
||||
try {
|
||||
final String hashnew = PasswordSecurity.getHash(Settings.getPasswordHash, thePass, name);
|
||||
final PlayerAuth fAuth = new PlayerAuth(name, hashnew, PasswordSecurity.userSalt.get(name), ip, new Date().getTime(), (int) player.getLocation().getX() , (int) player.getLocation().getY(), (int) player.getLocation().getZ(), player.getLocation().getWorld().getName(), email);
|
||||
database.saveAuth(fAuth);
|
||||
database.updateEmail(fAuth);
|
||||
database.updateSession(fAuth);
|
||||
plugin.mail.main(fAuth, thePass);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
final String hashnew = PasswordSecurity.getHash(Settings.getPasswordHash, thePass, name);
|
||||
final PlayerAuth fAuth = new PlayerAuth(name, hashnew, ip, new Date().getTime(), (int) player.getLocation().getX() , (int) player.getLocation().getY(), (int) player.getLocation().getZ(), player.getLocation().getWorld().getName(), email);
|
||||
database.saveAuth(fAuth);
|
||||
database.updateEmail(fAuth);
|
||||
database.updateSession(fAuth);
|
||||
plugin.mail.main(fAuth, thePass);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(!Settings.getRegisteredGroup.isEmpty()){
|
||||
Utils.getInstance().setGroup(player, Utils.groupType.REGISTERED);
|
||||
}
|
||||
player.sendMessage(m._("vb_nonActiv"));
|
||||
String msg = m._("login_msg");
|
||||
int time = Settings.getRegistrationTimeout * 20;
|
||||
int msgInterval = Settings.getWarnMessageInterval;
|
||||
if (time != 0) {
|
||||
Bukkit.getScheduler().cancelTask(LimboCache.getInstance().getLimboPlayer(name).getTimeoutTaskId());
|
||||
BukkitTask id = Bukkit.getScheduler().runTaskLater(plugin, new TimeoutTask(plugin, name), time);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id.getTaskId());
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().cancelTask(LimboCache.getInstance().getLimboPlayer(name).getMessageTaskId());
|
||||
BukkitTask nwMsg = Bukkit.getScheduler().runTask(plugin, new MessageTask(plugin, name, msg, msgInterval));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(nwMsg.getTaskId());
|
||||
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
if (Settings.isTeleportToSpawnEnabled) {
|
||||
World world = player.getWorld();
|
||||
Location loca = plugin.getSpawnLocation(world);
|
||||
RegisterTeleportEvent tpEvent = new RegisterTeleportEvent(player, loca);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if(!tpEvent.isCancelled()) {
|
||||
if (!tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).isLoaded()) {
|
||||
tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).load();
|
||||
}
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
this.isFirstTimeJoin = true;
|
||||
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
|
||||
player.setAllowFlight(false);
|
||||
player.setFlying(false);
|
||||
}
|
||||
player.saveData();
|
||||
if (!Settings.noConsoleSpam)
|
||||
ConsoleLogger.info(player.getName() + " registered "+player.getAddress().getAddress().getHostAddress());
|
||||
if(plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " has registered!"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.length == 0 || (Settings.getEnablePasswordVerifier && args.length < 2) ) {
|
||||
player.sendMessage(m._("usage_reg"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if(args[0].length() < Settings.getPasswordMinLen || args[0].length() > Settings.passwordMaxLength) {
|
||||
player.sendMessage(m._("pass_len"));
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
String hash;
|
||||
if(Settings.getEnablePasswordVerifier) {
|
||||
if (args[0].equals(args[1])) {
|
||||
hash = PasswordSecurity.getHash(Settings.getPasswordHash, args[0], name);
|
||||
} else {
|
||||
player.sendMessage(m._("password_error"));
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
hash = PasswordSecurity.getHash(Settings.getPasswordHash, args[0], name);
|
||||
if (Settings.getMySQLColumnSalt.isEmpty())
|
||||
{
|
||||
auth = new PlayerAuth(name, hash, ip, new Date().getTime());
|
||||
} else {
|
||||
auth = new PlayerAuth(name, hash, PasswordSecurity.userSalt.get(name), ip, new Date().getTime());
|
||||
}
|
||||
if (!database.saveAuth(auth)) {
|
||||
player.sendMessage(m._("error"));
|
||||
return true;
|
||||
}
|
||||
PlayerCache.getInstance().addPlayer(auth);
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
if (limbo != null) {
|
||||
player.setGameMode(GameMode.getByValue(limbo.getGameMode()));
|
||||
if (Settings.isTeleportToSpawnEnabled) {
|
||||
World world = player.getWorld();
|
||||
Location loca = plugin.getSpawnLocation(world);
|
||||
RegisterTeleportEvent tpEvent = new RegisterTeleportEvent(player, loca);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if(!tpEvent.isCancelled()) {
|
||||
if (!tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).isLoaded()) {
|
||||
tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).load();
|
||||
}
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
sender.getServer().getScheduler().cancelTask(limbo.getTimeoutTaskId());
|
||||
sender.getServer().getScheduler().cancelTask(limbo.getMessageTaskId());
|
||||
LimboCache.getInstance().deleteLimboPlayer(name);
|
||||
}
|
||||
|
||||
if(!Settings.getRegisteredGroup.isEmpty()){
|
||||
Utils.getInstance().setGroup(player, Utils.groupType.REGISTERED);
|
||||
}
|
||||
player.sendMessage(m._("registered"));
|
||||
if (!Settings.getmailAccount.isEmpty())
|
||||
player.sendMessage(m._("add_email"));
|
||||
this.isFirstTimeJoin = true;
|
||||
if (player.getGameMode() != GameMode.CREATIVE && !Settings.isMovementAllowed) {
|
||||
player.setAllowFlight(false);
|
||||
player.setFlying(false);
|
||||
}
|
||||
player.saveData();
|
||||
if (!Settings.noConsoleSpam)
|
||||
ConsoleLogger.info(player.getName() + " registered "+player.getAddress().getAddress().getHostAddress());
|
||||
if(plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " has registered!"));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
sender.sendMessage(m._("error"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package fr.xephi.authme.commands;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import me.muizers.Notifications.Notification;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.events.SpawnTeleportEvent;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
import fr.xephi.authme.settings.PlayersLogs;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.task.TimeoutTask;
|
||||
|
||||
|
||||
public class UnregisterCommand implements CommandExecutor {
|
||||
|
||||
private Messages m = Messages.getInstance();
|
||||
private PlayersLogs pllog = PlayersLogs.getInstance();
|
||||
public AuthMe plugin;
|
||||
private DataSource database;
|
||||
private FileCache playerCache = new FileCache();
|
||||
|
||||
public UnregisterCommand(AuthMe plugin, DataSource database) {
|
||||
this.plugin = plugin;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command cmnd, String label, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!plugin.authmePermissible(sender, "authme." + label.toLowerCase())) {
|
||||
sender.sendMessage(m._("no_perm"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Player player = (Player) sender;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (!PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
player.sendMessage(m._("not_logged_in"));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length != 1) {
|
||||
player.sendMessage(m._("usage_unreg"));
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
if (PasswordSecurity.comparePasswordWithHash(args[0], PlayerCache.getInstance().getAuth(name).getHash(), name)) {
|
||||
if (!database.removeAuth(name)) {
|
||||
player.sendMessage("error");
|
||||
return true;
|
||||
}
|
||||
if(Settings.isForcedRegistrationEnabled) {
|
||||
player.getInventory().setArmorContents(new ItemStack[4]);
|
||||
player.getInventory().setContents(new ItemStack[36]);
|
||||
player.saveData();
|
||||
PlayerCache.getInstance().removePlayer(player.getName().toLowerCase());
|
||||
LimboCache.getInstance().addLimboPlayer(player);
|
||||
int delay = Settings.getRegistrationTimeout * 20;
|
||||
int interval = Settings.getWarnMessageInterval;
|
||||
BukkitScheduler sched = sender.getServer().getScheduler();
|
||||
if (delay != 0) {
|
||||
BukkitTask id = sched.runTaskLater(plugin, new TimeoutTask(plugin, name), delay);
|
||||
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id.getTaskId());
|
||||
}
|
||||
sched.scheduleSyncDelayedTask(plugin, new MessageTask(plugin, name, m._("reg_msg"), interval));
|
||||
if(!Settings.unRegisteredGroup.isEmpty()){
|
||||
Utils.getInstance().setGroup(player, Utils.groupType.UNREGISTERED);
|
||||
}
|
||||
player.sendMessage("unregistered");
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
if(plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " unregistered himself!"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if(!Settings.unRegisteredGroup.isEmpty()){
|
||||
Utils.getInstance().setGroup(player, Utils.groupType.UNREGISTERED);
|
||||
}
|
||||
PlayerCache.getInstance().removePlayer(player.getName().toLowerCase());
|
||||
// check if Player cache File Exist and delete it, preventing duplication of items
|
||||
if(playerCache.doesCacheExist(name)) {
|
||||
playerCache.removeCache(name);
|
||||
}
|
||||
if (PlayersLogs.players.contains(player.getName())) {
|
||||
PlayersLogs.players.remove(player.getName());
|
||||
pllog.save();
|
||||
}
|
||||
player.sendMessage("unregistered");
|
||||
ConsoleLogger.info(player.getDisplayName() + " unregistered himself");
|
||||
if(plugin.notifications != null) {
|
||||
plugin.notifications.showNotification(new Notification("[AuthMe] " + player.getName() + " unregistered himself!"));
|
||||
}
|
||||
if (Settings.isTeleportToSpawnEnabled) {
|
||||
Location spawn = plugin.getSpawnLocation(player.getWorld());
|
||||
SpawnTeleportEvent tpEvent = new SpawnTeleportEvent(player, player.getLocation(), spawn, false);
|
||||
plugin.getServer().getPluginManager().callEvent(tpEvent);
|
||||
if(!tpEvent.isCancelled()) {
|
||||
if (!tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).isLoaded()) {
|
||||
tpEvent.getTo().getWorld().getChunkAt(tpEvent.getTo()).load();
|
||||
}
|
||||
player.teleport(tpEvent.getTo());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
player.sendMessage(m._("wrong_pwd"));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
sender.sendMessage("Internal Error please read the server log");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class FlatToSql {
|
||||
|
||||
private static String tableName;
|
||||
private static String columnName;
|
||||
private static String columnPassword;
|
||||
private static String columnIp;
|
||||
private static String columnLastLogin;
|
||||
private static String lastlocX;
|
||||
private static String lastlocY;
|
||||
private static String lastlocZ;
|
||||
private static String lastlocWorld;
|
||||
private static String columnEmail;
|
||||
private static File source;
|
||||
private static File output;
|
||||
|
||||
public static void FlatToSqlConverter() throws IOException {
|
||||
tableName = Settings.getMySQLTablename;
|
||||
columnName = Settings.getMySQLColumnName;
|
||||
columnPassword = Settings.getMySQLColumnPassword;
|
||||
columnIp = Settings.getMySQLColumnIp;
|
||||
columnLastLogin = Settings.getMySQLColumnLastLogin;
|
||||
lastlocX = Settings.getMySQLlastlocX;
|
||||
lastlocY = Settings.getMySQLlastlocY;
|
||||
lastlocZ = Settings.getMySQLlastlocZ;
|
||||
lastlocWorld = Settings.getMySQLlastlocWorld;
|
||||
columnEmail = Settings.getMySQLColumnEmail;
|
||||
|
||||
try {
|
||||
source = new File(AuthMe.getInstance().getDataFolder() + File.separator + "auths.db");
|
||||
source.createNewFile();
|
||||
output = new File(AuthMe.getInstance().getDataFolder() + File.separator + "authme.sql");
|
||||
BufferedReader br = null;
|
||||
BufferedWriter sql = null;
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
sql = new BufferedWriter(new FileWriter(output));
|
||||
String createDB = " CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ "id INTEGER AUTO_INCREMENT,"
|
||||
+ columnName + " VARCHAR(255) NOT NULL UNIQUE,"
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL,"
|
||||
+ columnIp + " VARCHAR(40) NOT NULL,"
|
||||
+ columnLastLogin + " BIGINT,"
|
||||
+ lastlocX + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocY + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocZ + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocWorld + " VARCHAR(255) DEFAULT 'world',"
|
||||
+ columnEmail + " VARCHAR(255) NOT NULL,"
|
||||
+ "CONSTRAINT table_const_prim PRIMARY KEY (id));";
|
||||
sql.write(createDB);
|
||||
String line;
|
||||
int i = 1;
|
||||
String newline;
|
||||
while ((line = br.readLine()) != null) {
|
||||
sql.newLine();
|
||||
String[] args = line.split(":");
|
||||
if (args.length == 4)
|
||||
newline = "INSERT INTO " + tableName + " VALUES (" + i + ", '" + args[0] + "', '" + args[1] + "', '" + args[2] + "', " + args[3] + ", 0, 0, 0, 'world', 'your@email.com');";
|
||||
else if (args.length == 7)
|
||||
newline = "INSERT INTO " + tableName + " VALUES (" + i + ", '" + args[0] + "', '" + args[1] + "', '" + args[2] + "', " + args[3] + ", " + args[4] + ", " + args[5] + ", " + args[6] + ", 'world', 'your@email.com');";
|
||||
else if (args.length == 8)
|
||||
newline = "INSERT INTO " + tableName + " VALUES (" + i + ", '" + args[0] + "', '" + args[1] + "', '" + args[2] + "', " + args[3] + ", " + args[4] + ", " + args[5] + ", " + args[6] + ", '" + args[7] + "', 'your@email.com');";
|
||||
else
|
||||
newline = "";
|
||||
if (newline != "")
|
||||
sql.write(newline);
|
||||
i = i + 1;
|
||||
}
|
||||
sql.close();
|
||||
br.close();
|
||||
ConsoleLogger.info("The FlatFile has been converted to authme.sql file");
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class FlatToSqlite {
|
||||
|
||||
private static String tableName;
|
||||
private static String columnName;
|
||||
private static String columnPassword;
|
||||
private static String columnIp;
|
||||
private static String columnLastLogin;
|
||||
private static String lastlocX;
|
||||
private static String lastlocY;
|
||||
private static String lastlocZ;
|
||||
private static String lastlocWorld;
|
||||
private static String columnEmail;
|
||||
private static File source;
|
||||
private static String database;
|
||||
private static String columnID;
|
||||
private static Connection con;
|
||||
|
||||
public static String convert() throws IOException {
|
||||
database = Settings.getMySQLDatabase;
|
||||
tableName = Settings.getMySQLTablename;
|
||||
columnName = Settings.getMySQLColumnName;
|
||||
columnPassword = Settings.getMySQLColumnPassword;
|
||||
columnIp = Settings.getMySQLColumnIp;
|
||||
columnLastLogin = Settings.getMySQLColumnLastLogin;
|
||||
lastlocX = Settings.getMySQLlastlocX;
|
||||
lastlocY = Settings.getMySQLlastlocY;
|
||||
lastlocZ = Settings.getMySQLlastlocZ;
|
||||
lastlocWorld = Settings.getMySQLlastlocWorld;
|
||||
columnEmail = Settings.getMySQLColumnEmail;
|
||||
columnID = Settings.getMySQLColumnId;
|
||||
ConsoleLogger.info("Converting FlatFile to SQLite ...");
|
||||
if (new File(AuthMe.getInstance().getDataFolder() + File.separator + database + ".db").exists()) {
|
||||
return "The Database " + database + ".db can't be created cause the file already exist";
|
||||
}
|
||||
try {
|
||||
connect();
|
||||
setup();
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.showError("Problem while trying to convert to sqlite !");
|
||||
return "Problem while trying to convert to sqlite !";
|
||||
}
|
||||
try {
|
||||
source = new File(AuthMe.getInstance().getDataFolder() + File.separator + "auths.db");
|
||||
source.createNewFile();
|
||||
BufferedReader br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
int i = 1;
|
||||
String newline;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length == 4)
|
||||
newline = "INSERT INTO " + tableName + " VALUES (" + i + ", '" + args[0] + "', '" + args[1] + "', '" + args[2] + "', " + args[3] + ", 0, 0, 0, 'world', 'your@email.com');";
|
||||
else if (args.length == 7)
|
||||
newline = "INSERT INTO " + tableName + " VALUES (" + i + ", '" + args[0] + "', '" + args[1] + "', '" + args[2] + "', " + args[3] + ", " + args[4] + ", " + args[5] + ", " + args[6] + ", 'world', 'your@email.com');";
|
||||
else if (args.length == 8)
|
||||
newline = "INSERT INTO " + tableName + " VALUES (" + i + ", '" + args[0] + "', '" + args[1] + "', '" + args[2] + "', " + args[3] + ", " + args[4] + ", " + args[5] + ", " + args[6] + ", '" + args[7] + "', 'your@email.com');";
|
||||
else
|
||||
newline = "";
|
||||
if (newline != "")
|
||||
saveAuth(newline);
|
||||
i = i + 1;
|
||||
}
|
||||
br.close();
|
||||
ConsoleLogger.info("The FlatFile has been converted to " + database + ".db file");
|
||||
close();
|
||||
return ("The FlatFile has been converted to " + database + ".db file");
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
return "Errors appears while trying to convert to SQLite";
|
||||
}
|
||||
|
||||
private synchronized static void connect() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
ConsoleLogger.info("SQLite driver loaded");
|
||||
con = DriverManager.getConnection("jdbc:sqlite:plugins/AuthMe/"+database+".db");
|
||||
}
|
||||
|
||||
private synchronized static void setup() throws SQLException {
|
||||
Statement st = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
st = con.createStatement();
|
||||
st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ columnID + " INTEGER AUTO_INCREMENT,"
|
||||
+ columnName + " VARCHAR(255) NOT NULL UNIQUE,"
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL,"
|
||||
+ columnIp + " VARCHAR(40) NOT NULL,"
|
||||
+ columnLastLogin + " BIGINT,"
|
||||
+ lastlocX + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocY + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocZ + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocWorld + " VARCHAR(255) DEFAULT 'world',"
|
||||
+ columnEmail + " VARCHAR(255) DEFAULT 'your@email.com',"
|
||||
+ "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + "));");
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnPassword);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnIp);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnIp + " VARCHAR(40) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnLastLogin);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnLastLogin + " BIGINT;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocX);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocX + " smallint(6) NOT NULL DEFAULT '0'; "
|
||||
+ "ALTER TABLE " + tableName + " ADD COLUMN " + lastlocY + " smallint(6) NOT NULL DEFAULT '0'; "
|
||||
+ "ALTER TABLE " + tableName + " ADD COLUMN " + lastlocZ + " smallint(6) NOT NULL DEFAULT '0';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ + ";");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnEmail);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com';");
|
||||
}
|
||||
} finally {
|
||||
close(rs);
|
||||
close(st);
|
||||
}
|
||||
ConsoleLogger.info("SQLite Setup finished");
|
||||
}
|
||||
|
||||
private static synchronized boolean saveAuth(String s) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement(s);
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void close(Statement st) {
|
||||
if (st != null) {
|
||||
try {
|
||||
st.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void close(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
rs.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static void close() {
|
||||
try {
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class RakamakConverter {
|
||||
|
||||
public AuthMe instance;
|
||||
|
||||
public RakamakConverter (AuthMe instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public RakamakConverter getInstance() {
|
||||
return this;
|
||||
}
|
||||
|
||||
private static HashAlgorithm hash;
|
||||
private static Boolean useIP;
|
||||
private static String fileName;
|
||||
private static String ipFileName;
|
||||
private static File source;
|
||||
private static File output;
|
||||
private static File ipfiles;
|
||||
private static boolean alreadyExist = false;
|
||||
|
||||
public static void RakamakConvert() throws IOException {
|
||||
hash = Settings.rakamakHash;
|
||||
useIP = Settings.rakamakUseIp;
|
||||
fileName = Settings.rakamakUsers;
|
||||
ipFileName = Settings.rakamakUsersIp;
|
||||
HashMap<String, String> playerIP = new HashMap<String, String>();
|
||||
HashMap<String, String> playerPSW = new HashMap<String, String>();
|
||||
try {
|
||||
source = new File(AuthMe.getInstance().getDataFolder() + File.separator + fileName);
|
||||
ipfiles = new File(AuthMe.getInstance().getDataFolder() + File.separator + ipFileName);
|
||||
output = new File(AuthMe.getInstance().getDataFolder() + File.separator + "auths.db");
|
||||
source.createNewFile();
|
||||
ipfiles.createNewFile();
|
||||
if (new File(AuthMe.getInstance().getDataFolder() + File.separator + "auths.db").exists()) {
|
||||
alreadyExist = true;
|
||||
}
|
||||
output.createNewFile();
|
||||
BufferedReader users = null;
|
||||
BufferedWriter outputDB = null;
|
||||
BufferedReader ipFile = null;
|
||||
ipFile = new BufferedReader(new FileReader(ipfiles));
|
||||
String line;
|
||||
String newLine = null;
|
||||
if (useIP) {
|
||||
String tempLine;
|
||||
while ((tempLine = ipFile.readLine()) != null) {
|
||||
if (tempLine.contains("=")) {
|
||||
String[] args = tempLine.split("=");
|
||||
playerIP.put(args[0], args[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ipFile.close();
|
||||
users = new BufferedReader(new FileReader(source));
|
||||
while ((line = users.readLine()) != null) {
|
||||
if (line.contains("=")) {
|
||||
String[] arguments = line.split("=");
|
||||
try {
|
||||
playerPSW.put(arguments[0],PasswordSecurity.getHash(hash, arguments[1], arguments[0].toLowerCase()));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
users.close();
|
||||
outputDB = new BufferedWriter(new FileWriter(output));
|
||||
for (Entry<String, String> m : playerPSW.entrySet()) {
|
||||
if (useIP) {
|
||||
String player = m.getKey();
|
||||
String psw = playerPSW.get(player);
|
||||
String ip = playerIP.get(player);
|
||||
newLine = player + ":" + psw + ":" + ip + ":1325376060:0:0:0";
|
||||
} else {
|
||||
String player = m.getKey();
|
||||
String psw = playerPSW.get(player);
|
||||
String ip = "127.0.0.1";
|
||||
newLine = player + ":" + psw + ":" + ip + ":1325376060:0:0:0";
|
||||
}
|
||||
if (alreadyExist) outputDB.newLine();
|
||||
outputDB.write(newLine);
|
||||
System.out.println("Write line");
|
||||
outputDB.newLine();
|
||||
}
|
||||
outputDB.close();
|
||||
ConsoleLogger.info("Rakamak database has been converted to auths.db");
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import com.cypherx.xauth.xAuth;
|
||||
import com.cypherx.xauth.database.Table;
|
||||
import com.cypherx.xauth.utils.xAuthLog;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class xAuthToFlat {
|
||||
|
||||
public AuthMe instance;
|
||||
public DataSource database;
|
||||
|
||||
public xAuthToFlat(AuthMe instance, DataSource database) {
|
||||
this.instance = instance;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public boolean convert(CommandSender sender) {
|
||||
if (instance.getServer().getPluginManager().getPlugin("xAuth") == null) {
|
||||
sender.sendMessage("[AuthMe] xAuth plugin not found");
|
||||
return false;
|
||||
}
|
||||
if (!(new File("./plugins/xAuth/xAuth.h2.db").exists())) {
|
||||
sender.sendMessage("[AuthMe] xAuth H2 database not found, checking for MySQL or SQLite data...");
|
||||
}
|
||||
List<Integer> players = getXAuthPlayers();
|
||||
if (players == null || players.isEmpty()) {
|
||||
sender.sendMessage("[AuthMe] Error while import xAuthPlayers");
|
||||
return false;
|
||||
}
|
||||
sender.sendMessage("[AuthMe] Starting import...");
|
||||
for (int id : players) {
|
||||
String pl = getIdPlayer(id);
|
||||
String psw = getPassword(id);
|
||||
if (psw != null && !psw.isEmpty() && pl != null) {
|
||||
PlayerAuth auth = new PlayerAuth(pl, psw, "198.18.0.1", 0);
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
}
|
||||
sender.sendMessage("[AuthMe] Import done!");
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getIdPlayer(int id) {
|
||||
String realPass = "";
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `playername` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(Table.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, id);
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next())
|
||||
return null;
|
||||
realPass = rs.getString("playername").toLowerCase();
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve name for account: " + id, e);
|
||||
return null;
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return realPass;
|
||||
}
|
||||
|
||||
public List<Integer> getXAuthPlayers() {
|
||||
List<Integer> xP = new ArrayList<Integer>();
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT * FROM `%s`",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(Table.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
while(rs.next()) {
|
||||
xP.add(rs.getInt("id"));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Cannot import xAuthPlayers", e);
|
||||
return new ArrayList<Integer>();
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return xP;
|
||||
}
|
||||
|
||||
public String getPassword(int accountId) {
|
||||
String realPass = "";
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `password`, `pwtype` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(Table.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, accountId);
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next())
|
||||
return null;
|
||||
realPass = rs.getString("password");
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve password hash for account: " + accountId, e);
|
||||
return null;
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return realPass;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
|
||||
|
||||
public class CacheDataSource implements DataSource {
|
||||
|
||||
private DataSource source;
|
||||
public AuthMe plugin;
|
||||
private final HashMap<String, PlayerAuth> cache = new HashMap<String, PlayerAuth>();
|
||||
|
||||
public CacheDataSource(AuthMe plugin, DataSource source) {
|
||||
this.plugin = plugin;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
return cache.containsKey(user) ? true : source.isAuthAvailable(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
if(cache.containsKey(user)) {
|
||||
return cache.get(user);
|
||||
} else {
|
||||
PlayerAuth auth = source.getAuth(user);
|
||||
cache.put(user, auth);
|
||||
return auth;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
if (source.saveAuth(auth)) {
|
||||
cache.put(auth.getNickname(), auth);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
if (source.updatePassword(auth)) {
|
||||
cache.get(auth.getNickname()).setHash(auth.getHash());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSession(PlayerAuth auth) {
|
||||
if (source.updateSession(auth)) {
|
||||
cache.get(auth.getNickname()).setIp(auth.getIp());
|
||||
cache.get(auth.getNickname()).setLastLogin(auth.getLastLogin());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuitLoc(PlayerAuth auth) {
|
||||
if (source.updateQuitLoc(auth)) {
|
||||
cache.get(auth.getNickname()).setQuitLocX(auth.getQuitLocX());
|
||||
cache.get(auth.getNickname()).setQuitLocY(auth.getQuitLocY());
|
||||
cache.get(auth.getNickname()).setQuitLocZ(auth.getQuitLocZ());
|
||||
cache.get(auth.getNickname()).setWorld(auth.getWorld());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIps(String ip) {
|
||||
return source.getIps(ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int purgeDatabase(long until) {
|
||||
int cleared = source.purgeDatabase(until);
|
||||
if (cleared > 0) {
|
||||
for (PlayerAuth auth : cache.values()) {
|
||||
if(auth.getLastLogin() < until) {
|
||||
cache.remove(auth.getNickname());
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
List<String> cleared = source.autoPurgeDatabase(until);
|
||||
if (cleared.size() > 0) {
|
||||
for (PlayerAuth auth : cache.values()) {
|
||||
if(auth.getLastLogin() < until) {
|
||||
cache.remove(auth.getNickname());
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
if (source.removeAuth(user)) {
|
||||
cache.remove(user);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
source.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
cache.clear();
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
String user = player.getName().toLowerCase();
|
||||
if (PlayerCache.getInstance().isAuthenticated(user)) {
|
||||
try {
|
||||
PlayerAuth auth = source.getAuth(user);
|
||||
cache.put(user, auth);
|
||||
} catch (NullPointerException npe) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateEmail(PlayerAuth auth) {
|
||||
if(source.updateEmail(auth)) {
|
||||
cache.get(auth.getNickname()).setEmail(auth.getEmail());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateSalt(PlayerAuth auth) {
|
||||
if(source.updateSalt(auth)) {
|
||||
cache.get(auth.getNickname()).setSalt(auth.getSalt());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
return source.getAllAuthsByName(auth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByIp(String ip) {
|
||||
return source.getAllAuthsByIp(ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByEmail(String email) {
|
||||
return source.getAllAuthsByEmail(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void purgeBanned(List<String> banned) {
|
||||
source.purgeBanned(banned);
|
||||
for (PlayerAuth auth : cache.values()) {
|
||||
if (banned.contains(auth.getNickname())) {
|
||||
cache.remove(auth.getNickname());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
|
||||
|
||||
public interface DataSource {
|
||||
|
||||
public enum DataSourceType {
|
||||
|
||||
MYSQL, FILE, SQLITE
|
||||
}
|
||||
|
||||
boolean isAuthAvailable(String user);
|
||||
|
||||
PlayerAuth getAuth(String user);
|
||||
|
||||
boolean saveAuth(PlayerAuth auth);
|
||||
|
||||
boolean updateSession(PlayerAuth auth);
|
||||
|
||||
boolean updatePassword(PlayerAuth auth);
|
||||
|
||||
int purgeDatabase(long until);
|
||||
|
||||
List<String> autoPurgeDatabase(long until);
|
||||
|
||||
boolean removeAuth(String user);
|
||||
|
||||
boolean updateQuitLoc(PlayerAuth auth);
|
||||
|
||||
int getIps(String ip);
|
||||
|
||||
List<String> getAllAuthsByName(PlayerAuth auth);
|
||||
|
||||
List<String> getAllAuthsByIp(String ip);
|
||||
|
||||
List<String> getAllAuthsByEmail(String email);
|
||||
|
||||
boolean updateEmail(PlayerAuth auth);
|
||||
|
||||
boolean updateSalt(PlayerAuth auth);
|
||||
|
||||
void close();
|
||||
|
||||
void reload();
|
||||
|
||||
void purgeBanned(List<String> banned);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,566 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class FileDataSource implements DataSource {
|
||||
|
||||
/* file layout:
|
||||
*
|
||||
* PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS:LASTPOSX:LASTPOSY:LASTPOSZ:LASTPOSWORLD
|
||||
*
|
||||
* Old but compatible:
|
||||
* PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS
|
||||
* PLAYERNAME:HASHSUM:IP
|
||||
* PLAYERNAME:HASHSUM
|
||||
*
|
||||
*/
|
||||
private File source;
|
||||
|
||||
public FileDataSource() throws IOException {
|
||||
source = new File(Settings.AUTH_FILE);
|
||||
source.createNewFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 1 && args[0].equals(user)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
if (isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(source, true));
|
||||
bw.write(auth.getNickname() + ":" + auth.getHash() + ":" + auth.getIp() + ":" + auth.getLastLogin() + ":" + auth.getQuitLocX() + ":" + auth.getQuitLocY() + ":" + auth.getQuitLocZ() + ":" + auth.getWorld() + "\n");
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth newAuth = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
switch (args.length) {
|
||||
case 4: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], Long.parseLong(args[3]), 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), "world");
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), args[7]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], 0, 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAuth(auth.getNickname());
|
||||
saveAuth(newAuth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSession(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth newAuth = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
switch (args.length) {
|
||||
case 4: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), "world");
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), args[7]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAuth(auth.getNickname());
|
||||
saveAuth(newAuth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuitLoc(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth newAuth = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
newAuth = new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ(), auth.getWorld());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAuth(auth.getNickname());
|
||||
saveAuth(newAuth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIps(String ip) {
|
||||
BufferedReader br = null;
|
||||
int countIp = 0;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 3 && args[2].equals(ip)) {
|
||||
countIp++;
|
||||
}
|
||||
}
|
||||
return countIp;
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int purgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
int cleared = 0;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length >= 4) {
|
||||
if (Long.parseLong(args[3]) >= until) {
|
||||
lines.add(line);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cleared++;
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
List<String> cleared = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length >= 4) {
|
||||
if (Long.parseLong(args[3]) >= until) {
|
||||
lines.add(line);
|
||||
continue;
|
||||
} else {
|
||||
cleared.add(args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
if (!isAuthAvailable(user)) {
|
||||
return false;
|
||||
}
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 1 && !args[0].equals(user)) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(user)) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
return new PlayerAuth(args[0], args[1], "198.18.0.1", 0);
|
||||
case 3:
|
||||
return new PlayerAuth(args[0], args[1], args[2], 0);
|
||||
case 4:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]));
|
||||
case 7:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), "unavailableworld");
|
||||
case 8:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), args[7]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateEmail(PlayerAuth auth) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSalt(PlayerAuth auth) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
BufferedReader br = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 3 && args[2].equals(auth.getIp())) {
|
||||
countIp.add(args[0]);
|
||||
}
|
||||
}
|
||||
return countIp;
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByIp(String ip) {
|
||||
BufferedReader br = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 3 && args[2].equals(ip)) {
|
||||
countIp.add(args[0]);
|
||||
}
|
||||
}
|
||||
return countIp;
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByEmail(String email) {
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
try {
|
||||
if (banned.contains(args[0])) {
|
||||
lines.add(line);
|
||||
}
|
||||
} catch (NullPointerException npe) {}
|
||||
catch (ArrayIndexOutOfBoundsException aioobe) {}
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
// Copyright 2007-2013 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
|
||||
// www.source-code.biz, www.inventec.ch/chdh
|
||||
//
|
||||
// This module is multi-licensed and may be used under the terms
|
||||
// of any of the following licenses:
|
||||
//
|
||||
// EPL, Eclipse Public License, http://www.eclipse.org/legal
|
||||
// LGPL, GNU Lesser General Public License, http://www.gnu.org/licenses/lgpl.html
|
||||
// MPL, Mozilla Public License 1.1, http://www.mozilla.org/MPL
|
||||
//
|
||||
// Please contact the author if you need another license.
|
||||
// This module is provided "as is", without warranties of any kind.
|
||||
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.LinkedList;
|
||||
import javax.sql.ConnectionEvent;
|
||||
import javax.sql.ConnectionEventListener;
|
||||
import javax.sql.ConnectionPoolDataSource;
|
||||
import javax.sql.PooledConnection;
|
||||
|
||||
/**
|
||||
* A lightweight standalone JDBC connection pool manager.
|
||||
*
|
||||
* <p>The public methods of this class are thread-safe.
|
||||
*
|
||||
* <p>Home page: <a href="http://www.source-code.biz/miniconnectionpoolmanager">www.source-code.biz/miniconnectionpoolmanager</a><br>
|
||||
* Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>
|
||||
* Multi-licensed: EPL / LGPL / MPL.
|
||||
*/
|
||||
public class MiniConnectionPoolManager {
|
||||
|
||||
private ConnectionPoolDataSource dataSource;
|
||||
private int maxConnections;
|
||||
private long timeoutMs;
|
||||
private PrintWriter logWriter;
|
||||
private Semaphore semaphore;
|
||||
private PoolConnectionEventListener poolConnectionEventListener;
|
||||
|
||||
// The following variables must only be accessed within synchronized blocks.
|
||||
// @GuardedBy("this") could by used in the future.
|
||||
private LinkedList<PooledConnection> recycledConnections; // list of inactive PooledConnections
|
||||
private int activeConnections; // number of active (open) connections of this pool
|
||||
private boolean isDisposed; // true if this connection pool has been disposed
|
||||
private boolean doPurgeConnection; // flag to purge the connection currently beeing closed instead of recycling it
|
||||
private PooledConnection connectionInTransition; // a PooledConnection which is currently within a PooledConnection.getConnection() call, or null
|
||||
|
||||
/**
|
||||
* Thrown in {@link #getConnection()} or {@link #getValidConnection()} when no free connection becomes
|
||||
* available within <code>timeout</code> seconds.
|
||||
*/
|
||||
public static class TimeoutException extends RuntimeException {
|
||||
private static final long serialVersionUID = 1;
|
||||
public TimeoutException () {
|
||||
super("Timeout while waiting for a free database connection."); }
|
||||
public TimeoutException (String msg) {
|
||||
super(msg); }}
|
||||
|
||||
/**
|
||||
* Constructs a MiniConnectionPoolManager object with a timeout of 60 seconds.
|
||||
*
|
||||
* @param dataSource
|
||||
* the data source for the connections.
|
||||
* @param maxConnections
|
||||
* the maximum number of connections.
|
||||
*/
|
||||
public MiniConnectionPoolManager (ConnectionPoolDataSource dataSource, int maxConnections) {
|
||||
this(dataSource, maxConnections, 60); }
|
||||
|
||||
/**
|
||||
* Constructs a MiniConnectionPoolManager object.
|
||||
*
|
||||
* @param dataSource
|
||||
* the data source for the connections.
|
||||
* @param maxConnections
|
||||
* the maximum number of connections.
|
||||
* @param timeout
|
||||
* the maximum time in seconds to wait for a free connection.
|
||||
*/
|
||||
public MiniConnectionPoolManager (ConnectionPoolDataSource dataSource, int maxConnections, int timeout) {
|
||||
this.dataSource = dataSource;
|
||||
this.maxConnections = maxConnections;
|
||||
this.timeoutMs = timeout * 1000L;
|
||||
try {
|
||||
logWriter = dataSource.getLogWriter(); }
|
||||
catch (SQLException e) {}
|
||||
if (maxConnections < 1) {
|
||||
throw new IllegalArgumentException("Invalid maxConnections value."); }
|
||||
semaphore = new Semaphore(maxConnections,true);
|
||||
recycledConnections = new LinkedList<PooledConnection>();
|
||||
poolConnectionEventListener = new PoolConnectionEventListener(); }
|
||||
|
||||
/**
|
||||
* Closes all unused pooled connections.
|
||||
*/
|
||||
public synchronized void dispose() throws SQLException {
|
||||
if (isDisposed) {
|
||||
return; }
|
||||
isDisposed = true;
|
||||
SQLException e = null;
|
||||
while (!recycledConnections.isEmpty()) {
|
||||
PooledConnection pconn = recycledConnections.remove();
|
||||
try {
|
||||
pconn.close(); }
|
||||
catch (SQLException e2) {
|
||||
if (e == null) {
|
||||
e = e2; }}}
|
||||
if (e != null) {
|
||||
throw e; }}
|
||||
|
||||
/**
|
||||
* Retrieves a connection from the connection pool.
|
||||
*
|
||||
* <p>If <code>maxConnections</code> connections are already in use, the method
|
||||
* waits until a connection becomes available or <code>timeout</code> seconds elapsed.
|
||||
* When the application is finished using the connection, it must close it
|
||||
* in order to return it to the pool.
|
||||
*
|
||||
* @return
|
||||
* a new <code>Connection</code> object.
|
||||
* @throws TimeoutException
|
||||
* when no connection becomes available within <code>timeout</code> seconds.
|
||||
*/
|
||||
public Connection getConnection() throws SQLException {
|
||||
return getConnection2(timeoutMs); }
|
||||
|
||||
private Connection getConnection2 (long timeoutMs) throws SQLException {
|
||||
// This routine is unsynchronized, because semaphore.tryAcquire() may block.
|
||||
synchronized (this) {
|
||||
if (isDisposed) {
|
||||
throw new IllegalStateException("Connection pool has been disposed."); }}
|
||||
try {
|
||||
if (!semaphore.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
|
||||
throw new TimeoutException(); }}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException("Interrupted while waiting for a database connection.",e); }
|
||||
boolean ok = false;
|
||||
try {
|
||||
Connection conn = getConnection3();
|
||||
ok = true;
|
||||
return conn; }
|
||||
finally {
|
||||
if (!ok) {
|
||||
semaphore.release(); }}}
|
||||
|
||||
private synchronized Connection getConnection3() throws SQLException {
|
||||
if (isDisposed) {
|
||||
throw new IllegalStateException("Connection pool has been disposed."); }
|
||||
PooledConnection pconn;
|
||||
if (!recycledConnections.isEmpty()) {
|
||||
pconn = recycledConnections.remove(); }
|
||||
else {
|
||||
pconn = dataSource.getPooledConnection();
|
||||
pconn.addConnectionEventListener(poolConnectionEventListener); }
|
||||
Connection conn;
|
||||
try {
|
||||
// The JDBC driver may call ConnectionEventListener.connectionErrorOccurred()
|
||||
// from within PooledConnection.getConnection(). To detect this within
|
||||
// disposeConnection(), we temporarily set connectionInTransition.
|
||||
connectionInTransition = pconn;
|
||||
activeConnections++;
|
||||
conn = pconn.getConnection(); }
|
||||
finally {
|
||||
connectionInTransition = null; }
|
||||
assertInnerState();
|
||||
return conn; }
|
||||
|
||||
/**
|
||||
* Retrieves a connection from the connection pool and ensures that it is valid
|
||||
* by calling {@link Connection#isValid(int)}.
|
||||
*
|
||||
* <p>If a connection is not valid, the method tries to get another connection
|
||||
* until one is valid (or a timeout occurs).
|
||||
*
|
||||
* <p>Pooled connections may become invalid when e.g. the database server is
|
||||
* restarted.
|
||||
*
|
||||
* <p>This method is slower than {@link #getConnection()} because the JDBC
|
||||
* driver has to send an extra command to the database server to test the connection.
|
||||
*
|
||||
* <p>This method requires Java 1.6 or newer.
|
||||
*
|
||||
* @throws TimeoutException
|
||||
* when no valid connection becomes available within <code>timeout</code> seconds.
|
||||
*/
|
||||
public Connection getValidConnection() {
|
||||
long time = System.currentTimeMillis();
|
||||
long timeoutTime = time + timeoutMs;
|
||||
int triesWithoutDelay = getInactiveConnections() + 1;
|
||||
while (true) {
|
||||
Connection conn = getValidConnection2(time, timeoutTime);
|
||||
if (conn != null) {
|
||||
return conn; }
|
||||
triesWithoutDelay--;
|
||||
if (triesWithoutDelay <= 0) {
|
||||
triesWithoutDelay = 0;
|
||||
try {
|
||||
Thread.sleep(250); }
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException("Interrupted while waiting for a valid database connection.", e); }}
|
||||
time = System.currentTimeMillis();
|
||||
if (time >= timeoutTime) {
|
||||
throw new TimeoutException("Timeout while waiting for a valid database connection."); }}}
|
||||
|
||||
private Connection getValidConnection2 (long time, long timeoutTime) {
|
||||
long rtime = Math.max(1, timeoutTime - time);
|
||||
Connection conn;
|
||||
try {
|
||||
conn = getConnection2(rtime); }
|
||||
catch (SQLException e) {
|
||||
return null; }
|
||||
rtime = timeoutTime - System.currentTimeMillis();
|
||||
int rtimeSecs = Math.max(1, (int)((rtime+999)/1000));
|
||||
try {
|
||||
if (conn.isValid(rtimeSecs)) {
|
||||
return conn; }}
|
||||
catch (SQLException e) {}
|
||||
// This Exception should never occur. If it nevertheless occurs, it's because of an error in the
|
||||
// JDBC driver which we ignore and assume that the connection is not valid.
|
||||
// When isValid() returns false, the JDBC driver should have already called connectionErrorOccurred()
|
||||
// and the PooledConnection has been removed from the pool, i.e. the PooledConnection will
|
||||
// not be added to recycledConnections when Connection.close() is called.
|
||||
// But to be sure that this works even with a faulty JDBC driver, we call purgeConnection().
|
||||
purgeConnection(conn);
|
||||
return null; }
|
||||
|
||||
// Purges the PooledConnection associated with the passed Connection from the connection pool.
|
||||
private synchronized void purgeConnection (Connection conn) {
|
||||
try {
|
||||
doPurgeConnection = true;
|
||||
// (A potential problem of this program logic is that setting the doPurgeConnection flag
|
||||
// has an effect only if the JDBC driver calls connectionClosed() synchronously within
|
||||
// Connection.close().)
|
||||
conn.close(); }
|
||||
catch (SQLException e) {}
|
||||
// ignore exception from close()
|
||||
finally {
|
||||
doPurgeConnection = false; }}
|
||||
|
||||
private synchronized void recycleConnection (PooledConnection pconn) {
|
||||
if (isDisposed || doPurgeConnection) {
|
||||
disposeConnection(pconn);
|
||||
return; }
|
||||
if (activeConnections <= 0) {
|
||||
throw new AssertionError("AuthMeDatabaseError"); }
|
||||
activeConnections--;
|
||||
semaphore.release();
|
||||
recycledConnections.add(pconn);
|
||||
assertInnerState(); }
|
||||
|
||||
private synchronized void disposeConnection (PooledConnection pconn) {
|
||||
pconn.removeConnectionEventListener(poolConnectionEventListener);
|
||||
if (!recycledConnections.remove(pconn) && pconn != connectionInTransition) {
|
||||
// If the PooledConnection is not in the recycledConnections list
|
||||
// and is not currently within a PooledConnection.getConnection() call,
|
||||
// we assume that the connection was active.
|
||||
if (activeConnections <= 0) {
|
||||
throw new AssertionError("AuthMeDatabaseError"); }
|
||||
activeConnections--;
|
||||
semaphore.release(); }
|
||||
closeConnectionAndIgnoreException(pconn);
|
||||
assertInnerState(); }
|
||||
|
||||
private void closeConnectionAndIgnoreException (PooledConnection pconn) {
|
||||
try {
|
||||
pconn.close(); }
|
||||
catch (SQLException e) {
|
||||
log("Error while closing database connection: "+e.toString()); }}
|
||||
|
||||
private void log (String msg) {
|
||||
String s = "MiniConnectionPoolManager: "+msg;
|
||||
try {
|
||||
if (logWriter == null) {
|
||||
System.err.println(s); }
|
||||
else {
|
||||
logWriter.println(s); }}
|
||||
catch (Exception e) {}}
|
||||
|
||||
private synchronized void assertInnerState() {
|
||||
if (activeConnections < 0) {
|
||||
throw new AssertionError("AuthMeDatabaseError"); }
|
||||
if (activeConnections + recycledConnections.size() > maxConnections) {
|
||||
throw new AssertionError("AuthMeDatabaseError"); }
|
||||
if (activeConnections + semaphore.availablePermits() > maxConnections) {
|
||||
throw new AssertionError("AuthMeDatabaseError"); }}
|
||||
|
||||
private class PoolConnectionEventListener implements ConnectionEventListener {
|
||||
public void connectionClosed (ConnectionEvent event) {
|
||||
PooledConnection pconn = (PooledConnection)event.getSource();
|
||||
recycleConnection(pconn); }
|
||||
public void connectionErrorOccurred (ConnectionEvent event) {
|
||||
PooledConnection pconn = (PooledConnection)event.getSource();
|
||||
disposeConnection(pconn); }}
|
||||
|
||||
/**
|
||||
* Returns the number of active (open) connections of this pool.
|
||||
*
|
||||
* <p>This is the number of <code>Connection</code> objects that have been
|
||||
* issued by {@link #getConnection()}, for which <code>Connection.close()</code>
|
||||
* has not yet been called.
|
||||
*
|
||||
* @return
|
||||
* the number of active connections.
|
||||
**/
|
||||
public synchronized int getActiveConnections() {
|
||||
return activeConnections; }
|
||||
|
||||
/**
|
||||
* Returns the number of inactive (unused) connections in this pool.
|
||||
*
|
||||
* <p>This is the number of internally kept recycled connections,
|
||||
* for which <code>Connection.close()</code> has been called and which
|
||||
* have not yet been reused.
|
||||
*
|
||||
* @return
|
||||
* the number of inactive connections.
|
||||
**/
|
||||
public synchronized int getInactiveConnections() {
|
||||
return recycledConnections.size(); }
|
||||
|
||||
} // end class MiniConnectionPoolManager
|
||||
@@ -0,0 +1,770 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.MiniConnectionPoolManager.TimeoutException;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class MySQLDataSource implements DataSource {
|
||||
|
||||
private String host;
|
||||
private String port;
|
||||
private String username;
|
||||
private String password;
|
||||
private String database;
|
||||
private String tableName;
|
||||
private String columnName;
|
||||
private String columnPassword;
|
||||
private String columnIp;
|
||||
private String columnLastLogin;
|
||||
private String columnSalt;
|
||||
private String columnGroup;
|
||||
private String lastlocX;
|
||||
private String lastlocY;
|
||||
private String lastlocZ;
|
||||
private String lastlocWorld;
|
||||
private String columnEmail;
|
||||
private String columnID;
|
||||
private List<String> columnOthers;
|
||||
private MiniConnectionPoolManager conPool;
|
||||
|
||||
public MySQLDataSource() throws ClassNotFoundException, SQLException {
|
||||
this.host = Settings.getMySQLHost;
|
||||
this.port = Settings.getMySQLPort;
|
||||
this.username = Settings.getMySQLUsername;
|
||||
this.password = Settings.getMySQLPassword;
|
||||
this.database = Settings.getMySQLDatabase;
|
||||
this.tableName = Settings.getMySQLTablename;
|
||||
this.columnName = Settings.getMySQLColumnName;
|
||||
this.columnPassword = Settings.getMySQLColumnPassword;
|
||||
this.columnIp = Settings.getMySQLColumnIp;
|
||||
this.columnLastLogin = Settings.getMySQLColumnLastLogin;
|
||||
this.lastlocX = Settings.getMySQLlastlocX;
|
||||
this.lastlocY = Settings.getMySQLlastlocY;
|
||||
this.lastlocZ = Settings.getMySQLlastlocZ;
|
||||
this.lastlocWorld = Settings.getMySQLlastlocWorld;
|
||||
this.columnSalt = Settings.getMySQLColumnSalt;
|
||||
this.columnGroup = Settings.getMySQLColumnGroup;
|
||||
this.columnEmail = Settings.getMySQLColumnEmail;
|
||||
this.columnOthers = Settings.getMySQLOtherUsernameColumn;
|
||||
this.columnID = Settings.getMySQLColumnId;
|
||||
|
||||
connect();
|
||||
setup();
|
||||
}
|
||||
|
||||
private synchronized void connect() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
ConsoleLogger.info("MySQL driver loaded");
|
||||
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
|
||||
dataSource.setDatabaseName(database);
|
||||
dataSource.setServerName(host);
|
||||
dataSource.setPort(Integer.parseInt(port));
|
||||
dataSource.setUser(username);
|
||||
dataSource.setPassword(password);
|
||||
conPool = new MiniConnectionPoolManager(dataSource, 20);
|
||||
ConsoleLogger.info("Connection pool ready");
|
||||
}
|
||||
|
||||
private synchronized void setup() throws SQLException {
|
||||
Connection con = null;
|
||||
Statement st = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
st = con.createStatement();
|
||||
st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ columnID + " INTEGER AUTO_INCREMENT,"
|
||||
+ columnName + " VARCHAR(255) NOT NULL UNIQUE,"
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL,"
|
||||
+ columnIp + " VARCHAR(40) NOT NULL,"
|
||||
+ columnLastLogin + " BIGINT,"
|
||||
+ lastlocX + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocY + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocZ + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocWorld + " VARCHAR(255) DEFAULT 'world',"
|
||||
+ columnEmail + " VARCHAR(255) DEFAULT 'your@email.com',"
|
||||
+ "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + "));");
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnPassword);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnIp);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnIp + " VARCHAR(40) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnLastLogin);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnLastLogin + " BIGINT;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocX);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocX + " smallint(6) NOT NULL DEFAULT '0' AFTER "
|
||||
+ columnLastLogin +" , ADD " + lastlocY + " smallint(6) NOT NULL DEFAULT '0' AFTER " + lastlocX + " , ADD " + lastlocZ + " smallint(6) NOT NULL DEFAULT '0' AFTER " + lastlocY + ";");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ + ";");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnEmail);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com' AFTER " + lastlocZ +";");
|
||||
}
|
||||
} finally {
|
||||
close(rs);
|
||||
close(st);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnName + "=?;");
|
||||
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnName + "=?;");
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
if (rs.getString(columnIp).isEmpty() ) {
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), "198.18.0.1", rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld),rs.getString(columnEmail));
|
||||
} else {
|
||||
if(!columnSalt.isEmpty()){
|
||||
if(!columnGroup.isEmpty())
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword),rs.getString(columnSalt), rs.getInt(columnGroup), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail));
|
||||
else return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword),rs.getString(columnSalt), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld),rs.getString(columnEmail));
|
||||
} else {
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
if ((columnSalt.isEmpty() || columnSalt == null) && (auth.getSalt().isEmpty() || auth.getSalt() == null)) {
|
||||
pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + ") VALUES (?,?,?,?);");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getHash());
|
||||
pst.setString(3, auth.getIp());
|
||||
pst.setLong(4, auth.getLastLogin());
|
||||
pst.executeUpdate();
|
||||
} else {
|
||||
pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + "," + columnSalt + ") VALUES (?,?,?,?,?);");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getHash());
|
||||
pst.setString(3, auth.getIp());
|
||||
pst.setLong(4, auth.getLastLogin());
|
||||
pst.setString(5, auth.getSalt());
|
||||
pst.executeUpdate();
|
||||
}
|
||||
if (!columnOthers.isEmpty()) {
|
||||
for(String column : columnOthers) {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + tableName + "." + column + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
}
|
||||
}
|
||||
if (Settings.getPasswordHash == HashAlgorithm.PHPBB) {
|
||||
int id;
|
||||
ResultSet rs = null;
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
id = rs.getInt(columnID);
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getPhpbbPrefix + "user_group (group_id, user_id, group_leader, user_pending) VALUES (?,?,?,?);");
|
||||
pst.setInt(1, Settings.getPhpbbGroup);
|
||||
pst.setInt(2, id);
|
||||
pst.setInt(3, 0);
|
||||
pst.setInt(4, 0);
|
||||
pst.executeUpdate();
|
||||
}
|
||||
}
|
||||
if (Settings.getPasswordHash == HashAlgorithm.WORDPRESS) {
|
||||
int id;
|
||||
ResultSet rs = null;
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
id = rs.getInt(columnID);
|
||||
// First Name
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "first_name");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
// Last Name
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "last_name");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
// Nick Name
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "nickname");
|
||||
pst.setString(3, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
// Description
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "description");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
// Rich_Editing
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "rich_editing");
|
||||
pst.setString(3, "true");
|
||||
pst.executeUpdate();
|
||||
// Comments_Shortcuts
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "comment_shortcuts");
|
||||
pst.setString(3, "false");
|
||||
pst.executeUpdate();
|
||||
// admin_color
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "admin_color");
|
||||
pst.setString(3, "fresh");
|
||||
pst.executeUpdate();
|
||||
// use_ssl
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "use_ssl");
|
||||
pst.setString(3, "0");
|
||||
pst.executeUpdate();
|
||||
// show_admin_bar_front
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "show_admin_bar_front");
|
||||
pst.setString(3, "true");
|
||||
pst.executeUpdate();
|
||||
// wp_capabilities
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "wp_capabilities");
|
||||
pst.setString(3, "a:1:{s:10:\"subscriber\";b:1;}");
|
||||
pst.executeUpdate();
|
||||
// wp_user_level
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "wp_user_level");
|
||||
pst.setString(3, "0");
|
||||
pst.executeUpdate();
|
||||
// default_password_nag
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "default_password_nag");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnPassword + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getHash());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateSession(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnIp + "=?, " + columnLastLogin + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getIp());
|
||||
pst.setLong(2, auth.getLastLogin());
|
||||
pst.setString(3, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int purgeDatabase(long until) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnLastLogin + "<?;");
|
||||
pst.setLong(1, until);
|
||||
return pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> autoPurgeDatabase(long until) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> list = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLastLogin + "<?;");
|
||||
pst.setLong(1, until);
|
||||
rs = pst.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(rs.getString(columnName));
|
||||
}
|
||||
return list;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, user);
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateQuitLoc(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET "+ lastlocX + " =?, "+ lastlocY +"=?, "+ lastlocZ +"=?, " + lastlocWorld + "=? WHERE " + columnName + "=?;");
|
||||
pst.setLong(1, auth.getQuitLocX());
|
||||
pst.setLong(2, auth.getQuitLocY());
|
||||
pst.setLong(3, auth.getQuitLocZ());
|
||||
pst.setString(4, auth.getWorld());
|
||||
pst.setString(5, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getIps(String ip) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
int countIp=0;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, ip);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp++;
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateEmail(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET "+ columnEmail + " =? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getEmail());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateSalt(PlayerAuth auth) {
|
||||
if (columnSalt.isEmpty() || auth.getSalt() == null || auth.getSalt().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET "+ columnSalt + " =? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getSalt());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
try {
|
||||
conPool.dispose();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
private void close(Statement st) {
|
||||
if (st != null) {
|
||||
try {
|
||||
st.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
rs.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(Connection con) {
|
||||
if (con != null) {
|
||||
try {
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, auth.getIp());
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp.add(rs.getString(columnName));
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByIp(String ip) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, ip);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp.add(rs.getString(columnName));
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByEmail(String email) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countEmail = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnEmail + "=?;");
|
||||
pst.setString(1, email);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countEmail.add(rs.getString(columnName));
|
||||
}
|
||||
return countEmail;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void purgeBanned(List<String> banned) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
for (String name : banned) {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, name);
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Connection makeSureConnectionIsReady() {
|
||||
Connection con = null;
|
||||
try {
|
||||
con = conPool.getValidConnection();
|
||||
} catch (Exception te) {
|
||||
try {
|
||||
con = null;
|
||||
reconnect();
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
}
|
||||
} catch (AssertionError ae) {
|
||||
// Make sure assertionerror is caused by the connectionpoolmanager, else re-throw it
|
||||
if (!ae.getMessage().equalsIgnoreCase("AuthMeDatabaseError"))
|
||||
throw new AssertionError(ae.getMessage());
|
||||
try {
|
||||
con = null;
|
||||
reconnect();
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
}
|
||||
}
|
||||
if (con == null)
|
||||
con = conPool.getValidConnection();
|
||||
return con;
|
||||
}
|
||||
|
||||
private synchronized void reconnect() throws ClassNotFoundException, SQLException, TimeoutException {
|
||||
conPool.dispose();
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
|
||||
dataSource.setDatabaseName(database);
|
||||
dataSource.setServerName(host);
|
||||
dataSource.setPort(Integer.parseInt(port));
|
||||
dataSource.setUser(username);
|
||||
dataSource.setPassword(password);
|
||||
conPool = new MiniConnectionPoolManager(dataSource, 10);
|
||||
ConsoleLogger.info("ConnectionPool was unavailable... Reconnected!");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.sqlite.*;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.MiniConnectionPoolManager.TimeoutException;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author stefano
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SqliteDataSource implements DataSource {
|
||||
|
||||
private String database;
|
||||
private String tableName;
|
||||
private String columnName;
|
||||
private String columnPassword;
|
||||
private String columnIp;
|
||||
private String columnLastLogin;
|
||||
private String columnSalt;
|
||||
private String columnGroup;
|
||||
private String lastlocX;
|
||||
private String lastlocY;
|
||||
private String lastlocZ;
|
||||
private String lastlocWorld;
|
||||
private String columnEmail;
|
||||
private String columnID;
|
||||
private Connection con;
|
||||
|
||||
public SqliteDataSource() throws ClassNotFoundException, SQLException {
|
||||
this.database = Settings.getMySQLDatabase;
|
||||
this.tableName = Settings.getMySQLTablename;
|
||||
this.columnName = Settings.getMySQLColumnName;
|
||||
this.columnPassword = Settings.getMySQLColumnPassword;
|
||||
this.columnIp = Settings.getMySQLColumnIp;
|
||||
this.columnLastLogin = Settings.getMySQLColumnLastLogin;
|
||||
this.columnSalt = Settings.getMySQLColumnSalt;
|
||||
this.columnGroup = Settings.getMySQLColumnGroup;
|
||||
this.lastlocX = Settings.getMySQLlastlocX;
|
||||
this.lastlocY = Settings.getMySQLlastlocY;
|
||||
this.lastlocZ = Settings.getMySQLlastlocZ;
|
||||
this.lastlocWorld = Settings.getMySQLlastlocWorld;
|
||||
this.columnEmail = Settings.getMySQLColumnEmail;
|
||||
this.columnID = Settings.getMySQLColumnId;
|
||||
|
||||
connect();
|
||||
setup();
|
||||
}
|
||||
|
||||
private synchronized void connect() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
ConsoleLogger.info("SQLite driver loaded");
|
||||
this.con = DriverManager.getConnection("jdbc:sqlite:plugins/AuthMe/"+database+".db");
|
||||
}
|
||||
|
||||
private synchronized void setup() throws SQLException {
|
||||
Statement st = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
st = con.createStatement();
|
||||
st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ columnID + " INTEGER AUTO_INCREMENT,"
|
||||
+ columnName + " VARCHAR(255) NOT NULL UNIQUE,"
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL,"
|
||||
+ columnIp + " VARCHAR(40) NOT NULL,"
|
||||
+ columnLastLogin + " BIGINT,"
|
||||
+ lastlocX + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocY + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocZ + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocWorld + " VARCHAR(255) DEFAULT 'world',"
|
||||
+ columnEmail + " VARCHAR(255) DEFAULT 'your@email.com',"
|
||||
+ "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + "));");
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnPassword);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnIp);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnIp + " VARCHAR(40) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnLastLogin);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnLastLogin + " BIGINT;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocX);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocX + " smallint(6) NOT NULL DEFAULT '0'; "
|
||||
+ "ALTER TABLE " + tableName + " ADD COLUMN " + lastlocY + " smallint(6) NOT NULL DEFAULT '0'; "
|
||||
+ "ALTER TABLE " + tableName + " ADD COLUMN " + lastlocZ + " smallint(6) NOT NULL DEFAULT '0';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnEmail);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com';");
|
||||
}
|
||||
} finally {
|
||||
close(rs);
|
||||
close(st);
|
||||
}
|
||||
ConsoleLogger.info("SQLite Setup finished");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?");
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnName + "=?;");
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
if (rs.getString(columnIp).isEmpty() ) {
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), "198.18.0.1", rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld) , rs.getString(columnEmail));
|
||||
} else {
|
||||
if(!columnSalt.isEmpty()){
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword),rs.getString(columnSalt), rs.getInt(columnGroup), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld) , rs.getString(columnEmail));
|
||||
} else {
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld) , rs.getString(columnEmail));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
if (columnSalt.isEmpty() && auth.getSalt().isEmpty()) {
|
||||
pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + ") VALUES (?,?,?,?);");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getHash());
|
||||
pst.setString(3, auth.getIp());
|
||||
pst.setLong(4, auth.getLastLogin());
|
||||
pst.executeUpdate();
|
||||
} else {
|
||||
pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + "," + columnSalt + ") VALUES (?,?,?,?,?);");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getHash());
|
||||
pst.setString(3, auth.getIp());
|
||||
pst.setLong(4, auth.getLastLogin());
|
||||
pst.setString(5, auth.getSalt());
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnPassword + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getHash());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSession(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnIp + "=?, " + columnLastLogin + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getIp());
|
||||
pst.setLong(2, auth.getLastLogin());
|
||||
pst.setString(3, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int purgeDatabase(long until) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnLastLogin + "<?;");
|
||||
pst.setLong(1, until);
|
||||
return pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> list = new ArrayList<String>();
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLastLogin + "<?;");
|
||||
pst.setLong(1, until);
|
||||
rs = pst.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(rs.getString(columnName));
|
||||
}
|
||||
return list;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, user);
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuitLoc(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + lastlocX + "=?, "+ lastlocY +"=?, "+ lastlocZ +"=?, " + lastlocWorld + "=? WHERE " + columnName + "=?;");
|
||||
pst.setLong(1, auth.getQuitLocX());
|
||||
pst.setLong(2, auth.getQuitLocY());
|
||||
pst.setLong(3, auth.getQuitLocZ());
|
||||
pst.setString(4, auth.getWorld());
|
||||
pst.setString(5, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIps(String ip) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
int countIp=0;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, ip);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp++;
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateEmail(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnEmail + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getEmail());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSalt(PlayerAuth auth) {
|
||||
if(columnSalt.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnSalt + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getSalt());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
try {
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
private void close(Statement st) {
|
||||
if (st != null) {
|
||||
try {
|
||||
st.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
rs.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(Connection con) {
|
||||
if (con != null) {
|
||||
try {
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, auth.getIp());
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp.add(rs.getString(columnName));
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (NullPointerException npe) {
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByIp(String ip) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, ip);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp.add(rs.getString(columnName));
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (NullPointerException npe) {
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByEmail(String email) {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countEmail = new ArrayList<String>();
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnEmail + "=?;");
|
||||
pst.setString(1, email);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countEmail.add(rs.getString(columnName));
|
||||
}
|
||||
return countEmail;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (NullPointerException npe) {
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
for (String name : banned) {
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, name);
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
} finally {
|
||||
close(pst);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class AuthMeTeleportEvent extends CustomEvent {
|
||||
|
||||
private Player player;
|
||||
private Location to;
|
||||
private Location from;
|
||||
|
||||
public AuthMeTeleportEvent(Player player, Location to) {
|
||||
this.player = player;
|
||||
this.from = player.getLocation();
|
||||
this.to = to;
|
||||
}
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class CustomEvent extends Event implements Cancellable {
|
||||
|
||||
private boolean isCancelled;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private static Server s;
|
||||
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return this.isCancelled;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled) {
|
||||
this.isCancelled = cancelled;
|
||||
}
|
||||
|
||||
public static Server getServer() {
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class LoginEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private boolean isLogin;
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
public LoginEvent(Player player, boolean isLogin) {
|
||||
this.player = player;
|
||||
this.isLogin = isLogin;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setLogin(boolean isLogin) {
|
||||
this.isLogin = isLogin;
|
||||
}
|
||||
|
||||
public boolean isLogin() {
|
||||
return isLogin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
|
||||
/**
|
||||
* <p>This event is called when we need to compare or get an hash password,
|
||||
* for set a custom EncryptionMethod</p>
|
||||
*
|
||||
* @see fr.xephi.authme.security.crypts.EncryptionMethod
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class PasswordEncryptionEvent extends Event {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private EncryptionMethod method = null;
|
||||
private String playerName = "";
|
||||
|
||||
public PasswordEncryptionEvent(EncryptionMethod method, String playerName) {
|
||||
this.method = method;
|
||||
this.playerName = playerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public void setMethod(EncryptionMethod method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public EncryptionMethod getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class ProtectInventoryEvent extends CustomEvent {
|
||||
|
||||
private ItemStack[] storedinventory;
|
||||
private ItemStack[] storedarmor;
|
||||
private ItemStack[] emptyInventory = null;
|
||||
private ItemStack[] emptyArmor = null;
|
||||
private Player player;
|
||||
|
||||
public ProtectInventoryEvent(Player player, ItemStack[] storedinventory, ItemStack[] storedarmor) {
|
||||
this.player = player;
|
||||
this.storedinventory = storedinventory;
|
||||
this.storedarmor = storedarmor;
|
||||
this.emptyInventory = new ItemStack[36];
|
||||
this.emptyArmor = new ItemStack[4];
|
||||
}
|
||||
|
||||
public ItemStack[] getStoredInventory() {
|
||||
return this.storedinventory;
|
||||
}
|
||||
|
||||
public ItemStack[] getStoredArmor() {
|
||||
return this.storedarmor;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setNewInventory(ItemStack[] emptyInventory) {
|
||||
this.emptyInventory = emptyInventory;
|
||||
}
|
||||
|
||||
public ItemStack[] getEmptyInventory() {
|
||||
return this.emptyInventory;
|
||||
}
|
||||
|
||||
public void setNewArmor(ItemStack[] emptyArmor) {
|
||||
this.emptyArmor = emptyArmor;
|
||||
}
|
||||
|
||||
public ItemStack[] getEmptyArmor() {
|
||||
return this.emptyArmor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class RegisterTeleportEvent extends CustomEvent {
|
||||
|
||||
private Player player;
|
||||
private Location to;
|
||||
private Location from;
|
||||
|
||||
public RegisterTeleportEvent(Player player, Location to) {
|
||||
this.player = player;
|
||||
this.from = player.getLocation();
|
||||
this.to = to;
|
||||
}
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class ResetInventoryEvent extends CustomEvent {
|
||||
|
||||
private Player player;
|
||||
|
||||
public ResetInventoryEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class RestoreInventoryEvent extends CustomEvent {
|
||||
|
||||
private ItemStack[] inventory;
|
||||
private ItemStack[] armor;
|
||||
private Player player;
|
||||
|
||||
public RestoreInventoryEvent(Player player, ItemStack[] inventory, ItemStack[] armor) {
|
||||
this.player = player;
|
||||
this.inventory = inventory;
|
||||
this.armor = armor;
|
||||
}
|
||||
|
||||
public ItemStack[] getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
public void setInventory(ItemStack[] inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
public ItemStack[] getArmor() {
|
||||
return this.armor;
|
||||
}
|
||||
|
||||
public void setArmor(ItemStack[] armor) {
|
||||
this.armor = armor;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class SessionEvent extends CustomEvent {
|
||||
|
||||
private PlayerAuth player;
|
||||
private boolean isLogin;
|
||||
|
||||
public SessionEvent(PlayerAuth auth, boolean isLogin) {
|
||||
this.player = auth;
|
||||
this.isLogin = isLogin;
|
||||
}
|
||||
|
||||
public PlayerAuth getPlayerAuth() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setPlayer(PlayerAuth player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public boolean isLogin() {
|
||||
return isLogin;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class SpawnTeleportEvent extends CustomEvent {
|
||||
|
||||
private Player player;
|
||||
private Location to;
|
||||
private Location from;
|
||||
private boolean isAuthenticated;
|
||||
|
||||
public SpawnTeleportEvent(Player player, Location from, Location to, boolean isAuthenticated) {
|
||||
this.player = player;
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.isAuthenticated = isAuthenticated;
|
||||
}
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
public void setTo(Location to) {
|
||||
this.to = to;
|
||||
}
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
public Location getFrom() {
|
||||
return from;
|
||||
}
|
||||
public boolean isAuthenticated() {
|
||||
return isAuthenticated;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package fr.xephi.authme.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class StoreInventoryEvent extends CustomEvent {
|
||||
|
||||
private ItemStack[] inventory;
|
||||
private ItemStack[] armor;
|
||||
private Player player;
|
||||
|
||||
public StoreInventoryEvent(Player player) {
|
||||
this.player = player;
|
||||
this.inventory = player.getInventory().getContents();
|
||||
this.armor = player.getInventory().getArmorContents();
|
||||
}
|
||||
|
||||
public StoreInventoryEvent(Player player, FileCache fileCache) {
|
||||
this.player = player;
|
||||
this.inventory = fileCache.readCache(player.getName().toLowerCase()).getInventory();
|
||||
this.armor = fileCache.readCache(player.getName().toLowerCase()).getArmour();
|
||||
}
|
||||
|
||||
public ItemStack[] getInventory() {
|
||||
return this.inventory;
|
||||
}
|
||||
|
||||
public void setInventory(ItemStack[] inventory) {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
public ItemStack[] getArmor() {
|
||||
return this.armor;
|
||||
}
|
||||
|
||||
public void setArmor(ItemStack[] armor) {
|
||||
this.armor = armor;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package fr.xephi.authme.gui;
|
||||
|
||||
import org.getspout.spoutapi.event.screen.ButtonClickEvent;
|
||||
|
||||
public interface Clickable {
|
||||
public void handleClick(ButtonClickEvent event);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package fr.xephi.authme.gui;
|
||||
|
||||
import org.getspout.spoutapi.event.screen.ButtonClickEvent;
|
||||
import org.getspout.spoutapi.gui.GenericButton;
|
||||
|
||||
public class CustomButton extends GenericButton
|
||||
{
|
||||
public Clickable handleRef = null;
|
||||
|
||||
public CustomButton(Clickable c) {
|
||||
handleRef = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onButtonClick(ButtonClickEvent event) {
|
||||
handleRef.handleClick(event);
|
||||
}
|
||||
|
||||
public CustomButton setMidPos(int x, int y)
|
||||
{
|
||||
this.setX(x)
|
||||
.setY(y)
|
||||
.shiftXPos(-(width / 2))
|
||||
.shiftYPos(-(height / 2));
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
package fr.xephi.authme.gui.screens;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.getspout.spoutapi.event.screen.ButtonClickEvent;
|
||||
import org.getspout.spoutapi.gui.Button;
|
||||
import org.getspout.spoutapi.gui.Color;
|
||||
import org.getspout.spoutapi.gui.GenericLabel;
|
||||
import org.getspout.spoutapi.gui.GenericPopup;
|
||||
import org.getspout.spoutapi.gui.GenericTextField;
|
||||
import org.getspout.spoutapi.gui.RenderPriority;
|
||||
import org.getspout.spoutapi.gui.Widget;
|
||||
import org.getspout.spoutapi.gui.WidgetAnchor;
|
||||
import org.getspout.spoutapi.player.SpoutPlayer;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.gui.Clickable;
|
||||
import fr.xephi.authme.gui.CustomButton;
|
||||
import fr.xephi.authme.settings.SpoutCfg;
|
||||
|
||||
|
||||
public class LoginScreen extends GenericPopup implements Clickable{
|
||||
|
||||
public AuthMe plugin = AuthMe.getInstance();
|
||||
private SpoutCfg spoutCfg = SpoutCfg.getInstance();
|
||||
private CustomButton exitBtn;
|
||||
private CustomButton loginBtn;
|
||||
private GenericTextField passBox;
|
||||
private GenericLabel titleLbl;
|
||||
private GenericLabel textLbl;
|
||||
private GenericLabel errorLbl;
|
||||
|
||||
String exitTxt = spoutCfg.getString("LoginScreen.exit button");
|
||||
String loginTxt = spoutCfg.getString("LoginScreen.login button");
|
||||
String exitMsg = spoutCfg.getString("LoginScreen.exit message");
|
||||
String title = spoutCfg.getString("LoginScreen.title");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> textlines = (List<String>) spoutCfg.getList("LoginScreen.text");
|
||||
public SpoutPlayer splayer;
|
||||
|
||||
public LoginScreen(SpoutPlayer player) {
|
||||
this.splayer = player;
|
||||
createScreen();
|
||||
}
|
||||
|
||||
private void createScreen() {
|
||||
int objects = textlines.size() + 4;
|
||||
int part = !(textlines.size() <= 5) ? 195 / objects : 20;
|
||||
int h = 3*part/4, w = 8*part;
|
||||
titleLbl = new GenericLabel();
|
||||
titleLbl
|
||||
.setText(title)
|
||||
.setTextColor(new Color(1.0F, 0, 0, 1.0F))
|
||||
.setAlign(WidgetAnchor.TOP_CENTER)
|
||||
.setHeight(h)
|
||||
.setWidth(w)
|
||||
.setX(maxWidth / 2 )
|
||||
.setY(25);
|
||||
this.attachWidget(plugin, titleLbl);
|
||||
int ystart = 25 + h + part/2;
|
||||
for (int x=0; x<textlines.size();x++)
|
||||
{
|
||||
textLbl = new GenericLabel();
|
||||
textLbl
|
||||
.setText(textlines.get(x))
|
||||
.setAlign(WidgetAnchor.TOP_CENTER)
|
||||
.setHeight(h)
|
||||
.setWidth(w)
|
||||
.setX(maxWidth / 2)
|
||||
.setY(ystart + x*part);
|
||||
this.attachWidget(plugin, textLbl);
|
||||
}
|
||||
passBox = new GenericTextField();
|
||||
passBox
|
||||
.setMaximumCharacters(18)
|
||||
.setMaximumLines(1)
|
||||
.setHeight(h-2)
|
||||
.setWidth(w-2)
|
||||
.setY(220-h - 2*part);
|
||||
passBox.setPasswordField(true);
|
||||
setXToMid(passBox);
|
||||
this.attachWidget(plugin, passBox);
|
||||
errorLbl = new GenericLabel();
|
||||
errorLbl
|
||||
.setText("")
|
||||
.setTextColor(new Color(1.0F, 0, 0, 1.0F))
|
||||
.setHeight(h)
|
||||
.setWidth(w)
|
||||
.setX(passBox.getX() + passBox.getWidth() + 2)
|
||||
.setY(passBox.getY());
|
||||
this.attachWidget(plugin, errorLbl);
|
||||
loginBtn = new CustomButton(this);
|
||||
loginBtn
|
||||
.setText(loginTxt)
|
||||
.setHeight(h)
|
||||
.setWidth(w)
|
||||
.setY(220-h-part);
|
||||
setXToMid(loginBtn);
|
||||
this.attachWidget(plugin, loginBtn);
|
||||
exitBtn = new CustomButton(this);
|
||||
exitBtn
|
||||
.setText(exitTxt)
|
||||
.setHeight(h)
|
||||
.setWidth(w)
|
||||
.setY(220-h);
|
||||
setXToMid(exitBtn);
|
||||
this.attachWidget(plugin, exitBtn);
|
||||
this.setPriority(RenderPriority.Highest);
|
||||
}
|
||||
|
||||
@EventHandler (priority = EventPriority.HIGHEST)
|
||||
public void handleClick(ButtonClickEvent event) {
|
||||
Button b = event.getButton();
|
||||
SpoutPlayer player = event.getPlayer();
|
||||
if (event.isCancelled() || event == null || event.getPlayer() == null) return;
|
||||
if (b.equals(loginBtn))
|
||||
{
|
||||
plugin.management.performLogin(player, passBox.getText(), false);
|
||||
}else if(b.equals(exitBtn))
|
||||
{
|
||||
event.getPlayer().kickPlayer(exitMsg);
|
||||
}
|
||||
}
|
||||
|
||||
private void setXToMid(Widget w) {
|
||||
w.setX( (maxWidth - w.getWidth()) / 2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class AuthMeBlockListener implements Listener {
|
||||
|
||||
private DataSource data;
|
||||
public AuthMe instance;
|
||||
|
||||
public AuthMeBlockListener(DataSource data, AuthMe instance) {
|
||||
this.data = data;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (event.isCancelled() || event.getPlayer() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if(Utils.getInstance().isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if (event.isCancelled() || event.getPlayer() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if(Utils.getInstance().isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(player.getName().toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import net.md_5.bungee.api.event.ChatEvent;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class AuthMeBungeeCordListener implements Listener {
|
||||
private DataSource data;
|
||||
|
||||
public AuthMeBungeeCordListener(DataSource data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@EventHandler (priority = EventPriority.LOWEST)
|
||||
public void onBungeeChatEvent(ChatEvent event) {
|
||||
if (!Settings.bungee) return;
|
||||
if (event.isCancelled()) return;
|
||||
if (!event.isCommand()) return;
|
||||
Player player = null;
|
||||
for (Player p : Bukkit.getServer().getOnlinePlayers()) {
|
||||
if (p.getAddress().getAddress().equals(event.getReceiver().getAddress().getAddress())) {
|
||||
player = p;
|
||||
}
|
||||
}
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (Utils.getInstance().isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setMessage("/unreacheablecommand");
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import com.Acrobot.ChestShop.Events.PreTransactionEvent;
|
||||
import com.Acrobot.ChestShop.Events.PreTransactionEvent.TransactionOutcome;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class AuthMeChestShopListener implements Listener {
|
||||
|
||||
public DataSource database;
|
||||
public AuthMe plugin;
|
||||
|
||||
public AuthMeChestShopListener(DataSource database, AuthMe plugin) {
|
||||
this.database = database;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPreTransaction(PreTransactionEvent event) {
|
||||
if (event.isCancelled() || event.getClient() == null || event == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getClient();
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (Utils.getInstance().isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!database.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setCancelled(TransactionOutcome.OTHER);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityInteractEvent;
|
||||
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||
import org.bukkit.event.entity.EntityTargetEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.Utils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.plugin.manager.CombatTagComunicator;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class AuthMeEntityListener implements Listener{
|
||||
|
||||
private DataSource data;
|
||||
public AuthMe instance;
|
||||
|
||||
public AuthMeEntityListener(DataSource data, AuthMe instance) {
|
||||
this.data = data;
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDamage(EntityDamageEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Entity entity = event.getEntity();
|
||||
|
||||
if (!(entity instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(Utils.getInstance().isUnrestricted((Player)entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance.citizens.isNPC(entity, instance))
|
||||
return;
|
||||
|
||||
Player player = (Player) entity;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if(CombatTagComunicator.isNPC(player))
|
||||
return;
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
player.setFireTicks(0);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityTarget(EntityTargetEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
if (event.getTarget() == null) return;
|
||||
Entity entity = event.getTarget();
|
||||
if (!(entity instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance.citizens.isNPC(entity, instance))
|
||||
return;
|
||||
|
||||
Player player = (Player) entity;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setTarget(null);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance.citizens.isNPC(entity, instance))
|
||||
return;
|
||||
|
||||
Player player = (Player) entity;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void EntityRegainHealthEvent(EntityRegainHealthEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity entity = event.getEntity();
|
||||
if (!(entity instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance.citizens.isNPC(entity, instance))
|
||||
return;
|
||||
|
||||
Player player = (Player) entity;
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler (priority = EventPriority.MONITOR)
|
||||
public void onEntityInteract(EntityInteractEvent event) {
|
||||
if (event.isCancelled() || event == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getEntity() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (Utils.getInstance().isUnrestricted(player) || CombatTagComunicator.isNPC(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance.citizens.isNPC(player, instance))
|
||||
return;
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(player.getName().toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler (priority = EventPriority.LOWEST)
|
||||
public void onLowestEntityInteract(EntityInteractEvent event) {
|
||||
if (event.isCancelled() || event == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getEntity() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
String name = player.getName().toLowerCase();
|
||||
|
||||
if (Utils.getInstance().isUnrestricted(player) || CombatTagComunicator.isNPC(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(instance.citizens.isNPC(player, instance))
|
||||
return;
|
||||
|
||||
if (PlayerCache.getInstance().isAuthenticated(player.getName().toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isAuthAvailable(name)) {
|
||||
if (!Settings.isForcedRegistrationEnabled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,27 @@
|
||||
package fr.xephi.authme.listener;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.getspout.spoutapi.event.spout.SpoutCraftEnableEvent;
|
||||
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.gui.screens.LoginScreen;
|
||||
import fr.xephi.authme.settings.SpoutCfg;
|
||||
|
||||
public class AuthMeSpoutListener implements Listener {
|
||||
private DataSource data;
|
||||
|
||||
public AuthMeSpoutListener(DataSource data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSpoutCraftEnable(final SpoutCraftEnableEvent event) {
|
||||
if(SpoutCfg.getInstance().getBoolean("LoginScreen.enabled")) {
|
||||
if (data.isAuthAvailable(event.getPlayer().getName().toLowerCase()) && !PlayerCache.getInstance().isAuthenticated(event.getPlayer().getName().toLowerCase()) ) {
|
||||
event.getPlayer().getMainScreen().attachPopupScreen(new LoginScreen(event.getPlayer()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.plugin.manager;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
public class BungeeCordMessage implements PluginMessageListener {
|
||||
|
||||
public AuthMe plugin;
|
||||
|
||||
public BungeeCordMessage(AuthMe plugin)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(String channel, Player player, byte[] message) {
|
||||
try {
|
||||
final DataInputStream in = new DataInputStream(new ByteArrayInputStream(message));
|
||||
if (in.readUTF().equals("IP")) { //We need only the IP channel
|
||||
plugin.realIp.put(player.getName().toLowerCase(), in.readUTF()); //Put the IP (only the ip not the port) in the hashmap
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package fr.xephi.authme.plugin.manager;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.CitizensManager;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
public class CitizensCommunicator {
|
||||
|
||||
public AuthMe instance;
|
||||
|
||||
public CitizensCommunicator(AuthMe instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public boolean isNPC(final Entity player, AuthMe instance) {
|
||||
try {
|
||||
if (instance.CitizensVersion == 1) {
|
||||
return CitizensManager.isNPC(player);
|
||||
} else if (instance.CitizensVersion == 2) {
|
||||
return CitizensAPI.getNPCRegistry().isNPC(player);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
return false;
|
||||
} catch (Exception npe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package fr.xephi.authme.plugin.manager;
|
||||
|
||||
import com.trc202.CombatTag.CombatTag;
|
||||
import com.trc202.CombatTagApi.CombatTagApi;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class CombatTagComunicator {
|
||||
|
||||
static CombatTagApi combatApi;
|
||||
|
||||
public CombatTagComunicator() {
|
||||
if(Bukkit.getServer().getPluginManager().getPlugin("CombatTag") != null){
|
||||
combatApi = new CombatTagApi((CombatTag)Bukkit.getServer().getPluginManager().getPlugin("CombatTag"));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks to see if the player is in combat. The combat time can be configured by the server owner
|
||||
* If the player has died while in combat the player is no longer considered in combat and as such will return false
|
||||
* @param playerName
|
||||
* @return true if player is in combat
|
||||
*/
|
||||
public abstract boolean isInCombat(String player);
|
||||
|
||||
/**
|
||||
* Checks to see if the player is in combat. The combat time can be configured by the server owner
|
||||
* If the player has died while in combat the player is no longer considered in combat and as such will return false
|
||||
* @param player
|
||||
* @return true if player is in combat
|
||||
*/
|
||||
public abstract boolean isInCombat(Player player);
|
||||
/**
|
||||
* Returns the time before the tag is over
|
||||
* -1 if the tag has expired
|
||||
* -2 if the player is not in combat
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public abstract long getRemainingTagTime(String player);
|
||||
|
||||
/**
|
||||
* Returns if the entity is an NPC
|
||||
* @param player
|
||||
* @return true if the player is an NPC
|
||||
*/
|
||||
public static boolean isNPC(Entity player) {
|
||||
try {
|
||||
if(Bukkit.getServer().getPluginManager().getPlugin("CombatTag") != null){
|
||||
combatApi = new CombatTagApi((CombatTag) Bukkit.getServer().getPluginManager().getPlugin("CombatTag"));
|
||||
return combatApi.isNPC(player);
|
||||
}
|
||||
} catch (ClassCastException ex) {
|
||||
return false;
|
||||
} catch (NullPointerException npe) {
|
||||
return false;
|
||||
} catch (NoClassDefFoundError ncdfe) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package fr.xephi.authme.plugin.manager;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import fr.xephi.authme.settings.CustomConfiguration;
|
||||
|
||||
public class EssSpawn extends CustomConfiguration {
|
||||
|
||||
private static EssSpawn spawn;
|
||||
|
||||
public EssSpawn() {
|
||||
super(new File("./plugins/Essentials/spawn.yml"));
|
||||
spawn = this;
|
||||
load();
|
||||
}
|
||||
|
||||
public static EssSpawn getInstance() {
|
||||
if (spawn == null) {
|
||||
spawn = new EssSpawn();
|
||||
}
|
||||
return spawn;
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
try {
|
||||
if (this.getString("spawns.default.world").isEmpty() || this.getString("spawns.default.world") == "") return null;
|
||||
Location location = new Location(Bukkit.getWorld(this.getString("spawns.default.world")), this.getDouble("spawns.default.x"), this.getDouble("spawns.default.y"), this.getDouble("spawns.default.z"), Float.parseFloat(this.getString("spawns.default.yaw")), Float.parseFloat(this.getString("spawns.default.pitch")));
|
||||
return location;
|
||||
} catch (NullPointerException npe) {
|
||||
return null;
|
||||
} catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils.Null;
|
||||
|
||||
public enum HashAlgorithm {
|
||||
|
||||
MD5(fr.xephi.authme.security.crypts.MD5.class),
|
||||
SHA1(fr.xephi.authme.security.crypts.SHA1.class),
|
||||
SHA256(fr.xephi.authme.security.crypts.SHA256.class),
|
||||
WHIRLPOOL(fr.xephi.authme.security.crypts.WHIRLPOOL.class),
|
||||
XAUTH(fr.xephi.authme.security.crypts.XAUTH.class),
|
||||
MD5VB(fr.xephi.authme.security.crypts.MD5VB.class),
|
||||
PHPBB(fr.xephi.authme.security.crypts.PHPBB.class),
|
||||
PLAINTEXT(fr.xephi.authme.security.crypts.PLAINTEXT.class),
|
||||
MYBB(fr.xephi.authme.security.crypts.MYBB.class),
|
||||
IPB3(fr.xephi.authme.security.crypts.IPB3.class),
|
||||
PHPFUSION(fr.xephi.authme.security.crypts.PHPFUSION.class),
|
||||
SMF(fr.xephi.authme.security.crypts.SMF.class),
|
||||
XENFORO(fr.xephi.authme.security.crypts.XF.class),
|
||||
SALTED2MD5(fr.xephi.authme.security.crypts.SALTED2MD5.class),
|
||||
JOOMLA(fr.xephi.authme.security.crypts.JOOMLA.class),
|
||||
BCRYPT(fr.xephi.authme.security.crypts.BCRYPT.class),
|
||||
WBB3(fr.xephi.authme.security.crypts.WBB3.class),
|
||||
SHA512(fr.xephi.authme.security.crypts.SHA512.class),
|
||||
DOUBLEMD5(fr.xephi.authme.security.crypts.DOUBLEMD5.class),
|
||||
PBKDF2(fr.xephi.authme.security.crypts.CryptPBKDF2.class),
|
||||
WORDPRESS(fr.xephi.authme.security.crypts.WORDPRESS.class),
|
||||
CUSTOM(Null.class);
|
||||
|
||||
Class<?> classe;
|
||||
|
||||
HashAlgorithm(Class<?> classe) {
|
||||
this.classe = classe;
|
||||
}
|
||||
|
||||
public Class<?> getclass() {
|
||||
return classe;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.events.PasswordEncryptionEvent;
|
||||
import fr.xephi.authme.security.crypts.BCRYPT;
|
||||
import fr.xephi.authme.security.crypts.EncryptionMethod;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class PasswordSecurity {
|
||||
|
||||
private static SecureRandom rnd = new SecureRandom();
|
||||
public static HashMap<String, String> userSalt = new HashMap<String, String>();
|
||||
|
||||
private static String createSalt(int length) throws NoSuchAlgorithmException {
|
||||
byte[] msg = new byte[40];
|
||||
rnd.nextBytes(msg);
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||
sha1.reset();
|
||||
byte[] digest = sha1.digest(msg);
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest)).substring(0, length);
|
||||
}
|
||||
|
||||
public static String getHash(HashAlgorithm alg, String password, String playerName) throws NoSuchAlgorithmException {
|
||||
EncryptionMethod method;
|
||||
try {
|
||||
if (alg != HashAlgorithm.CUSTOM)
|
||||
method = (EncryptionMethod) alg.getclass().newInstance();
|
||||
else method = null;
|
||||
} catch (InstantiationException e) {
|
||||
throw new NoSuchAlgorithmException("Problem with this hash algorithm");
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchAlgorithmException("Problem with this hash algorithm");
|
||||
}
|
||||
String salt = "";
|
||||
switch (alg) {
|
||||
case MD5:
|
||||
case SHA1:
|
||||
case WHIRLPOOL:
|
||||
case PHPBB:
|
||||
case PLAINTEXT:
|
||||
case XENFORO:
|
||||
case SHA512:
|
||||
case DOUBLEMD5:
|
||||
case WORDPRESS:
|
||||
case CUSTOM:
|
||||
break;
|
||||
case SHA256:
|
||||
salt = createSalt(16);
|
||||
break;
|
||||
case MD5VB:
|
||||
salt = createSalt(16);
|
||||
break;
|
||||
case XAUTH:
|
||||
salt = createSalt(12);
|
||||
break;
|
||||
case MYBB:
|
||||
salt = createSalt(8);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case IPB3:
|
||||
salt = createSalt(5);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case PHPFUSION:
|
||||
salt = createSalt(12);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case SALTED2MD5:
|
||||
salt = createSalt(Settings.saltLength);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case JOOMLA:
|
||||
salt = createSalt(32);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case BCRYPT:
|
||||
salt = BCRYPT.gensalt(Settings.bCryptLog2Rounds);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case WBB3:
|
||||
salt = createSalt(40);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case PBKDF2:
|
||||
salt = createSalt(12);
|
||||
userSalt.put(playerName, salt);
|
||||
break;
|
||||
case SMF:
|
||||
return method.getHash(password, playerName.toLowerCase());
|
||||
default:
|
||||
throw new NoSuchAlgorithmException("Unknown hash algorithm");
|
||||
}
|
||||
PasswordEncryptionEvent event = new PasswordEncryptionEvent(method, playerName);
|
||||
method = event.getMethod();
|
||||
if (method == null)
|
||||
throw new NoSuchAlgorithmException("Unknown hash algorithm");
|
||||
return method.getHash(password, salt);
|
||||
}
|
||||
|
||||
public static boolean comparePasswordWithHash(String password, String hash, String playerName) throws NoSuchAlgorithmException {
|
||||
HashAlgorithm algo = Settings.getPasswordHash;
|
||||
EncryptionMethod method;
|
||||
try {
|
||||
if (algo != HashAlgorithm.CUSTOM)
|
||||
method = (EncryptionMethod) algo.getclass().newInstance();
|
||||
else method = null;
|
||||
} catch (InstantiationException e) {
|
||||
throw new NoSuchAlgorithmException("Problem with this hash algorithm");
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new NoSuchAlgorithmException("Problem with this hash algorithm");
|
||||
}
|
||||
PasswordEncryptionEvent event = new PasswordEncryptionEvent(method, playerName);
|
||||
method = event.getMethod();
|
||||
if (method == null)
|
||||
throw new NoSuchAlgorithmException("Unknown hash algorithm");
|
||||
|
||||
if (method.comparePassword(hash, password, playerName))
|
||||
return true;
|
||||
if (Settings.supportOldPassword) {
|
||||
try {
|
||||
if (compareWithAllEncryptionMethod(password, hash, playerName))
|
||||
return true;
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean compareWithAllEncryptionMethod(String password, String hash, String playerName) throws NoSuchAlgorithmException {
|
||||
for (HashAlgorithm algo : HashAlgorithm.values()) {
|
||||
try {
|
||||
if (algo != HashAlgorithm.CUSTOM)
|
||||
if (((EncryptionMethod) algo.getclass().newInstance()).comparePassword(hash, password, playerName)) {
|
||||
PlayerAuth nAuth = AuthMe.getInstance().database.getAuth(playerName);
|
||||
if (nAuth != null) {
|
||||
nAuth.setHash(getHash(Settings.getPasswordHash, password, playerName));
|
||||
nAuth.setSalt(userSalt.get(playerName));
|
||||
AuthMe.getInstance().database.updatePassword(nAuth);
|
||||
AuthMe.getInstance().database.updateSalt(nAuth);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (InstantiationException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package fr.xephi.authme.security;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class RandomString
|
||||
{
|
||||
|
||||
private static final char[] chars = new char[36];
|
||||
|
||||
static {
|
||||
for (int idx = 0; idx < 10; ++idx)
|
||||
chars[idx] = (char) ('0' + idx);
|
||||
for (int idx = 10; idx < 36; ++idx)
|
||||
chars[idx] = (char) ('a' + idx - 10);
|
||||
}
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
private final char[] buf;
|
||||
|
||||
public RandomString(int length)
|
||||
{
|
||||
if (length < 1)
|
||||
throw new IllegalArgumentException("length < 1: " + length);
|
||||
buf = new char[length];
|
||||
}
|
||||
|
||||
public String nextString()
|
||||
{
|
||||
for (int idx = 0; idx < buf.length; ++idx)
|
||||
buf[idx] = chars[random.nextInt(chars.length)];
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,768 @@
|
||||
//Copyright (c) 2006 Damien Miller <djm@mindrot.org>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
/**
|
||||
* BCrypt implements OpenBSD-style Blowfish password hashing using
|
||||
* the scheme described in "A Future-Adaptable Password Scheme" by
|
||||
* Niels Provos and David Mazieres.
|
||||
* <p>
|
||||
* This password hashing system tries to thwart off-line password
|
||||
* cracking using a computationally-intensive hashing algorithm,
|
||||
* based on Bruce Schneier's Blowfish cipher. The work factor of
|
||||
* the algorithm is parameterised, so it can be increased as
|
||||
* computers get faster.
|
||||
* <p>
|
||||
* Usage is really simple. To hash a password for the first time,
|
||||
* call the hashpw method with a random salt, like this:
|
||||
* <p>
|
||||
* <code>
|
||||
* String pw_hash = BCrypt.hashpw(plain_password, BCrypt.gensalt()); <br />
|
||||
* </code>
|
||||
* <p>
|
||||
* To check whether a plaintext password matches one that has been
|
||||
* hashed previously, use the checkpw method:
|
||||
* <p>
|
||||
* <code>
|
||||
* if (BCrypt.checkpw(candidate_password, stored_hash))<br />
|
||||
* System.out.println("It matches");<br />
|
||||
* else<br />
|
||||
* System.out.println("It does not match");<br />
|
||||
* </code>
|
||||
* <p>
|
||||
* The gensalt() method takes an optional parameter (log_rounds)
|
||||
* that determines the computational complexity of the hashing:
|
||||
* <p>
|
||||
* <code>
|
||||
* String strong_salt = BCrypt.gensalt(10)<br />
|
||||
* String stronger_salt = BCrypt.gensalt(12)<br />
|
||||
* </code>
|
||||
* <p>
|
||||
* The amount of work increases exponentially (2**log_rounds), so
|
||||
* each increment is twice as much work. The default log_rounds is
|
||||
* 10, and the valid range is 4 to 31.
|
||||
*
|
||||
* @author Damien Miller
|
||||
* @version 0.2
|
||||
*/
|
||||
public class BCRYPT implements EncryptionMethod {
|
||||
// BCrypt parameters
|
||||
private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
|
||||
private static final int BCRYPT_SALT_LEN = 16;
|
||||
|
||||
// Blowfish parameters
|
||||
private static final int BLOWFISH_NUM_ROUNDS = 16;
|
||||
|
||||
// Initial contents of key schedule
|
||||
private static final int P_orig[] = {
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
||||
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
};
|
||||
private static final int S_orig[] = {
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
||||
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
||||
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
||||
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
||||
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
||||
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
||||
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
||||
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
||||
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
||||
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
||||
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
||||
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
||||
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
||||
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
||||
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
||||
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
||||
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
||||
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
||||
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
||||
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
||||
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
||||
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
||||
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
||||
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
||||
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
||||
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
||||
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
||||
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
||||
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
||||
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
||||
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
||||
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
||||
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
||||
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
||||
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
||||
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
||||
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
||||
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
||||
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
||||
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
||||
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
||||
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
||||
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
||||
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
||||
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
||||
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
||||
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
||||
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
||||
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
||||
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
||||
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
||||
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
||||
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
||||
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
||||
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
||||
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
||||
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
||||
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
||||
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
||||
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
||||
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
||||
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
||||
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
||||
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
||||
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
||||
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
||||
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
||||
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
||||
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
||||
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
||||
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
||||
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
||||
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
||||
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
||||
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
||||
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
||||
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
||||
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
||||
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
||||
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
||||
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
||||
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
||||
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
||||
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
||||
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||
};
|
||||
|
||||
// bcrypt IV: "OrpheanBeholderScryDoubt"
|
||||
static private final int bf_crypt_ciphertext[] = {
|
||||
0x4f727068, 0x65616e42, 0x65686f6c,
|
||||
0x64657253, 0x63727944, 0x6f756274
|
||||
};
|
||||
|
||||
// Table for Base64 encoding
|
||||
static private final char base64_code[] = {
|
||||
'.', '/', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
|
||||
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5',
|
||||
'6', '7', '8', '9'
|
||||
};
|
||||
|
||||
// Table for Base64 decoding
|
||||
static private final byte index_64[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, 0, 1, 54, 55,
|
||||
56, 57, 58, 59, 60, 61, 62, 63, -1, -1,
|
||||
-1, -1, -1, -1, -1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
-1, -1, -1, -1, -1, -1, 28, 29, 30,
|
||||
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
|
||||
51, 52, 53, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
// Expanded Blowfish key
|
||||
private int P[];
|
||||
private int S[];
|
||||
|
||||
/**
|
||||
* Encode a byte array using bcrypt's slightly-modified base64
|
||||
* encoding scheme. Note that this is *not* compatible with
|
||||
* the standard MIME-base64 encoding.
|
||||
*
|
||||
* @param d the byte array to encode
|
||||
* @param len the number of bytes to encode
|
||||
* @return base64-encoded string
|
||||
* @exception IllegalArgumentException if the length is invalid
|
||||
*/
|
||||
private static String encode_base64(byte d[], int len)
|
||||
throws IllegalArgumentException {
|
||||
int off = 0;
|
||||
StringBuffer rs = new StringBuffer();
|
||||
int c1, c2;
|
||||
|
||||
if (len <= 0 || len > d.length)
|
||||
throw new IllegalArgumentException ("Invalid len");
|
||||
|
||||
while (off < len) {
|
||||
c1 = d[off++] & 0xff;
|
||||
rs.append(base64_code[(c1 >> 2) & 0x3f]);
|
||||
c1 = (c1 & 0x03) << 4;
|
||||
if (off >= len) {
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
break;
|
||||
}
|
||||
c2 = d[off++] & 0xff;
|
||||
c1 |= (c2 >> 4) & 0x0f;
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
c1 = (c2 & 0x0f) << 2;
|
||||
if (off >= len) {
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
break;
|
||||
}
|
||||
c2 = d[off++] & 0xff;
|
||||
c1 |= (c2 >> 6) & 0x03;
|
||||
rs.append(base64_code[c1 & 0x3f]);
|
||||
rs.append(base64_code[c2 & 0x3f]);
|
||||
}
|
||||
return rs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up the 3 bits base64-encoded by the specified character,
|
||||
* range-checking againt conversion table
|
||||
* @param x the base64-encoded value
|
||||
* @return the decoded value of x
|
||||
*/
|
||||
private static byte char64(char x) {
|
||||
if ((int)x < 0 || (int)x > index_64.length)
|
||||
return -1;
|
||||
return index_64[(int)x];
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a string encoded using bcrypt's base64 scheme to a
|
||||
* byte array. Note that this is *not* compatible with
|
||||
* the standard MIME-base64 encoding.
|
||||
* @param s the string to decode
|
||||
* @param maxolen the maximum number of bytes to decode
|
||||
* @return an array containing the decoded bytes
|
||||
* @throws IllegalArgumentException if maxolen is invalid
|
||||
*/
|
||||
private static byte[] decode_base64(String s, int maxolen)
|
||||
throws IllegalArgumentException {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
int off = 0, slen = s.length(), olen = 0;
|
||||
byte ret[];
|
||||
byte c1, c2, c3, c4, o;
|
||||
|
||||
if (maxolen <= 0)
|
||||
throw new IllegalArgumentException ("Invalid maxolen");
|
||||
|
||||
while (off < slen - 1 && olen < maxolen) {
|
||||
c1 = char64(s.charAt(off++));
|
||||
c2 = char64(s.charAt(off++));
|
||||
if (c1 == -1 || c2 == -1)
|
||||
break;
|
||||
o = (byte)(c1 << 2);
|
||||
o |= (c2 & 0x30) >> 4;
|
||||
rs.append((char)o);
|
||||
if (++olen >= maxolen || off >= slen)
|
||||
break;
|
||||
c3 = char64(s.charAt(off++));
|
||||
if (c3 == -1)
|
||||
break;
|
||||
o = (byte)((c2 & 0x0f) << 4);
|
||||
o |= (c3 & 0x3c) >> 2;
|
||||
rs.append((char)o);
|
||||
if (++olen >= maxolen || off >= slen)
|
||||
break;
|
||||
c4 = char64(s.charAt(off++));
|
||||
o = (byte)((c3 & 0x03) << 6);
|
||||
o |= c4;
|
||||
rs.append((char)o);
|
||||
++olen;
|
||||
}
|
||||
|
||||
ret = new byte[olen];
|
||||
for (off = 0; off < olen; off++)
|
||||
ret[off] = (byte)rs.charAt(off);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blowfish encipher a single 64-bit block encoded as
|
||||
* two 32-bit halves
|
||||
* @param lr an array containing the two 32-bit half blocks
|
||||
* @param off the position in the array of the blocks
|
||||
*/
|
||||
private final void encipher(int lr[], int off) {
|
||||
int i, n, l = lr[off], r = lr[off + 1];
|
||||
|
||||
l ^= P[0];
|
||||
for (i = 0; i <= BLOWFISH_NUM_ROUNDS - 2;) {
|
||||
// Feistel substitution on left word
|
||||
n = S[(l >> 24) & 0xff];
|
||||
n += S[0x100 | ((l >> 16) & 0xff)];
|
||||
n ^= S[0x200 | ((l >> 8) & 0xff)];
|
||||
n += S[0x300 | (l & 0xff)];
|
||||
r ^= n ^ P[++i];
|
||||
|
||||
// Feistel substitution on right word
|
||||
n = S[(r >> 24) & 0xff];
|
||||
n += S[0x100 | ((r >> 16) & 0xff)];
|
||||
n ^= S[0x200 | ((r >> 8) & 0xff)];
|
||||
n += S[0x300 | (r & 0xff)];
|
||||
l ^= n ^ P[++i];
|
||||
}
|
||||
lr[off] = r ^ P[BLOWFISH_NUM_ROUNDS + 1];
|
||||
lr[off + 1] = l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycically extract a word of key material
|
||||
* @param data the string to extract the data from
|
||||
* @param offp a "pointer" (as a one-entry array) to the
|
||||
* current offset into data
|
||||
* @return the next word of material from data
|
||||
*/
|
||||
private static int streamtoword(byte data[], int offp[]) {
|
||||
int i;
|
||||
int word = 0;
|
||||
int off = offp[0];
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
word = (word << 8) | (data[off] & 0xff);
|
||||
off = (off + 1) % data.length;
|
||||
}
|
||||
|
||||
offp[0] = off;
|
||||
return word;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the Blowfish key schedule
|
||||
*/
|
||||
private void init_key() {
|
||||
P = (int[])P_orig.clone();
|
||||
S = (int[])S_orig.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Key the Blowfish cipher
|
||||
* @param key an array containing the key
|
||||
*/
|
||||
private void key(byte key[]) {
|
||||
int i;
|
||||
int koffp[] = { 0 };
|
||||
int lr[] = { 0, 0 };
|
||||
int plen = P.length, slen = S.length;
|
||||
|
||||
for (i = 0; i < plen; i++)
|
||||
P[i] = P[i] ^ streamtoword(key, koffp);
|
||||
|
||||
for (i = 0; i < plen; i += 2) {
|
||||
encipher(lr, 0);
|
||||
P[i] = lr[0];
|
||||
P[i + 1] = lr[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < slen; i += 2) {
|
||||
encipher(lr, 0);
|
||||
S[i] = lr[0];
|
||||
S[i + 1] = lr[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the "enhanced key schedule" step described by
|
||||
* Provos and Mazieres in "A Future-Adaptable Password Scheme"
|
||||
* http://www.openbsd.org/papers/bcrypt-paper.ps
|
||||
* @param data salt information
|
||||
* @param key password information
|
||||
*/
|
||||
private void ekskey(byte data[], byte key[]) {
|
||||
int i;
|
||||
int koffp[] = { 0 }, doffp[] = { 0 };
|
||||
int lr[] = { 0, 0 };
|
||||
int plen = P.length, slen = S.length;
|
||||
|
||||
for (i = 0; i < plen; i++)
|
||||
P[i] = P[i] ^ streamtoword(key, koffp);
|
||||
|
||||
for (i = 0; i < plen; i += 2) {
|
||||
lr[0] ^= streamtoword(data, doffp);
|
||||
lr[1] ^= streamtoword(data, doffp);
|
||||
encipher(lr, 0);
|
||||
P[i] = lr[0];
|
||||
P[i + 1] = lr[1];
|
||||
}
|
||||
|
||||
for (i = 0; i < slen; i += 2) {
|
||||
lr[0] ^= streamtoword(data, doffp);
|
||||
lr[1] ^= streamtoword(data, doffp);
|
||||
encipher(lr, 0);
|
||||
S[i] = lr[0];
|
||||
S[i + 1] = lr[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the central password hashing step in the
|
||||
* bcrypt scheme
|
||||
* @param password the password to hash
|
||||
* @param salt the binary salt to hash with the password
|
||||
* @param log_rounds the binary logarithm of the number
|
||||
* of rounds of hashing to apply
|
||||
* @return an array containing the binary hashed password
|
||||
*/
|
||||
private byte[] crypt_raw(byte password[], byte salt[], int log_rounds) {
|
||||
int rounds, i, j;
|
||||
int cdata[] = (int[])bf_crypt_ciphertext.clone();
|
||||
int clen = cdata.length;
|
||||
byte ret[];
|
||||
|
||||
if (log_rounds < 4 || log_rounds > 31)
|
||||
throw new IllegalArgumentException ("Bad number of rounds");
|
||||
rounds = 1 << log_rounds;
|
||||
if (salt.length != BCRYPT_SALT_LEN)
|
||||
throw new IllegalArgumentException ("Bad salt length");
|
||||
|
||||
init_key();
|
||||
ekskey(salt, password);
|
||||
for (i = 0; i < rounds; i++) {
|
||||
key(password);
|
||||
key(salt);
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
for (j = 0; j < (clen >> 1); j++)
|
||||
encipher(cdata, j << 1);
|
||||
}
|
||||
|
||||
ret = new byte[clen * 4];
|
||||
for (i = 0, j = 0; i < clen; i++) {
|
||||
ret[j++] = (byte)((cdata[i] >> 24) & 0xff);
|
||||
ret[j++] = (byte)((cdata[i] >> 16) & 0xff);
|
||||
ret[j++] = (byte)((cdata[i] >> 8) & 0xff);
|
||||
ret[j++] = (byte)(cdata[i] & 0xff);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a password using the OpenBSD bcrypt scheme
|
||||
* @param password the password to hash
|
||||
* @param salt the salt to hash with (perhaps generated
|
||||
* using BCrypt.gensalt)
|
||||
* @return the hashed password
|
||||
*/
|
||||
public static String hashpw(String password, String salt) {
|
||||
BCRYPT B;
|
||||
String real_salt;
|
||||
byte passwordb[], saltb[], hashed[];
|
||||
char minor = (char)0;
|
||||
int rounds, off = 0;
|
||||
StringBuffer rs = new StringBuffer();
|
||||
|
||||
if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
|
||||
throw new IllegalArgumentException ("Invalid salt version");
|
||||
if (salt.charAt(2) == '$')
|
||||
off = 3;
|
||||
else {
|
||||
minor = salt.charAt(2);
|
||||
if (minor != 'a' || salt.charAt(3) != '$')
|
||||
throw new IllegalArgumentException ("Invalid salt revision");
|
||||
off = 4;
|
||||
}
|
||||
|
||||
// Extract number of rounds
|
||||
if (salt.charAt(off + 2) > '$')
|
||||
throw new IllegalArgumentException ("Missing salt rounds");
|
||||
rounds = Integer.parseInt(salt.substring(off, off + 2));
|
||||
|
||||
real_salt = salt.substring(off + 3, off + 25);
|
||||
try {
|
||||
passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException uee) {
|
||||
throw new AssertionError("UTF-8 is not supported");
|
||||
}
|
||||
|
||||
saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
|
||||
|
||||
B = new BCRYPT();
|
||||
hashed = B.crypt_raw(passwordb, saltb, rounds);
|
||||
|
||||
rs.append("$2");
|
||||
if (minor >= 'a')
|
||||
rs.append(minor);
|
||||
rs.append("$");
|
||||
if (rounds < 10)
|
||||
rs.append("0");
|
||||
rs.append(Integer.toString(rounds));
|
||||
rs.append("$");
|
||||
rs.append(encode_base64(saltb, saltb.length));
|
||||
rs.append(encode_base64(hashed,
|
||||
bf_crypt_ciphertext.length * 4 - 1));
|
||||
return rs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a salt for use with the BCrypt.hashpw() method
|
||||
* @param log_rounds the log2 of the number of rounds of
|
||||
* hashing to apply - the work factor therefore increases as
|
||||
* 2**log_rounds.
|
||||
* @param random an instance of SecureRandom to use
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt(int log_rounds, SecureRandom random) {
|
||||
StringBuffer rs = new StringBuffer();
|
||||
byte rnd[] = new byte[BCRYPT_SALT_LEN];
|
||||
|
||||
random.nextBytes(rnd);
|
||||
|
||||
rs.append("$2a$");
|
||||
if (log_rounds < 10)
|
||||
rs.append("0");
|
||||
rs.append(Integer.toString(log_rounds));
|
||||
rs.append("$");
|
||||
rs.append(encode_base64(rnd, rnd.length));
|
||||
return rs.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a salt for use with the BCrypt.hashpw() method
|
||||
* @param log_rounds the log2 of the number of rounds of
|
||||
* hashing to apply - the work factor therefore increases as
|
||||
* 2**log_rounds.
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt(int log_rounds) {
|
||||
return gensalt(log_rounds, new SecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a salt for use with the BCrypt.hashpw() method,
|
||||
* selecting a reasonable default for the number of hashing
|
||||
* rounds to apply
|
||||
* @return an encoded salt value
|
||||
*/
|
||||
public static String gensalt() {
|
||||
return gensalt(GENSALT_DEFAULT_LOG2_ROUNDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a plaintext password matches a previously hashed
|
||||
* one
|
||||
* @param plaintext the plaintext password to verify
|
||||
* @param hashed the previously-hashed password
|
||||
* @return true if the passwords match, false otherwise
|
||||
*/
|
||||
public static boolean checkpw(String plaintext, String hashed) {
|
||||
return (hashed.compareTo(hashpw(plaintext, hashed)) == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return hashpw(password, salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(hashpw(password, salt));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import fr.xephi.authme.security.pbkdf2.PBKDF2Engine;
|
||||
import fr.xephi.authme.security.pbkdf2.PBKDF2Parameters;
|
||||
|
||||
|
||||
public class CryptPBKDF2 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
String result = "pbkdf2_sha256$10000$"+salt+"$";
|
||||
PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "ASCII", salt.getBytes(), 10000);
|
||||
PBKDF2Engine engine = new PBKDF2Engine(params);
|
||||
|
||||
return result + engine.deriveKey(password,64).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String[] line = hash.split("\\$");
|
||||
String salt = line[2];
|
||||
String derivedKey = line[3];
|
||||
PBKDF2Parameters params = new PBKDF2Parameters("HmacSHA256", "ASCII", salt.getBytes(), 10000, derivedKey.getBytes());
|
||||
PBKDF2Engine engine = new PBKDF2Engine(params);
|
||||
return engine.verifyKey(password);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class DOUBLEMD5 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getMD5(getMD5(password));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
return hash.equals(getHash(password, ""));
|
||||
}
|
||||
|
||||
private String getMD5(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(message.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* <p>Public interface for Custom Password encryption method</p>
|
||||
* <p>The getHash function is called when we need to crypt the password (/register usually)</p>
|
||||
* <p>The comparePassword is called when we need to match password (/login usually)</p>
|
||||
*/
|
||||
public interface EncryptionMethod {
|
||||
|
||||
/**
|
||||
* @param password
|
||||
* @param salt (can be an other data like playerName;salt , playerName, etc...
|
||||
* for customs methods)
|
||||
* @return Hashing password
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
String getHash(String password, String salt) throws NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* @param hash
|
||||
* @param password
|
||||
* @param playerName
|
||||
* @return true if password match, false else
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
boolean comparePassword(String hash, String password, String playerName) throws NoSuchAlgorithmException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
public class IPB3 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getMD5(getMD5(salt) + getMD5(password));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(getHash(password, salt));
|
||||
}
|
||||
|
||||
private String getMD5(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(message.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class JOOMLA implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getMD5(password + salt) + ":" + salt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = hash.split(":")[1];
|
||||
return hash.equals(getMD5(password + salt) + ":" + salt);
|
||||
}
|
||||
|
||||
private String getMD5(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(message.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(password.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password, String playerName) throws NoSuchAlgorithmException {
|
||||
return hash.equals(getHash(password, ""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5VB implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return "$MD5vb$" + salt + "$" + getMD5(getMD5(password) + salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String[] line = hash.split("\\$");
|
||||
return hash.equals(getHash(password, line[2]));
|
||||
}
|
||||
|
||||
private String getMD5(String password) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(password.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
public class MYBB implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getMD5(getMD5(salt)+ getMD5(password));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(getHash(password, salt));
|
||||
}
|
||||
|
||||
private String getMD5(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(message.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* To change this template, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author stefano
|
||||
*/
|
||||
public class PHPBB implements EncryptionMethod {
|
||||
private static final int PHP_VERSION = 4;
|
||||
private String itoa64 =
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
public String phpbb_hash(String password) {
|
||||
String random_state = unique_id();
|
||||
String random = "";
|
||||
int count = 6;
|
||||
if (random.length() < count) {
|
||||
random = "";
|
||||
for (int i = 0; i < count; i += 16) {
|
||||
random_state = md5(unique_id() + random_state);
|
||||
random += pack(md5(random_state));
|
||||
}
|
||||
random = random.substring(0, count);
|
||||
}
|
||||
String hash = _hash_crypt_private(
|
||||
password, _hash_gensalt_private(random, itoa64));
|
||||
if (hash.length() == 34)
|
||||
return hash;
|
||||
return md5(password);
|
||||
}
|
||||
|
||||
private String unique_id() {
|
||||
return unique_id("c");
|
||||
}
|
||||
|
||||
private String unique_id(String extra) {
|
||||
//TODO: Maybe check the salt?
|
||||
return "1234567890abcdef";
|
||||
}
|
||||
|
||||
private String _hash_gensalt_private(String input, String itoa64) {
|
||||
return _hash_gensalt_private(input, itoa64, 6);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String _hash_gensalt_private(
|
||||
String input, String itoa64, int iteration_count_log2) {
|
||||
if (iteration_count_log2 < 4 || iteration_count_log2 > 31) {
|
||||
iteration_count_log2 = 8;
|
||||
}
|
||||
String output = "$H$";
|
||||
output += itoa64.charAt(
|
||||
Math.min(iteration_count_log2 +
|
||||
((PHP_VERSION >= 5) ? 5 : 3), 30));
|
||||
output += _hash_encode64(input, 6);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode hash
|
||||
*/
|
||||
private String _hash_encode64(String input, int count) {
|
||||
String output = "";
|
||||
int i = 0;
|
||||
do {
|
||||
int value = input.charAt(i++);
|
||||
output += itoa64.charAt(value & 0x3f);
|
||||
if (i < count)
|
||||
value |= input.charAt(i) << 8;
|
||||
output += itoa64.charAt((value >> 6) & 0x3f);
|
||||
if (i++ >= count)
|
||||
break;
|
||||
if (i < count)
|
||||
value |= input.charAt(i) << 16;
|
||||
output += itoa64.charAt((value >> 12) & 0x3f);
|
||||
if (i++ >= count)
|
||||
break;
|
||||
output += itoa64.charAt((value >> 18) & 0x3f);
|
||||
} while (i < count);
|
||||
return output;
|
||||
}
|
||||
String _hash_crypt_private(String password, String setting) {
|
||||
String output = "*";
|
||||
if (!setting.substring(0, 3).equals("$H$"))
|
||||
return output;
|
||||
int count_log2 = itoa64.indexOf(setting.charAt(3));
|
||||
if (count_log2 < 7 || count_log2 > 30)
|
||||
return output;
|
||||
int count = 1 << count_log2;
|
||||
String salt = setting.substring(4, 12);
|
||||
if (salt.length() != 8)
|
||||
return output;
|
||||
String m1 = md5(salt + password);
|
||||
String hash = pack(m1);
|
||||
do {
|
||||
hash = pack(md5(hash + password));
|
||||
} while (--count > 0);
|
||||
output = setting.substring(0, 12);
|
||||
output += _hash_encode64(hash, 16);
|
||||
return output;
|
||||
}
|
||||
|
||||
public boolean phpbb_check_hash( String password, String hash) {
|
||||
if (hash.length() == 34)
|
||||
return _hash_crypt_private(password, hash).equals(hash);
|
||||
else
|
||||
return md5(password).equals(hash);
|
||||
}
|
||||
|
||||
public static String md5(String data) {
|
||||
try {
|
||||
byte[] bytes = data.getBytes("ISO-8859-1");
|
||||
MessageDigest md5er = MessageDigest.getInstance("MD5");
|
||||
byte[] hash = md5er.digest(bytes);
|
||||
return bytes2hex(hash);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static int hexToInt(char ch) {
|
||||
if(ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
ch = Character.toUpperCase(ch);
|
||||
if(ch >= 'A' && ch <= 'F')
|
||||
return ch - 'A' + 0xA;
|
||||
throw new IllegalArgumentException("Not a hex character: " + ch);
|
||||
}
|
||||
|
||||
private static String bytes2hex(byte[] bytes) {
|
||||
StringBuffer r = new StringBuffer(32);
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
String x = Integer.toHexString(bytes[i] & 0xff);
|
||||
if (x.length() < 2)
|
||||
r.append("0");
|
||||
r.append(x);
|
||||
}
|
||||
return r.toString();
|
||||
}
|
||||
|
||||
static String pack(String hex) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for(int i = 0; i < hex.length(); i += 2) {
|
||||
char c1 = hex.charAt(i);
|
||||
char c2 = hex.charAt(i+1);
|
||||
char packed = (char) (hexToInt(c1) * 16 + hexToInt(c2));
|
||||
buf.append(packed);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return phpbb_hash(password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password, String playerName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return phpbb_check_hash(password, hash);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
public class PHPFUSION implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
String digest = null;
|
||||
String algo = "HmacSHA256";
|
||||
String keyString = getSHA1(salt);
|
||||
try {
|
||||
SecretKeySpec key = new SecretKeySpec((keyString).getBytes("UTF-8"), algo);
|
||||
Mac mac = Mac.getInstance(algo);
|
||||
mac.init(key);
|
||||
byte[] bytes = mac.doFinal(password.getBytes("ASCII"));
|
||||
StringBuffer hash = new StringBuffer();
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
String hex = Integer.toHexString(0xFF & bytes[i]);
|
||||
if (hex.length() == 1) {
|
||||
hash.append('0');
|
||||
}
|
||||
hash.append(hex);
|
||||
}
|
||||
digest = hash.toString();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
} catch (InvalidKeyException e) {
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
}
|
||||
return digest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(getHash(password, salt));
|
||||
}
|
||||
|
||||
private String getSHA1(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||
sha1.reset();
|
||||
sha1.update(message.getBytes());
|
||||
byte[] digest = sha1.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class PLAINTEXT implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
return hash.equals(password);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
public class SALTED2MD5 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getMD5(getMD5(password) + salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(getMD5(getMD5(password) + salt));
|
||||
}
|
||||
|
||||
private String getMD5(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.reset();
|
||||
md5.update(message.getBytes());
|
||||
byte[] digest = md5.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class SHA1 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt) throws NoSuchAlgorithmException {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||
sha1.reset();
|
||||
sha1.update(password.getBytes());
|
||||
byte[] digest = sha1.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password, String playerName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return hash.equals(getHash(password, ""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class SHA256 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt) throws NoSuchAlgorithmException {
|
||||
return "$SHA$" + salt + "$" + getSha256(getSha256(password) + salt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password, String playerName)
|
||||
throws NoSuchAlgorithmException {
|
||||
String[] line = hash.split("\\$");
|
||||
return hash.equals(getHash(password, line[2]));
|
||||
}
|
||||
|
||||
private String getSha256(String password) throws NoSuchAlgorithmException {
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
sha256.reset();
|
||||
sha256.update(password.getBytes());
|
||||
byte[] digest = sha256.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class SHA512 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
MessageDigest sha512 = MessageDigest.getInstance("SHA-512");
|
||||
sha512.reset();
|
||||
sha512.update(password.getBytes());
|
||||
byte[] digest = sha512.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
return hash.equals(getHash(password, ""));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class SMF implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getSHA1(salt.toLowerCase() + password);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
return hash.equals(getHash(password, playerName.toLowerCase()));
|
||||
}
|
||||
|
||||
private String getSHA1(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||
sha1.reset();
|
||||
sha1.update(message.getBytes());
|
||||
byte[] digest = sha1.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
public class WBB3 implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getSHA1(salt.concat(getSHA1(salt.concat(getSHA1(password)))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(getHash(password, salt));
|
||||
}
|
||||
|
||||
private String getSHA1(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||
sha1.reset();
|
||||
sha1.update(message.getBytes());
|
||||
byte[] digest = sha1.digest();
|
||||
return String.format("%0" + (digest.length << 1) + "x", new BigInteger(1,digest));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
/**
|
||||
* The Whirlpool hashing function.
|
||||
*
|
||||
* <P>
|
||||
* <b>References</b>
|
||||
*
|
||||
* <P>
|
||||
* The Whirlpool algorithm was developed by
|
||||
* <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
|
||||
* <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
|
||||
*
|
||||
* See
|
||||
* P.S.L.M. Barreto, V. Rijmen,
|
||||
* ``The Whirlpool hashing function,''
|
||||
* First NESSIE workshop, 2000 (tweaked version, 2003),
|
||||
* <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
|
||||
*
|
||||
* @author Paulo S.L.M. Barreto
|
||||
* @author Vincent Rijmen.
|
||||
*
|
||||
* @version 3.0 (2003.03.12)
|
||||
*
|
||||
* =============================================================================
|
||||
*
|
||||
* Differences from version 2.1:
|
||||
*
|
||||
* - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2, 9).
|
||||
*
|
||||
* =============================================================================
|
||||
*
|
||||
* Differences from version 2.0:
|
||||
*
|
||||
* - Generation of ISO/IEC 10118-3 test vectors.
|
||||
* - Bug fix: nonzero carry was ignored when tallying the data length
|
||||
* (this bug apparently only manifested itself when feeding data
|
||||
* in pieces rather than in a single chunk at once).
|
||||
*
|
||||
* Differences from version 1.0:
|
||||
*
|
||||
* - Original S-box replaced by the tweaked, hardware-efficient version.
|
||||
*
|
||||
* =============================================================================
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class WHIRLPOOL implements EncryptionMethod {
|
||||
|
||||
public WHIRLPOOL() {}
|
||||
|
||||
/**
|
||||
* The message digest size (in bits)
|
||||
*/
|
||||
public static final int DIGESTBITS = 512;
|
||||
|
||||
/**
|
||||
* The message digest size (in bytes)
|
||||
*/
|
||||
public static final int DIGESTBYTES = DIGESTBITS >>> 3;
|
||||
|
||||
/**
|
||||
* The number of rounds of the internal dedicated block cipher.
|
||||
*/
|
||||
protected static final int R = 10;
|
||||
|
||||
/**
|
||||
* The substitution box.
|
||||
*/
|
||||
private static final String sbox =
|
||||
"\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152" +
|
||||
"\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57" +
|
||||
"\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85" +
|
||||
"\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8" +
|
||||
"\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333" +
|
||||
"\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0" +
|
||||
"\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE" +
|
||||
"\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d" +
|
||||
"\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF" +
|
||||
"\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A" +
|
||||
"\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c" +
|
||||
"\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04" +
|
||||
"\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB" +
|
||||
"\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9" +
|
||||
"\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1" +
|
||||
"\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886";
|
||||
|
||||
private static long[][] C = new long[8][256];
|
||||
private static long[] rc = new long[R + 1];
|
||||
|
||||
static {
|
||||
for (int x = 0; x < 256; x++) {
|
||||
char c = sbox.charAt(x/2);
|
||||
long v1 = ((x & 1) == 0) ? c >>> 8 : c & 0xff;
|
||||
long v2 = v1 << 1;
|
||||
if (v2 >= 0x100L) {
|
||||
v2 ^= 0x11dL;
|
||||
}
|
||||
long v4 = v2 << 1;
|
||||
if (v4 >= 0x100L) {
|
||||
v4 ^= 0x11dL;
|
||||
}
|
||||
long v5 = v4 ^ v1;
|
||||
long v8 = v4 << 1;
|
||||
if (v8 >= 0x100L) {
|
||||
v8 ^= 0x11dL;
|
||||
}
|
||||
long v9 = v8 ^ v1;
|
||||
/*
|
||||
* build the circulant table C[0][x] = S[x].[1, 1, 4, 1, 8, 5, 2, 9]:
|
||||
*/
|
||||
C[0][x] =
|
||||
(v1 << 56) | (v1 << 48) | (v4 << 40) | (v1 << 32) |
|
||||
(v8 << 24) | (v5 << 16) | (v2 << 8) | (v9 );
|
||||
/*
|
||||
* build the remaining circulant tables C[t][x] = C[0][x] rotr t
|
||||
*/
|
||||
for (int t = 1; t < 8; t++) {
|
||||
C[t][x] = (C[t - 1][x] >>> 8) | ((C[t - 1][x] << 56));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* build the round constants:
|
||||
*/
|
||||
rc[0] = 0L; /* not used (assigment kept only to properly initialize all variables) */
|
||||
for (int r = 1; r <= R; r++) {
|
||||
int i = 8*(r - 1);
|
||||
rc[r] =
|
||||
(C[0][i ] & 0xff00000000000000L) ^
|
||||
(C[1][i + 1] & 0x00ff000000000000L) ^
|
||||
(C[2][i + 2] & 0x0000ff0000000000L) ^
|
||||
(C[3][i + 3] & 0x000000ff00000000L) ^
|
||||
(C[4][i + 4] & 0x00000000ff000000L) ^
|
||||
(C[5][i + 5] & 0x0000000000ff0000L) ^
|
||||
(C[6][i + 6] & 0x000000000000ff00L) ^
|
||||
(C[7][i + 7] & 0x00000000000000ffL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Global number of hashed bits (256-bit counter).
|
||||
*/
|
||||
protected byte[] bitLength = new byte[32];
|
||||
|
||||
/**
|
||||
* Buffer of data to hash.
|
||||
*/
|
||||
protected byte[] buffer = new byte[64];
|
||||
|
||||
/**
|
||||
* Current number of bits on the buffer.
|
||||
*/
|
||||
protected int bufferBits = 0;
|
||||
|
||||
/**
|
||||
* Current (possibly incomplete) byte slot on the buffer.
|
||||
*/
|
||||
protected int bufferPos = 0;
|
||||
|
||||
/**
|
||||
* The hashing state.
|
||||
*/
|
||||
protected long[] hash = new long[8];
|
||||
protected long[] K = new long[8];
|
||||
protected long[] L = new long[8];
|
||||
protected long[] block = new long[8];
|
||||
protected long[] state = new long[8];
|
||||
|
||||
/**
|
||||
* The core Whirlpool transform.
|
||||
*/
|
||||
protected void processBuffer() {
|
||||
/*
|
||||
* map the buffer to a block:
|
||||
*/
|
||||
for (int i = 0, j = 0; i < 8; i++, j += 8) {
|
||||
block[i] =
|
||||
(((long)buffer[j ] ) << 56) ^
|
||||
(((long)buffer[j + 1] & 0xffL) << 48) ^
|
||||
(((long)buffer[j + 2] & 0xffL) << 40) ^
|
||||
(((long)buffer[j + 3] & 0xffL) << 32) ^
|
||||
(((long)buffer[j + 4] & 0xffL) << 24) ^
|
||||
(((long)buffer[j + 5] & 0xffL) << 16) ^
|
||||
(((long)buffer[j + 6] & 0xffL) << 8) ^
|
||||
(((long)buffer[j + 7] & 0xffL) );
|
||||
}
|
||||
/*
|
||||
* compute and apply K^0 to the cipher state:
|
||||
*/
|
||||
for (int i = 0; i < 8; i++) {
|
||||
state[i] = block[i] ^ (K[i] = hash[i]);
|
||||
}
|
||||
/*
|
||||
* iterate over all rounds:
|
||||
*/
|
||||
for (int r = 1; r <= R; r++) {
|
||||
/*
|
||||
* compute K^r from K^{r-1}:
|
||||
*/
|
||||
for (int i = 0; i < 8; i++) {
|
||||
L[i] = 0L;
|
||||
for (int t = 0, s = 56; t < 8; t++, s -= 8) {
|
||||
L[i] ^= C[t][(int)(K[(i - t) & 7] >>> s) & 0xff];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
K[i] = L[i];
|
||||
}
|
||||
K[0] ^= rc[r];
|
||||
/*
|
||||
* apply the r-th round transformation:
|
||||
*/
|
||||
for (int i = 0; i < 8; i++) {
|
||||
L[i] = K[i];
|
||||
for (int t = 0, s = 56; t < 8; t++, s -= 8) {
|
||||
L[i] ^= C[t][(int)(state[(i - t) & 7] >>> s) & 0xff];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
state[i] = L[i];
|
||||
}
|
||||
}
|
||||
/*
|
||||
* apply the Miyaguchi-Preneel compression function:
|
||||
*/
|
||||
for (int i = 0; i < 8; i++) {
|
||||
hash[i] ^= state[i] ^ block[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the hashing state.
|
||||
*/
|
||||
public void NESSIEinit() {
|
||||
Arrays.fill(bitLength, (byte)0);
|
||||
bufferBits = bufferPos = 0;
|
||||
buffer[0] = 0;
|
||||
Arrays.fill(hash, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivers input data to the hashing algorithm.
|
||||
*
|
||||
* @param source plaintext data to hash.
|
||||
* @param sourceBits how many bits of plaintext to process.
|
||||
*
|
||||
* This method maintains the invariant: bufferBits < 512
|
||||
*/
|
||||
public void NESSIEadd(byte[] source, long sourceBits) {
|
||||
/*
|
||||
sourcePos
|
||||
|
|
||||
+-------+-------+-------
|
||||
||||||||||||||||||||| source
|
||||
+-------+-------+-------
|
||||
+-------+-------+-------+-------+-------+-------
|
||||
|||||||||||||||||||||| buffer
|
||||
+-------+-------+-------+-------+-------+-------
|
||||
|
|
||||
bufferPos
|
||||
*/
|
||||
int sourcePos = 0; // index of leftmost source byte containing data (1 to 8 bits).
|
||||
int sourceGap = (8 - ((int)sourceBits & 7)) & 7; // space on source[sourcePos].
|
||||
int bufferRem = bufferBits & 7; // occupied bits on buffer[bufferPos].
|
||||
int b;
|
||||
// tally the length of the added data:
|
||||
long value = sourceBits;
|
||||
for (int i = 31, carry = 0; i >= 0; i--) {
|
||||
carry += (bitLength[i] & 0xff) + ((int)value & 0xff);
|
||||
bitLength[i] = (byte)carry;
|
||||
carry >>>= 8;
|
||||
value >>>= 8;
|
||||
}
|
||||
// process data in chunks of 8 bits:
|
||||
while (sourceBits > 8) { // at least source[sourcePos] and source[sourcePos+1] contain data.
|
||||
// take a byte from the source:
|
||||
b = ((source[sourcePos] << sourceGap) & 0xff) |
|
||||
((source[sourcePos + 1] & 0xff) >>> (8 - sourceGap));
|
||||
if (b < 0 || b >= 256) {
|
||||
throw new RuntimeException("LOGIC ERROR");
|
||||
}
|
||||
// process this byte:
|
||||
buffer[bufferPos++] |= b >>> bufferRem;
|
||||
bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos;
|
||||
if (bufferBits == 512) {
|
||||
// process data block:
|
||||
processBuffer();
|
||||
// reset buffer:
|
||||
bufferBits = bufferPos = 0;
|
||||
}
|
||||
buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff);
|
||||
bufferBits += bufferRem;
|
||||
// proceed to remaining data:
|
||||
sourceBits -= 8;
|
||||
sourcePos++;
|
||||
}
|
||||
// now 0 <= sourceBits <= 8;
|
||||
// furthermore, all data (if any is left) is in source[sourcePos].
|
||||
if (sourceBits > 0) {
|
||||
b = (source[sourcePos] << sourceGap) & 0xff; // bits are left-justified on b.
|
||||
// process the remaining bits:
|
||||
buffer[bufferPos] |= b >>> bufferRem;
|
||||
} else {
|
||||
b = 0;
|
||||
}
|
||||
if (bufferRem + sourceBits < 8) {
|
||||
// all remaining data fits on buffer[bufferPos], and there still remains some space.
|
||||
bufferBits += sourceBits;
|
||||
} else {
|
||||
// buffer[bufferPos] is full:
|
||||
bufferPos++;
|
||||
bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos;
|
||||
sourceBits -= 8 - bufferRem;
|
||||
// now 0 <= sourceBits < 8; furthermore, all data is in source[sourcePos].
|
||||
if (bufferBits == 512) {
|
||||
// process data block:
|
||||
processBuffer();
|
||||
// reset buffer:
|
||||
bufferBits = bufferPos = 0;
|
||||
}
|
||||
buffer[bufferPos] = (byte)((b << (8 - bufferRem)) & 0xff);
|
||||
bufferBits += (int)sourceBits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hash value from the hashing state.
|
||||
*
|
||||
* This method uses the invariant: bufferBits < 512
|
||||
*/
|
||||
public void NESSIEfinalize(byte[] digest) {
|
||||
// append a '1'-bit:
|
||||
buffer[bufferPos] |= 0x80 >>> (bufferBits & 7);
|
||||
bufferPos++; // all remaining bits on the current byte are set to zero.
|
||||
// pad with zero bits to complete 512N + 256 bits:
|
||||
if (bufferPos > 32) {
|
||||
while (bufferPos < 64) {
|
||||
buffer[bufferPos++] = 0;
|
||||
}
|
||||
// process data block:
|
||||
processBuffer();
|
||||
// reset buffer:
|
||||
bufferPos = 0;
|
||||
}
|
||||
while (bufferPos < 32) {
|
||||
buffer[bufferPos++] = 0;
|
||||
}
|
||||
// append bit length of hashed data:
|
||||
System.arraycopy(bitLength, 0, buffer, 32, 32);
|
||||
// process data block:
|
||||
processBuffer();
|
||||
// return the completed message digest:
|
||||
for (int i = 0, j = 0; i < 8; i++, j += 8) {
|
||||
long h = hash[i];
|
||||
digest[j ] = (byte)(h >>> 56);
|
||||
digest[j + 1] = (byte)(h >>> 48);
|
||||
digest[j + 2] = (byte)(h >>> 40);
|
||||
digest[j + 3] = (byte)(h >>> 32);
|
||||
digest[j + 4] = (byte)(h >>> 24);
|
||||
digest[j + 5] = (byte)(h >>> 16);
|
||||
digest[j + 6] = (byte)(h >>> 8);
|
||||
digest[j + 7] = (byte)(h );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delivers string input data to the hashing algorithm.
|
||||
*
|
||||
* @param source plaintext data to hash (ASCII text string).
|
||||
*
|
||||
* This method maintains the invariant: bufferBits < 512
|
||||
*/
|
||||
public void NESSIEadd(String source) {
|
||||
if (source.length() > 0) {
|
||||
byte[] data = new byte[source.length()];
|
||||
for (int i = 0; i < source.length(); i++) {
|
||||
data[i] = (byte)source.charAt(i);
|
||||
}
|
||||
NESSIEadd(data, 8*data.length);
|
||||
}
|
||||
}
|
||||
|
||||
protected static String display(byte[] array) {
|
||||
char[] val = new char[2*array.length];
|
||||
String hex = "0123456789ABCDEF";
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
int b = array[i] & 0xff;
|
||||
val[2*i] = hex.charAt(b >>> 4);
|
||||
val[2*i + 1] = hex.charAt(b & 15);
|
||||
}
|
||||
return String.valueOf(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
byte[] digest = new byte[DIGESTBYTES];
|
||||
NESSIEinit();
|
||||
NESSIEadd(password);
|
||||
NESSIEfinalize(digest);
|
||||
return display(digest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
return hash.equals(getHash(password, ""));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class WORDPRESS implements EncryptionMethod {
|
||||
private static String itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
private int iterationCountLog2 = 8;
|
||||
private SecureRandom randomGen = new SecureRandom();
|
||||
|
||||
private String encode64(byte[] src, int count) {
|
||||
int i, value;
|
||||
String output = "";
|
||||
i = 0;
|
||||
|
||||
if (src.length < count) {
|
||||
byte[] t = new byte[count];
|
||||
System.arraycopy(src, 0, t, 0, src.length);
|
||||
Arrays.fill(t, src.length, count - 1, (byte) 0);
|
||||
}
|
||||
|
||||
do {
|
||||
value = src[i] + (src[i] < 0 ? 256 : 0);
|
||||
++i;
|
||||
output += itoa64.charAt(value & 63);
|
||||
if (i < count) {
|
||||
value |= (src[i] + (src[i] < 0 ? 256 : 0)) << 8;
|
||||
}
|
||||
output += itoa64.charAt((value >> 6) & 63);
|
||||
if (i++ >= count) {
|
||||
break;
|
||||
}
|
||||
if (i < count) {
|
||||
value |= (src[i] + (src[i] < 0 ? 256 : 0)) << 16;
|
||||
}
|
||||
output += itoa64.charAt((value >> 12) & 63);
|
||||
if (i++ >= count) {
|
||||
break;
|
||||
}
|
||||
output += itoa64.charAt((value >> 18) & 63);
|
||||
} while (i < count);
|
||||
return output;
|
||||
}
|
||||
|
||||
private String crypt(String password, String setting) {
|
||||
String output = "*0";
|
||||
if (((setting.length() < 2) ? setting : setting.substring(0, 2)).equalsIgnoreCase(output)) {
|
||||
output = "*1";
|
||||
}
|
||||
String id = (setting.length() < 3) ? setting : setting.substring(0, 3);
|
||||
if (!(id.equals("$P$") || id.equals("$H$"))) {
|
||||
return output;
|
||||
}
|
||||
int countLog2 = itoa64.indexOf(setting.charAt(3));
|
||||
if (countLog2 < 7 || countLog2 > 30) {
|
||||
return output;
|
||||
}
|
||||
int count = 1 << countLog2;
|
||||
String salt = setting.substring(4, 4 + 8);
|
||||
if (salt.length() != 8) {
|
||||
return output;
|
||||
}
|
||||
MessageDigest md;
|
||||
try {
|
||||
md = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return output;
|
||||
}
|
||||
byte[] pass = stringToUtf8(password);
|
||||
byte[] hash = md.digest(stringToUtf8(salt + password));
|
||||
do {
|
||||
byte[] t = new byte[hash.length + pass.length];
|
||||
System.arraycopy(hash, 0, t, 0, hash.length);
|
||||
System.arraycopy(pass, 0, t, hash.length, pass.length);
|
||||
hash = md.digest(t);
|
||||
} while (--count > 0);
|
||||
output = setting.substring(0, 12);
|
||||
output += encode64(hash, 16);
|
||||
return output;
|
||||
}
|
||||
|
||||
private String gensaltPrivate(byte[] input) {
|
||||
String output = "$P$";
|
||||
output += itoa64.charAt(Math.min(this.iterationCountLog2 + 5, 30));
|
||||
output += encode64(input, 6);
|
||||
return output;
|
||||
}
|
||||
|
||||
private byte[] stringToUtf8(String string) {
|
||||
try {
|
||||
return string.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new UnsupportedOperationException("This system doesn't support UTF-8!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt) throws NoSuchAlgorithmException {
|
||||
byte random[] = new byte[6];
|
||||
this.randomGen.nextBytes(random);
|
||||
return crypt(password, gensaltPrivate(stringToUtf8(new String(random))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String comparedHash = crypt(password, hash);
|
||||
return comparedHash.equals(hash);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class XAUTH implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
WHIRLPOOL w = new WHIRLPOOL();
|
||||
String hash = w.getHash((salt + password).toLowerCase(), "");
|
||||
int saltPos = (password.length() >= hash.length() ? hash.length() - 1 : password.length());
|
||||
return hash.substring(0, saltPos) + salt + hash.substring(saltPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
int saltPos = (password.length() >= hash.length() ? hash.length() - 1 : password.length());
|
||||
String salt = hash.substring(saltPos, saltPos + 12);
|
||||
return hash.equals(getHash(password, salt));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
|
||||
|
||||
public class XF implements EncryptionMethod {
|
||||
|
||||
@Override
|
||||
public String getHash(String password, String salt)
|
||||
throws NoSuchAlgorithmException {
|
||||
return getSHA256(getSHA256(password) + regmatch("\"salt\";.:..:\"(.*)\";.:.:\"hashFunc\"", salt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean comparePassword(String hash, String password,
|
||||
String playerName) throws NoSuchAlgorithmException {
|
||||
String salt = AuthMe.getInstance().database.getAuth(playerName).getSalt();
|
||||
return hash.equals(regmatch("\"hash\";.:..:\"(.*)\";.:.:\"salt\"", salt));
|
||||
}
|
||||
|
||||
public String getSHA256(String password) throws NoSuchAlgorithmException
|
||||
{
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||||
md.update(password.getBytes());
|
||||
byte byteData[] = md.digest();
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (byte element : byteData)
|
||||
{
|
||||
sb.append(Integer.toString((element & 0xff) + 0x100, 16).substring(1));
|
||||
}
|
||||
StringBuffer hexString = new StringBuffer();
|
||||
for (byte element : byteData)
|
||||
{
|
||||
String hex = Integer.toHexString(0xff & element);
|
||||
if (hex.length() == 1)
|
||||
{
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
}
|
||||
|
||||
public String regmatch(String pattern, String line)
|
||||
{
|
||||
List<String> allMatches = new ArrayList<String>();
|
||||
Matcher m = Pattern.compile(pattern).matcher(line);
|
||||
while (m.find())
|
||||
{
|
||||
allMatches.add(m.group(1));
|
||||
}
|
||||
return allMatches.get(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Free auxiliary functions. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public class BinTools
|
||||
{
|
||||
public static final String hex = "0123456789ABCDEF";
|
||||
|
||||
/**
|
||||
* Simple binary-to-hexadecimal conversion.
|
||||
*
|
||||
* @param b
|
||||
* Input bytes. May be <code>null</code>.
|
||||
* @return Hexadecimal representation of b. Uppercase A-F, two characters
|
||||
* per byte. Empty string on <code>null</code> input.
|
||||
*/
|
||||
public static String bin2hex(final byte[] b)
|
||||
{
|
||||
if (b == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
StringBuffer sb = new StringBuffer(2 * b.length);
|
||||
for (int i = 0; i < b.length; i++)
|
||||
{
|
||||
int v = (256 + b[i]) % 256;
|
||||
sb.append(hex.charAt((v / 16) & 15));
|
||||
sb.append(hex.charAt((v % 16) & 15));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hex string to array of bytes.
|
||||
*
|
||||
* @param s
|
||||
* String containing hexadecimal digits. May be <code>null</code>.
|
||||
* On odd length leading zero will be assumed.
|
||||
* @return Array on bytes, non-<code>null</code>.
|
||||
* @throws IllegalArgumentException
|
||||
* when string contains non-hex character
|
||||
*/
|
||||
public static byte[] hex2bin(final String s)
|
||||
{
|
||||
String m = s;
|
||||
if (s == null)
|
||||
{
|
||||
// Allow empty input string.
|
||||
m = "";
|
||||
}
|
||||
else if (s.length() % 2 != 0)
|
||||
{
|
||||
// Assume leading zero for odd string length
|
||||
m = "0" + s;
|
||||
}
|
||||
byte r[] = new byte[m.length() / 2];
|
||||
for (int i = 0, n = 0; i < m.length(); n++)
|
||||
{
|
||||
char h = m.charAt(i++);
|
||||
char l = m.charAt(i++);
|
||||
r[n] = (byte) (hex2bin(h) * 16 + hex2bin(l));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hex digit to numerical value.
|
||||
*
|
||||
* @param c
|
||||
* 0-9, a-f, A-F allowd.
|
||||
* @return 0-15
|
||||
* @throws IllegalArgumentException
|
||||
* on non-hex character
|
||||
*/
|
||||
public static int hex2bin(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
{
|
||||
return (c - '0');
|
||||
}
|
||||
if (c >= 'A' && c <= 'F')
|
||||
{
|
||||
return (c - 'A' + 10);
|
||||
}
|
||||
if (c >= 'a' && c <= 'f')
|
||||
{
|
||||
return (c - 'a' + 10);
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Input string may only contain hex digits, but found '" + c
|
||||
+ "'");
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
byte b[] = new byte[256];
|
||||
byte bb = 0;
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
b[i] = bb++;
|
||||
}
|
||||
String s = bin2hex(b);
|
||||
byte c[] = hex2bin(s);
|
||||
String t = bin2hex(c);
|
||||
if (!s.equals(t))
|
||||
{
|
||||
throw new AssertionError("Mismatch");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Default PRF implementation based on standard javax.crypt.Mac mechanisms.
|
||||
*
|
||||
* <hr />
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MacBasedPRF implements PRF
|
||||
{
|
||||
protected Mac mac;
|
||||
|
||||
protected int hLen;
|
||||
|
||||
protected String macAlgorithm;
|
||||
|
||||
/**
|
||||
* Create Mac-based Pseudo Random Function.
|
||||
*
|
||||
* @param macAlgorithm
|
||||
* Mac algorithm to use, i.e. HMacSHA1 or HMacMD5.
|
||||
*/
|
||||
public MacBasedPRF(String macAlgorithm)
|
||||
{
|
||||
this.macAlgorithm = macAlgorithm;
|
||||
try
|
||||
{
|
||||
mac = Mac.getInstance(macAlgorithm);
|
||||
hLen = mac.getMacLength();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public MacBasedPRF(String macAlgorithm, String provider)
|
||||
{
|
||||
this.macAlgorithm = macAlgorithm;
|
||||
try
|
||||
{
|
||||
mac = Mac.getInstance(macAlgorithm, provider);
|
||||
hLen = mac.getMacLength();
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (NoSuchProviderException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] doFinal(byte[] M)
|
||||
{
|
||||
byte[] r = mac.doFinal(M);
|
||||
return r;
|
||||
}
|
||||
|
||||
public int getHLen()
|
||||
{
|
||||
return hLen;
|
||||
}
|
||||
|
||||
public void init(byte[] P)
|
||||
{
|
||||
try
|
||||
{
|
||||
mac.init(new SecretKeySpec(P, macAlgorithm));
|
||||
}
|
||||
catch (InvalidKeyException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface PBKDF2
|
||||
{
|
||||
/**
|
||||
* Convert String-based input to internal byte array, then invoke PBKDF2.
|
||||
* Desired key length defaults to Pseudo Random Function block size.
|
||||
*
|
||||
* @param inputPassword
|
||||
* Candidate password to compute the derived key for.
|
||||
* @return internal byte array
|
||||
*/
|
||||
public abstract byte[] deriveKey(String inputPassword);
|
||||
|
||||
/**
|
||||
* Convert String-based input to internal byte array, then invoke PBKDF2.
|
||||
*
|
||||
* @param inputPassword
|
||||
* Candidate password to compute the derived key for.
|
||||
* @param dkLen
|
||||
* Specify desired key length
|
||||
* @return internal byte array
|
||||
*/
|
||||
public abstract byte[] deriveKey(String inputPassword, int dkLen);
|
||||
|
||||
/**
|
||||
* Convert String-based input to internal byte arrays, then invoke PBKDF2
|
||||
* and verify result against the reference data that is supplied in the
|
||||
* PBKDF2Parameters.
|
||||
*
|
||||
* @param inputPassword
|
||||
* Candidate password to compute the derived key for.
|
||||
* @return <code>true</code> password match; <code>false</code>
|
||||
* incorrect password
|
||||
*/
|
||||
public abstract boolean verifyKey(String inputPassword);
|
||||
|
||||
/**
|
||||
* Allow reading of configured parameters.
|
||||
*
|
||||
* @return Currently set parameters.
|
||||
*/
|
||||
public abstract PBKDF2Parameters getParameters();
|
||||
|
||||
/**
|
||||
* Allow setting of configured parameters.
|
||||
*
|
||||
* @param parameters
|
||||
*/
|
||||
public abstract void setParameters(PBKDF2Parameters parameters);
|
||||
|
||||
/**
|
||||
* Get currently set Pseudo Random Function.
|
||||
*
|
||||
* @return Currently set Pseudo Random Function
|
||||
*/
|
||||
public abstract PRF getPseudoRandomFunction();
|
||||
|
||||
/**
|
||||
* Set the Pseudo Random Function to use. Note that deriveKeys/getPRF does
|
||||
* init this object using the supplied candidate password. If this is
|
||||
* undesired, one has to override getPRF.
|
||||
*
|
||||
* @param prf
|
||||
* Pseudo Random Function to set.
|
||||
*/
|
||||
public abstract void setPseudoRandomFunction(PRF prf);
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Request for Comments: 2898 PKCS #5: Password-Based Cryptography Specification
|
||||
* <p>
|
||||
* Version 2.0
|
||||
*
|
||||
* <p>
|
||||
* PBKDF2 (P, S, c, dkLen)
|
||||
*
|
||||
* <p>
|
||||
* Options:
|
||||
* <ul>
|
||||
* <li>PRF underlying pseudorandom function (hLen denotes the length in octets
|
||||
* of the pseudorandom function output). PRF is pluggable.</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Input:
|
||||
* <ul>
|
||||
* <li>P password, an octet string</li>
|
||||
* <li>S salt, an octet string</li>
|
||||
* <li>c iteration count, a positive integer</li>
|
||||
* <li>dkLen intended length in octets of the derived key, a positive integer,
|
||||
* at most (2^32 - 1) * hLen</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* Output:
|
||||
* <ul>
|
||||
* <li>DK derived key, a dkLen-octet string</li>
|
||||
* </ul>
|
||||
*
|
||||
* <hr />
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898</a>
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PBKDF2Engine implements PBKDF2
|
||||
{
|
||||
protected PBKDF2Parameters parameters;
|
||||
|
||||
protected PRF prf;
|
||||
|
||||
/**
|
||||
* Constructor for PBKDF2 implementation object. PBKDF2 parameters must be
|
||||
* passed later.
|
||||
*/
|
||||
public PBKDF2Engine()
|
||||
{
|
||||
this.parameters = null;
|
||||
prf = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PBKDF2 implementation object. PBKDF2 parameters are
|
||||
* passed so that this implementation knows iteration count, method to use
|
||||
* and String encoding.
|
||||
*
|
||||
* @param parameters
|
||||
* Data holder for iteration count, method to use et cetera.
|
||||
*/
|
||||
public PBKDF2Engine(PBKDF2Parameters parameters)
|
||||
{
|
||||
this.parameters = parameters;
|
||||
prf = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for PBKDF2 implementation object. PBKDF2 parameters are
|
||||
* passed so that this implementation knows iteration count, method to use
|
||||
* and String encoding.
|
||||
*
|
||||
* @param parameters
|
||||
* Data holder for iteration count, method to use et cetera.
|
||||
* @param prf
|
||||
* Supply customer Pseudo Random Function.
|
||||
*/
|
||||
public PBKDF2Engine(PBKDF2Parameters parameters, PRF prf)
|
||||
{
|
||||
this.parameters = parameters;
|
||||
this.prf = prf;
|
||||
}
|
||||
|
||||
public byte[] deriveKey(String inputPassword)
|
||||
{
|
||||
return deriveKey(inputPassword, 0);
|
||||
}
|
||||
|
||||
public byte[] deriveKey(String inputPassword, int dkLen)
|
||||
{
|
||||
byte[] r = null;
|
||||
byte P[] = null;
|
||||
String charset = parameters.getHashCharset();
|
||||
if (inputPassword == null)
|
||||
{
|
||||
inputPassword = "";
|
||||
}
|
||||
try
|
||||
{
|
||||
if (charset == null)
|
||||
{
|
||||
P = inputPassword.getBytes();
|
||||
}
|
||||
else
|
||||
{
|
||||
P = inputPassword.getBytes(charset);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
assertPRF(P);
|
||||
if (dkLen == 0)
|
||||
{
|
||||
dkLen = prf.getHLen();
|
||||
}
|
||||
r = PBKDF2(prf, parameters.getSalt(), parameters.getIterationCount(),
|
||||
dkLen);
|
||||
return r;
|
||||
}
|
||||
|
||||
public boolean verifyKey(String inputPassword)
|
||||
{
|
||||
byte[] referenceKey = getParameters().getDerivedKey();
|
||||
if (referenceKey == null || referenceKey.length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
byte[] inputKey = deriveKey(inputPassword, referenceKey.length);
|
||||
|
||||
if (inputKey == null || inputKey.length != referenceKey.length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < inputKey.length; i++)
|
||||
{
|
||||
if (inputKey[i] != referenceKey[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method. Default implementation is (H)MAC-based. To be overridden
|
||||
* in derived classes.
|
||||
*
|
||||
* @param P
|
||||
* User-supplied candidate password as array of bytes.
|
||||
*/
|
||||
protected void assertPRF(byte[] P)
|
||||
{
|
||||
if (prf == null)
|
||||
{
|
||||
prf = new MacBasedPRF(parameters.getHashAlgorithm());
|
||||
}
|
||||
prf.init(P);
|
||||
}
|
||||
|
||||
public PRF getPseudoRandomFunction()
|
||||
{
|
||||
return prf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Core Password Based Key Derivation Function 2.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2</a>
|
||||
* @param prf
|
||||
* Pseudo Random Function (i.e. HmacSHA1)
|
||||
* @param S
|
||||
* Salt as array of bytes. <code>null</code> means no salt.
|
||||
* @param c
|
||||
* Iteration count (see RFC 2898 4.2)
|
||||
* @param dkLen
|
||||
* desired length of derived key.
|
||||
* @return internal byte array
|
||||
*/
|
||||
protected byte[] PBKDF2(PRF prf, byte[] S, int c, int dkLen)
|
||||
{
|
||||
if (S == null)
|
||||
{
|
||||
S = new byte[0];
|
||||
}
|
||||
int hLen = prf.getHLen();
|
||||
int l = ceil(dkLen, hLen);
|
||||
int r = dkLen - (l - 1) * hLen;
|
||||
byte T[] = new byte[l * hLen];
|
||||
int ti_offset = 0;
|
||||
for (int i = 1; i <= l; i++)
|
||||
{
|
||||
_F(T, ti_offset, prf, S, c, i);
|
||||
ti_offset += hLen;
|
||||
}
|
||||
if (r < hLen)
|
||||
{
|
||||
// Incomplete last block
|
||||
byte DK[] = new byte[dkLen];
|
||||
System.arraycopy(T, 0, DK, 0, dkLen);
|
||||
return DK;
|
||||
}
|
||||
return T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer division with ceiling function.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2 Step 2.</a>
|
||||
* @param a
|
||||
* @param b
|
||||
* @return ceil(a/b)
|
||||
*/
|
||||
protected int ceil(int a, int b)
|
||||
{
|
||||
int m = 0;
|
||||
if (a % b > 0)
|
||||
{
|
||||
m = 1;
|
||||
}
|
||||
return a / b + m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function F.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2 Step 3.</a>
|
||||
* @param dest
|
||||
* Destination byte buffer
|
||||
* @param offset
|
||||
* Offset into destination byte buffer
|
||||
* @param prf
|
||||
* Pseudo Random Function
|
||||
* @param S
|
||||
* Salt as array of bytes
|
||||
* @param c
|
||||
* Iteration count
|
||||
* @param blockIndex
|
||||
*/
|
||||
protected void _F(byte[] dest, int offset, PRF prf, byte[] S, int c,
|
||||
int blockIndex)
|
||||
{
|
||||
int hLen = prf.getHLen();
|
||||
byte U_r[] = new byte[hLen];
|
||||
|
||||
// U0 = S || INT (i);
|
||||
byte U_i[] = new byte[S.length + 4];
|
||||
System.arraycopy(S, 0, U_i, 0, S.length);
|
||||
INT(U_i, S.length, blockIndex);
|
||||
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
U_i = prf.doFinal(U_i);
|
||||
xor(U_r, U_i);
|
||||
}
|
||||
System.arraycopy(U_r, 0, dest, offset, hLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Block-Xor. Xor source bytes into destination byte buffer. Destination
|
||||
* buffer must be same length or less than source buffer.
|
||||
*
|
||||
* @param dest
|
||||
* @param src
|
||||
*/
|
||||
protected void xor(byte[] dest, byte[] src)
|
||||
{
|
||||
for (int i = 0; i < dest.length; i++)
|
||||
{
|
||||
dest[i] ^= src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Four-octet encoding of the integer i, most significant octet first.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc2898">RFC 2898 5.2 Step 3.</a>
|
||||
* @param dest
|
||||
* @param offset
|
||||
* @param i
|
||||
*/
|
||||
protected void INT(byte[] dest, int offset, int i)
|
||||
{
|
||||
dest[offset + 0] = (byte) (i / (256 * 256 * 256));
|
||||
dest[offset + 1] = (byte) (i / (256 * 256));
|
||||
dest[offset + 2] = (byte) (i / (256));
|
||||
dest[offset + 3] = (byte) (i);
|
||||
}
|
||||
|
||||
public PBKDF2Parameters getParameters()
|
||||
{
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(PBKDF2Parameters parameters)
|
||||
{
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
public void setPseudoRandomFunction(PRF prf)
|
||||
{
|
||||
this.prf = prf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience client function. Convert supplied password with random 8-byte
|
||||
* salt and 1000 iterations using HMacSHA1. Assume that password is in
|
||||
* ISO-8559-1 encoding. Output result as
|
||||
* "Salt:iteration-count:PBKDF2" with binary data in hexadecimal
|
||||
* encoding.
|
||||
*
|
||||
* Example: Password "password" (without the quotes) leads to
|
||||
* 48290A0B96C426C3:1000:973899B1D4AFEB3ED371060D0797E0EE0142BD04
|
||||
*
|
||||
* @param args
|
||||
* Supply the password as argument.
|
||||
* @throws IOException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException,
|
||||
NoSuchAlgorithmException
|
||||
{
|
||||
String password = "password";
|
||||
String candidate = null;
|
||||
PBKDF2Formatter formatter = new PBKDF2HexFormatter();
|
||||
|
||||
if (args.length >= 1)
|
||||
{
|
||||
password = args[0];
|
||||
}
|
||||
if (args.length >= 2)
|
||||
{
|
||||
candidate = args[1];
|
||||
}
|
||||
if (candidate == null)
|
||||
{
|
||||
// Creation mode
|
||||
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
|
||||
byte[] salt = new byte[8];
|
||||
sr.nextBytes(salt);
|
||||
int iterations = 1000;
|
||||
PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA1", "ISO-8859-1",
|
||||
salt, iterations);
|
||||
PBKDF2Engine e = new PBKDF2Engine(p);
|
||||
p.setDerivedKey(e.deriveKey(password));
|
||||
candidate = formatter.toString(p);
|
||||
System.out.println(candidate);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Verification mode
|
||||
PBKDF2Parameters p = new PBKDF2Parameters();
|
||||
p.setHashAlgorithm("HmacSHA1");
|
||||
p.setHashCharset("ISO-8859-1");
|
||||
if (formatter.fromString(p, candidate))
|
||||
{
|
||||
throw new IllegalArgumentException(
|
||||
"Candidate data does not have correct format (\""
|
||||
+ candidate + "\")");
|
||||
}
|
||||
PBKDF2Engine e = new PBKDF2Engine(p);
|
||||
boolean verifyOK = e.verifyKey(password);
|
||||
System.out.println(verifyOK ? "OK" : "FAIL");
|
||||
System.exit(verifyOK ? 0 : 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface PBKDF2Formatter
|
||||
{
|
||||
/**
|
||||
* Convert parameters to String.
|
||||
*
|
||||
* @param p
|
||||
* Parameters object to output.
|
||||
* @return String representation
|
||||
*/
|
||||
public abstract String toString(PBKDF2Parameters p);
|
||||
|
||||
/**
|
||||
* Convert String to parameters. Depending on actual implementation, it may
|
||||
* be required to set further fields externally.
|
||||
*
|
||||
* @param s
|
||||
* String representation of parameters to decode.
|
||||
* @return <code>false</code> syntax OK, <code>true</code> some syntax
|
||||
* issue.
|
||||
*/
|
||||
public abstract boolean fromString(PBKDF2Parameters p, String s);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PBKDF2HexFormatter implements PBKDF2Formatter
|
||||
{
|
||||
public boolean fromString(PBKDF2Parameters p, String s)
|
||||
{
|
||||
if (p == null || s == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
String[] p123 = s.split(":");
|
||||
if (p123 == null || p123.length != 3)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
byte salt[] = BinTools.hex2bin(p123[0]);
|
||||
int iterationCount = Integer.parseInt(p123[1]);
|
||||
byte bDK[] = BinTools.hex2bin(p123[2]);
|
||||
|
||||
p.setSalt(salt);
|
||||
p.setIterationCount(iterationCount);
|
||||
p.setDerivedKey(bDK);
|
||||
return false;
|
||||
}
|
||||
|
||||
public String toString(PBKDF2Parameters p)
|
||||
{
|
||||
String s = BinTools.bin2hex(p.getSalt()) + ":"
|
||||
+ String.valueOf(p.getIterationCount()) + ":"
|
||||
+ BinTools.bin2hex(p.getDerivedKey());
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Parameter data holder for PBKDF2 configuration.
|
||||
* </p>
|
||||
*
|
||||
* <hr />
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PBKDF2Parameters
|
||||
{
|
||||
protected byte[] salt;
|
||||
|
||||
protected int iterationCount;
|
||||
|
||||
protected String hashAlgorithm;
|
||||
|
||||
protected String hashCharset;
|
||||
|
||||
/**
|
||||
* The derived key is actually only a convenience to store a reference
|
||||
* derived key. It is not used during computation.
|
||||
*/
|
||||
protected byte[] derivedKey;
|
||||
|
||||
/**
|
||||
* Constructor. Defaults to <code>null</code> for byte arrays, UTF-8 as
|
||||
* character set and 1000 for iteration count.
|
||||
*
|
||||
*/
|
||||
public PBKDF2Parameters()
|
||||
{
|
||||
this.hashAlgorithm = null;
|
||||
this.hashCharset = "UTF-8";
|
||||
this.salt = null;
|
||||
this.iterationCount = 1000;
|
||||
this.derivedKey = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param hashAlgorithm
|
||||
* for example HMacSHA1 or HMacMD5
|
||||
* @param hashCharset
|
||||
* for example UTF-8
|
||||
* @param salt
|
||||
* Salt as byte array, may be <code>null</code> (not
|
||||
* recommended)
|
||||
* @param iterationCount
|
||||
* Number of iterations to execute. Recommended value 1000.
|
||||
*/
|
||||
public PBKDF2Parameters(String hashAlgorithm, String hashCharset,
|
||||
byte[] salt, int iterationCount)
|
||||
{
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.hashCharset = hashCharset;
|
||||
this.salt = salt;
|
||||
this.iterationCount = iterationCount;
|
||||
this.derivedKey = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param hashAlgorithm
|
||||
* for example HMacSHA1 or HMacMD5
|
||||
* @param hashCharset
|
||||
* for example UTF-8
|
||||
* @param salt
|
||||
* Salt as byte array, may be <code>null</code> (not
|
||||
* recommended)
|
||||
* @param iterationCount
|
||||
* Number of iterations to execute. Recommended value 1000.
|
||||
* @param derivedKey
|
||||
* Convenience data holder, not used during computation.
|
||||
*/
|
||||
public PBKDF2Parameters(String hashAlgorithm, String hashCharset,
|
||||
byte[] salt, int iterationCount, byte[] derivedKey)
|
||||
{
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
this.hashCharset = hashCharset;
|
||||
this.salt = salt;
|
||||
this.iterationCount = iterationCount;
|
||||
this.derivedKey = derivedKey;
|
||||
}
|
||||
|
||||
public int getIterationCount()
|
||||
{
|
||||
return iterationCount;
|
||||
}
|
||||
|
||||
public void setIterationCount(int iterationCount)
|
||||
{
|
||||
this.iterationCount = iterationCount;
|
||||
}
|
||||
|
||||
public byte[] getSalt()
|
||||
{
|
||||
return salt;
|
||||
}
|
||||
|
||||
public void setSalt(byte[] salt)
|
||||
{
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
public byte[] getDerivedKey()
|
||||
{
|
||||
return derivedKey;
|
||||
}
|
||||
|
||||
public void setDerivedKey(byte[] derivedKey)
|
||||
{
|
||||
this.derivedKey = derivedKey;
|
||||
}
|
||||
|
||||
public String getHashAlgorithm()
|
||||
{
|
||||
return hashAlgorithm;
|
||||
}
|
||||
|
||||
public void setHashAlgorithm(String hashAlgorithm)
|
||||
{
|
||||
this.hashAlgorithm = hashAlgorithm;
|
||||
}
|
||||
|
||||
public String getHashCharset()
|
||||
{
|
||||
return hashCharset;
|
||||
}
|
||||
|
||||
public void setHashCharset(String hashCharset)
|
||||
{
|
||||
this.hashCharset = hashCharset;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package fr.xephi.authme.security.pbkdf2;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A free Java implementation of Password Based Key Derivation Function 2 as
|
||||
* defined by RFC 2898. Copyright (c) 2007 Matthias Gärtner
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 2.1 of the License, or (at your option)
|
||||
* any later version.
|
||||
* </p>
|
||||
* <p>
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
* details.
|
||||
* </p>
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
* </p>
|
||||
* <p>
|
||||
* For Details, see <a
|
||||
* href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Matthias Gärtner
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface PRF
|
||||
{
|
||||
/**
|
||||
* Initialize this instance with the user-supplied password.
|
||||
*
|
||||
* @param P
|
||||
* The password supplied as array of bytes. It is the caller's
|
||||
* task to convert String passwords to bytes as appropriate.
|
||||
*/
|
||||
public void init(byte[] P);
|
||||
|
||||
/**
|
||||
* Pseudo Random Function
|
||||
*
|
||||
* @param M
|
||||
* Input data/message etc. Together with any data supplied during
|
||||
* initilization.
|
||||
* @return Random bytes of hLen length.
|
||||
*/
|
||||
public byte[] doFinal(byte[] M);
|
||||
|
||||
/**
|
||||
* Query block size of underlying algorithm/mechanism.
|
||||
*
|
||||
* @return block size
|
||||
*/
|
||||
public int getHLen();
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class CustomConfiguration extends YamlConfiguration{
|
||||
|
||||
private File configFile;
|
||||
|
||||
public CustomConfiguration(File file)
|
||||
{
|
||||
this.configFile = file;
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
try {
|
||||
super.load(configFile);
|
||||
} catch (FileNotFoundException e) {
|
||||
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, "Could not find " + configFile.getName() + ", creating new one...");
|
||||
reLoad();
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, "Could not load " + configFile.getName(), e);
|
||||
} catch (InvalidConfigurationException e) {
|
||||
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, configFile.getName() + " is no valid configuration file", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean reLoad() {
|
||||
boolean out = true;
|
||||
if (!configFile.exists())
|
||||
{
|
||||
out = loadRessource(configFile);
|
||||
}
|
||||
if (out) load();
|
||||
return out;
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
super.save(configFile);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, "Could not save config to " + configFile.getName(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean loadRessource(File file) {
|
||||
boolean out = true;
|
||||
if (!file.exists()) {
|
||||
InputStream fis = getClass().getResourceAsStream("/" + file.getName());
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(file);
|
||||
byte[] buf = new byte[1024];
|
||||
int i = 0;
|
||||
while ((i = fis.read(buf)) != -1) {
|
||||
fos.write(buf, 0, i);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(JavaPlugin.class.getName()).log(Level.SEVERE, "Failed to load config from JAR");
|
||||
out = false;
|
||||
} finally {
|
||||
try {
|
||||
if (fis != null) {
|
||||
fis.close();
|
||||
}
|
||||
if (fos != null) {
|
||||
fos.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class Messages extends CustomConfiguration {
|
||||
|
||||
private static Messages singleton = null;
|
||||
|
||||
public Messages() {
|
||||
super(new File(Settings.MESSAGE_FILE+"_"+Settings.messagesLanguage+".yml"));
|
||||
loadDefaults();
|
||||
loadFile();
|
||||
singleton = this;
|
||||
}
|
||||
|
||||
private void loadDefaults() {
|
||||
this.set("logged_in", "&cAlready logged in!");
|
||||
this.set("not_logged_in", "&cNot logged in!");
|
||||
this.set("reg_disabled", "&cRegistration is disabled");
|
||||
this.set("user_regged", "&cUsername already registered");
|
||||
this.set("usage_reg", "&cUsage: /register password ConfirmPassword");
|
||||
this.set("usage_log", "&cUsage: /login password");
|
||||
this.set("user_unknown", "&cUsername not registered");
|
||||
this.set("pwd_changed", "&cPassword changed!");
|
||||
this.set("reg_only", "&fRegistered players only! Please visit http://example.com to register");
|
||||
this.set("valid_session", "&cSession login");
|
||||
this.set("login_msg", "&cPlease login with \"/login password\"");
|
||||
this.set("reg_msg", "&cPlease register with \"/register password ConfirmPassword\"");
|
||||
this.set("reg_email_msg", "&cPlease register with \"/register <email> <confirmEmail>\"");
|
||||
this.set("timeout", "&fLogin Timeout");
|
||||
this.set("wrong_pwd", "&cWrong password");
|
||||
this.set("logout", "&cSuccessful logout");
|
||||
this.set("usage_unreg", "&cUsage: /unregister password");
|
||||
this.set("registered", "&cSuccessfully registered!");
|
||||
this.set("unregistered", "&cSuccessfully unregistered!");
|
||||
this.set("login", "&cSuccessful login!");
|
||||
this.set("no_perm", "&cNo Permission");
|
||||
this.set("same_nick", "&fSame nick is already playing");
|
||||
this.set("reg_voluntarily", "&fYou can register your nickname with the server with the command \"/register password ConfirmPassword\"");
|
||||
this.set("reload", "&fConfiguration and database has been reloaded");
|
||||
this.set("error", "&fAn error ocurred; Please contact the admin");
|
||||
this.set("unknown_user", "&fUser is not in database");
|
||||
this.set("unsafe_spawn","&fYour Quit location was unsafe, teleporting you to World Spawn");
|
||||
this.set("unvalid_session","&fSession Dataes doesnt corrispond Plaese wait the end of session");
|
||||
this.set("max_reg","&fYou have Exceded the max number of Registration for your Account");
|
||||
this.set("password_error","&fPassword doesnt match");
|
||||
this.set("pass_len","&fYour password dind''t reach the minimum length or exeded the max length");
|
||||
this.set("vb_nonActiv","&fYour Account isent Activated yet check your Emails!");
|
||||
this.set("usage_changepassword", "&fUsage: /changepassword oldPassword newPassword");
|
||||
this.set("name_len", "&cYour nickname is too Short or too long");
|
||||
this.set("regex", "&cYour nickname contains illegal characters. Allowed chars: REG_EX");
|
||||
this.set("add_email","&cPlease add your email with : /email add yourEmail confirmEmail");
|
||||
this.set("bad_database_email", "[AuthMe] This /email command only available with MySQL and SQLite, contact an Admin");
|
||||
this.set("recovery_email", "&cForgot your password? Please use /email recovery <yourEmail>");
|
||||
this.set("usage_captcha", "&cUsage: /captcha <theCaptcha>");
|
||||
this.set("wrong_captcha", "&cWrong Captcha, please use : /captcha THE_CAPTCHA");
|
||||
this.set("valid_captcha", "&cYour captcha is valid !");
|
||||
this.set("kick_forvip", "&cA VIP Player join the full server!");
|
||||
this.set("kick_fullserver", "&cThe server is actually full, Sorry!");
|
||||
this.set("usage_email_add", "&fUsage: /email add <Email> <confirmEmail> ");
|
||||
this.set("usage_email_change", "&Usage: /email change <old> <new> ");
|
||||
this.set("usage_email_recovery", "&Usage: /email recovery <Email>");
|
||||
this.set("email_add", "[AuthMe] /email add <Email> <confirmEmail>");
|
||||
this.set("new_email_invalid", "[AuthMe] New email invalid!");
|
||||
this.set("old_email_invalid", "[AuthMe] Old email invalid!");
|
||||
this.set("email_invalid", "[AuthMe] Invalid Email !");
|
||||
this.set("email_added", "[AuthMe] Email Added !");
|
||||
this.set("email_confirm", "[AuthMe] Confirm your Email !");
|
||||
this.set("email_changed", "[AuthMe] Email Change !");
|
||||
this.set("email_send", "[AuthMe] Recovery Email Send !");
|
||||
}
|
||||
|
||||
private void loadFile() {
|
||||
this.load();
|
||||
this.save();
|
||||
}
|
||||
|
||||
public String _(String msg) {
|
||||
String loc = (String) this.get(msg);
|
||||
if (loc != null) {
|
||||
return loc.replace("&", "\u00a7");
|
||||
}
|
||||
if (loc == null && !contains(msg)) {
|
||||
set(msg, this.getDefault(msg));
|
||||
save();
|
||||
loc = (String) this.get(msg);
|
||||
}
|
||||
if (loc == null)
|
||||
return "Error with Translation files; Please contact the admin";
|
||||
return loc.replace("&", "\u00a7");
|
||||
}
|
||||
|
||||
public static Messages getInstance() {
|
||||
if (singleton == null) {
|
||||
singleton = new Messages();
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class PlayersLogs extends CustomConfiguration {
|
||||
private static PlayersLogs pllog = null;
|
||||
public static List<String> players;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public PlayersLogs() {
|
||||
super(new File("./plugins/AuthMe/players.yml"));
|
||||
pllog = this;
|
||||
load();
|
||||
save();
|
||||
players = (List<String>) this.getList("players");
|
||||
}
|
||||
|
||||
public static PlayersLogs getInstance() {
|
||||
if (pllog == null) {
|
||||
pllog = new PlayersLogs();
|
||||
}
|
||||
return pllog;
|
||||
}
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
List<String> players = this.getStringList("players");
|
||||
if (!players.contains(player.getName())) {
|
||||
players.add(player.getName());
|
||||
this.set("players", players);
|
||||
save();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,611 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.configuration.MemoryConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSource.DataSourceType;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
|
||||
|
||||
public final class Settings extends YamlConfiguration {
|
||||
|
||||
public static final String PLUGIN_FOLDER = "./plugins/AuthMe";
|
||||
public static final String CACHE_FOLDER = Settings.PLUGIN_FOLDER + "/cache";
|
||||
public static final String AUTH_FILE = Settings.PLUGIN_FOLDER + "/auths.db";
|
||||
public static final String MESSAGE_FILE = Settings.PLUGIN_FOLDER + "/messages";
|
||||
public static final String SETTINGS_FILE = Settings.PLUGIN_FOLDER + "/config.yml";
|
||||
public static List<String> allowCommands = null;
|
||||
public static List<String> getJoinPermissions = null;
|
||||
public static List<String> getUnrestrictedName = null;
|
||||
private static List<String> getRestrictedIp;
|
||||
public static List<String> getMySQLOtherUsernameColumn = null;
|
||||
public static List<String> getForcedWorlds = null;
|
||||
public final Plugin plugin;
|
||||
private final File file;
|
||||
public static DataSourceType getDataSource;
|
||||
public static HashAlgorithm getPasswordHash;
|
||||
public static HashAlgorithm rakamakHash;
|
||||
public static Boolean useLogging = false;
|
||||
|
||||
public static Boolean isPermissionCheckEnabled, isRegistrationEnabled, isForcedRegistrationEnabled,
|
||||
isTeleportToSpawnEnabled, isSessionsEnabled, isChatAllowed, isAllowRestrictedIp,
|
||||
isMovementAllowed, isKickNonRegisteredEnabled, isForceSingleSessionEnabled,
|
||||
isForceSpawnLocOnJoinEnabled, isForceExactSpawnEnabled, isSaveQuitLocationEnabled,
|
||||
isForceSurvivalModeEnabled, isResetInventoryIfCreative, isCachingEnabled, isKickOnWrongPasswordEnabled,
|
||||
getEnablePasswordVerifier, protectInventoryBeforeLogInEnabled, isBackupActivated, isBackupOnStart,
|
||||
isBackupOnStop, enablePasspartu, isStopEnabled, reloadSupport, rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts,
|
||||
useCaptcha, emailRegistration, multiverse, notifications, chestshop, bungee, banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange,
|
||||
disableSocialSpy, useMultiThreading, forceOnlyAfterLogin, useEssentialsMotd,
|
||||
usePurge, purgePlayerDat, purgeEssentialsFile, supportOldPassword;
|
||||
|
||||
public static String getNickRegex, getUnloggedinGroup, getMySQLHost, getMySQLPort,
|
||||
getMySQLUsername, getMySQLPassword, getMySQLDatabase, getMySQLTablename,
|
||||
getMySQLColumnName, getMySQLColumnPassword, getMySQLColumnIp, getMySQLColumnLastLogin,
|
||||
getMySQLColumnSalt, getMySQLColumnGroup, getMySQLColumnEmail, unRegisteredGroup, backupWindowsPath,
|
||||
getcUnrestrictedName, getRegisteredGroup, messagesLanguage, getMySQLlastlocX, getMySQLlastlocY, getMySQLlastlocZ,
|
||||
rakamakUsers, rakamakUsersIp, getmailAccount, getmailPassword, getmailSMTP, getMySQLColumnId, getmailSenderName,
|
||||
getMailSubject, getMailText, getMySQLlastlocWorld, defaultWorld,
|
||||
getPhpbbPrefix, getWordPressPrefix;
|
||||
|
||||
public static int getWarnMessageInterval, getSessionTimeout, getRegistrationTimeout, getMaxNickLength,
|
||||
getMinNickLength, getPasswordMinLen, getMovementRadius, getmaxRegPerIp, getNonActivatedGroup,
|
||||
passwordMaxLength, getRecoveryPassLength, getMailPort, maxLoginTry, captchaLength, saltLength, getmaxRegPerEmail,
|
||||
bCryptLog2Rounds, purgeDelay, getPhpbbGroup;
|
||||
|
||||
protected static YamlConfiguration configFile;
|
||||
|
||||
public Settings(Plugin plugin) {
|
||||
this.file = new File(plugin.getDataFolder(),"config.yml");
|
||||
this.plugin = plugin;
|
||||
if(exists()) {
|
||||
load();
|
||||
}
|
||||
else {
|
||||
loadDefaults(file.getName());
|
||||
load();
|
||||
}
|
||||
configFile = (YamlConfiguration) plugin.getConfig();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void loadConfigOptions() {
|
||||
plugin.getLogger().info("Loading Configuration File...");
|
||||
mergeConfig();
|
||||
|
||||
messagesLanguage = checkLang(configFile.getString("settings.messagesLanguage","en"));
|
||||
isPermissionCheckEnabled = configFile.getBoolean("permission.EnablePermissionCheck", false);
|
||||
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
|
||||
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
|
||||
isTeleportToSpawnEnabled = configFile.getBoolean("settings.restrictions.teleportUnAuthedToSpawn",false);
|
||||
getWarnMessageInterval = configFile.getInt("settings.registration.messageInterval",5);
|
||||
isSessionsEnabled = configFile.getBoolean("settings.sessions.enabled",false);
|
||||
getSessionTimeout = configFile.getInt("settings.sessions.timeout",10);
|
||||
getRegistrationTimeout = configFile.getInt("settings.restrictions.timeout",30);
|
||||
isChatAllowed = configFile.getBoolean("settings.restrictions.allowChat",false);
|
||||
getMaxNickLength = configFile.getInt("settings.restrictions.maxNicknameLength",20);
|
||||
getMinNickLength = configFile.getInt("settings.restrictions.minNicknameLength",3);
|
||||
getPasswordMinLen = configFile.getInt("settings.security.minPasswordLength",4);
|
||||
getNickRegex = configFile.getString("settings.restrictions.allowedNicknameCharacters","[a-zA-Z0-9_?]*");
|
||||
isAllowRestrictedIp = configFile.getBoolean("settings.restrictions.AllowRestrictedUser",false);
|
||||
getRestrictedIp = configFile.getStringList("settings.restrictions.AllowedRestrictedUser");
|
||||
isMovementAllowed = configFile.getBoolean("settings.restrictions.allowMovement",false);
|
||||
getMovementRadius = configFile.getInt("settings.restrictions.allowedMovementRadius",100);
|
||||
getJoinPermissions = configFile.getStringList("GroupOptions.Permissions.PermissionsOnJoin");
|
||||
isKickOnWrongPasswordEnabled = configFile.getBoolean("settings.restrictions.kickOnWrongPassword",false);
|
||||
isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered",false);
|
||||
isForceSingleSessionEnabled = configFile.getBoolean("settings.restrictions.ForceSingleSession",true);
|
||||
isForceSpawnLocOnJoinEnabled = configFile.getBoolean("settings.restrictions.ForceSpawnLocOnJoinEnabled",false);
|
||||
isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation", false);
|
||||
isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode", false);
|
||||
isResetInventoryIfCreative = configFile.getBoolean("settings.GameMode.ResetInventoryIfCreative",false);
|
||||
getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp",1);
|
||||
getPasswordHash = getPasswordHash();
|
||||
getUnloggedinGroup = configFile.getString("settings.security.unLoggedinGroup","unLoggedInGroup");
|
||||
getDataSource = getDataSource();
|
||||
isCachingEnabled = configFile.getBoolean("DataSource.caching",true);
|
||||
getMySQLHost = configFile.getString("DataSource.mySQLHost","127.0.0.1");
|
||||
getMySQLPort = configFile.getString("DataSource.mySQLPort","3306");
|
||||
getMySQLUsername = configFile.getString("DataSource.mySQLUsername","authme");
|
||||
getMySQLPassword = configFile.getString("DataSource.mySQLPassword","12345");
|
||||
getMySQLDatabase = configFile.getString("DataSource.mySQLDatabase","authme");
|
||||
getMySQLTablename = configFile.getString("DataSource.mySQLTablename","authme");
|
||||
getMySQLColumnEmail = configFile.getString("DataSource.mySQLColumnEmail","email");
|
||||
getMySQLColumnName = configFile.getString("DataSource.mySQLColumnName","username");
|
||||
getMySQLColumnPassword = configFile.getString("DataSource.mySQLColumnPassword","password");
|
||||
getMySQLColumnIp = configFile.getString("DataSource.mySQLColumnIp","ip");
|
||||
getMySQLColumnLastLogin = configFile.getString("DataSource.mySQLColumnLastLogin","lastlogin");
|
||||
getMySQLColumnSalt = configFile.getString("ExternalBoardOptions.mySQLColumnSalt");
|
||||
getMySQLColumnGroup = configFile.getString("ExternalBoardOptions.mySQLColumnGroup","");
|
||||
getMySQLlastlocX = configFile.getString("DataSource.mySQLlastlocX","x");
|
||||
getMySQLlastlocY = configFile.getString("DataSource.mySQLlastlocY","y");
|
||||
getMySQLlastlocZ = configFile.getString("DataSource.mySQLlastlocZ","z");
|
||||
getMySQLlastlocWorld = configFile.getString("DataSource.mySQLlastlocWorld", "world");
|
||||
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
|
||||
unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup","");
|
||||
getUnrestrictedName = configFile.getStringList("settings.unrestrictions.UnrestrictedName");
|
||||
getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup","");
|
||||
getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier" , true);
|
||||
protectInventoryBeforeLogInEnabled = configFile.getBoolean("settings.restrictions.ProtectInventoryBeforeLogIn", true);
|
||||
passwordMaxLength = configFile.getInt("settings.security.passwordMaxLength", 20);
|
||||
isBackupActivated = configFile.getBoolean("BackupSystem.ActivateBackup",false);
|
||||
isBackupOnStart = configFile.getBoolean("BackupSystem.OnServerStart",false);
|
||||
isBackupOnStop = configFile.getBoolean("BackupSystem.OnServeStop",false);
|
||||
backupWindowsPath = configFile.getString("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||
enablePasspartu = configFile.getBoolean("Passpartu.enablePasspartu",false);
|
||||
isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
|
||||
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
allowCommands = (List<String>) configFile.getList("settings.restrictions.allowCommands");
|
||||
if (configFile.contains("allowCommands")) {
|
||||
if (!allowCommands.contains("/login"))
|
||||
allowCommands.add("/login");
|
||||
if (!allowCommands.contains("/register"))
|
||||
allowCommands.add("/register");
|
||||
if (!allowCommands.contains("/l"))
|
||||
allowCommands.add("/l");
|
||||
if (!allowCommands.contains("/reg"))
|
||||
allowCommands.add("/reg");
|
||||
if (!allowCommands.contains("/passpartu"))
|
||||
allowCommands.add("/passpartu");
|
||||
if (!allowCommands.contains("/email"))
|
||||
allowCommands.add("/email");
|
||||
if(!allowCommands.contains("/captcha"))
|
||||
allowCommands.add("/captcha");
|
||||
}
|
||||
rakamakUsers = configFile.getString("Converter.Rakamak.fileName", "users.rak");
|
||||
rakamakUsersIp = configFile.getString("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
rakamakUseIp = configFile.getBoolean("Converter.Rakamak.useIp", false);
|
||||
rakamakHash = getRakamakHash();
|
||||
noConsoleSpam = configFile.getBoolean("Security.console.noConsoleSpam", false);
|
||||
removePassword = configFile.getBoolean("Security.console.removePassword", true);
|
||||
getmailAccount = configFile.getString("Email.mailAccount", "");
|
||||
getmailPassword = configFile.getString("Email.mailPassword", "");
|
||||
getmailSMTP = configFile.getString("Email.mailSMTP", "smtp.gmail.com");
|
||||
getMailPort = configFile.getInt("Email.mailPort", 465);
|
||||
getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
|
||||
getMySQLOtherUsernameColumn = (List<String>) configFile.getList("ExternalBoardOptions.mySQLOtherUsernameColumns", new ArrayList<String>());
|
||||
displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
|
||||
getMySQLColumnId = configFile.getString("DataSource.mySQLColumnId", "id");
|
||||
getmailSenderName = configFile.getString("Email.mailSenderName", "");
|
||||
useCaptcha = configFile.getBoolean("Security.captcha.useCaptcha", false);
|
||||
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
|
||||
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
|
||||
getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password");
|
||||
getMailText = configFile.getString("Email.mailText", "Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword");
|
||||
emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
|
||||
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
|
||||
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
|
||||
multiverse = configFile.getBoolean("Hooks.multiverse", true);
|
||||
chestshop = configFile.getBoolean("Hooks.chestshop", true);
|
||||
notifications = configFile.getBoolean("Hooks.notifications", true);
|
||||
bungee = configFile.getBoolean("Hooks.bungeecord", false);
|
||||
getForcedWorlds = (List<String>) configFile.getList("settings.restrictions.ForceSpawnOnTheseWorlds");
|
||||
banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false);
|
||||
doubleEmailCheck = configFile.getBoolean("settings.registration.doubleEmailCheck", false);
|
||||
sessionExpireOnIpChange = configFile.getBoolean("settings.sessions.sessionExpireOnIpChange", false);
|
||||
useLogging = configFile.getBoolean("Security.console.logConsole", false);
|
||||
disableSocialSpy = configFile.getBoolean("Hooks.disableSocialSpy", true);
|
||||
useMultiThreading = configFile.getBoolean("Performances.useMultiThreading", true);
|
||||
bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10);
|
||||
forceOnlyAfterLogin = configFile.getBoolean("settings.GameMode.ForceOnlyAfterLogin", false);
|
||||
useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false);
|
||||
usePurge = configFile.getBoolean("Purge.useAutoPurge", false);
|
||||
purgeDelay = configFile.getInt("Purge.daysBeforeRemovePlayer", 60);
|
||||
purgePlayerDat = configFile.getBoolean("Purge.removePlayerDat", false);
|
||||
purgeEssentialsFile = configFile.getBoolean("Purge.removeEssentialsFile", false);
|
||||
defaultWorld = configFile.getString("Purge.defaultWorld", "world");
|
||||
getPhpbbPrefix = configFile.getString("ExternalBoardOptions.phpbbTablePrefix", "phpbb_");
|
||||
getPhpbbGroup = configFile.getInt("ExternalBoardOptions.phpbbActivatedGroupId", 2);
|
||||
supportOldPassword = configFile.getBoolean("settings.security.supportOldPasswordHash", false);
|
||||
getWordPressPrefix = configFile.getString("ExternalBoardOptions.wordpressTablePrefix", "wp_");
|
||||
|
||||
saveDefaults();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void reloadConfigOptions(YamlConfiguration newConfig) {
|
||||
configFile = newConfig;
|
||||
|
||||
messagesLanguage = checkLang(configFile.getString("settings.messagesLanguage","en"));
|
||||
isPermissionCheckEnabled = configFile.getBoolean("permission.EnablePermissionCheck", false);
|
||||
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
|
||||
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
|
||||
isTeleportToSpawnEnabled = configFile.getBoolean("settings.restrictions.teleportUnAuthedToSpawn",false);
|
||||
getWarnMessageInterval = configFile.getInt("settings.registration.messageInterval",5);
|
||||
isSessionsEnabled = configFile.getBoolean("settings.sessions.enabled",false);
|
||||
getSessionTimeout = configFile.getInt("settings.sessions.timeout",10);
|
||||
getRegistrationTimeout = configFile.getInt("settings.restrictions.timeout",30);
|
||||
isChatAllowed = configFile.getBoolean("settings.restrictions.allowChat",false);
|
||||
getMaxNickLength = configFile.getInt("settings.restrictions.maxNicknameLength",20);
|
||||
getMinNickLength = configFile.getInt("settings.restrictions.minNicknameLength",3);
|
||||
getPasswordMinLen = configFile.getInt("settings.security.minPasswordLength",4);
|
||||
getNickRegex = configFile.getString("settings.restrictions.allowedNicknameCharacters","[a-zA-Z0-9_?]*");
|
||||
isAllowRestrictedIp = configFile.getBoolean("settings.restrictions.AllowRestrictedUser",false);
|
||||
getRestrictedIp = configFile.getStringList("settings.restrictions.AllowedRestrictedUser");
|
||||
isMovementAllowed = configFile.getBoolean("settings.restrictions.allowMovement",false);
|
||||
getMovementRadius = configFile.getInt("settings.restrictions.allowedMovementRadius",100);
|
||||
getJoinPermissions = configFile.getStringList("GroupOptions.Permissions.PermissionsOnJoin");
|
||||
isKickOnWrongPasswordEnabled = configFile.getBoolean("settings.restrictions.kickOnWrongPassword",false);
|
||||
isKickNonRegisteredEnabled = configFile.getBoolean("settings.restrictions.kickNonRegistered",false);
|
||||
isForceSingleSessionEnabled = configFile.getBoolean("settings.restrictions.ForceSingleSession",true);
|
||||
isForceSpawnLocOnJoinEnabled = configFile.getBoolean("settings.restrictions.ForceSpawnLocOnJoinEnabled",false);
|
||||
isSaveQuitLocationEnabled = configFile.getBoolean("settings.restrictions.SaveQuitLocation",false);
|
||||
isForceSurvivalModeEnabled = configFile.getBoolean("settings.GameMode.ForceSurvivalMode",false);
|
||||
isResetInventoryIfCreative = configFile.getBoolean("settings.GameMode.ResetInventoryIfCreative",false);
|
||||
getmaxRegPerIp = configFile.getInt("settings.restrictions.maxRegPerIp",1);
|
||||
getPasswordHash = getPasswordHash();
|
||||
getUnloggedinGroup = configFile.getString("settings.security.unLoggedinGroup","unLoggedInGroup");
|
||||
getDataSource = getDataSource();
|
||||
isCachingEnabled = configFile.getBoolean("DataSource.caching",true);
|
||||
getMySQLHost = configFile.getString("DataSource.mySQLHost","127.0.0.1");
|
||||
getMySQLPort = configFile.getString("DataSource.mySQLPort","3306");
|
||||
getMySQLUsername = configFile.getString("DataSource.mySQLUsername","authme");
|
||||
getMySQLPassword = configFile.getString("DataSource.mySQLPassword","12345");
|
||||
getMySQLDatabase = configFile.getString("DataSource.mySQLDatabase","authme");
|
||||
getMySQLTablename = configFile.getString("DataSource.mySQLTablename","authme");
|
||||
getMySQLColumnEmail = configFile.getString("DataSource.mySQLColumnEmail","email");
|
||||
getMySQLColumnName = configFile.getString("DataSource.mySQLColumnName","username");
|
||||
getMySQLColumnPassword = configFile.getString("DataSource.mySQLColumnPassword","password");
|
||||
getMySQLColumnIp = configFile.getString("DataSource.mySQLColumnIp","ip");
|
||||
getMySQLColumnLastLogin = configFile.getString("DataSource.mySQLColumnLastLogin","lastlogin");
|
||||
getMySQLlastlocX = configFile.getString("DataSource.mySQLlastlocX","x");
|
||||
getMySQLlastlocY = configFile.getString("DataSource.mySQLlastlocY","y");
|
||||
getMySQLlastlocZ = configFile.getString("DataSource.mySQLlastlocZ","z");
|
||||
getMySQLlastlocWorld = configFile.getString("DataSource.mySQLlastlocWorld", "world");
|
||||
getMySQLColumnSalt = configFile.getString("ExternalBoardOptions.mySQLColumnSalt","");
|
||||
getMySQLColumnGroup = configFile.getString("ExternalBoardOptions.mySQLColumnGroup","");
|
||||
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
|
||||
unRegisteredGroup = configFile.getString("GroupOptions.UnregisteredPlayerGroup","");
|
||||
getUnrestrictedName = configFile.getStringList("settings.unrestrictions.UnrestrictedName");
|
||||
getRegisteredGroup = configFile.getString("GroupOptions.RegisteredPlayerGroup","");
|
||||
getEnablePasswordVerifier = configFile.getBoolean("settings.restrictions.enablePasswordVerifier" , true);
|
||||
protectInventoryBeforeLogInEnabled = configFile.getBoolean("settings.restrictions.ProtectInventoryBeforeLogIn", true);
|
||||
passwordMaxLength = configFile.getInt("settings.security.passwordMaxLength", 20);
|
||||
isBackupActivated = configFile.getBoolean("BackupSystem.ActivateBackup",false);
|
||||
isBackupOnStart = configFile.getBoolean("BackupSystem.OnServerStart",false);
|
||||
isBackupOnStop = configFile.getBoolean("BackupSystem.OnServeStop",false);
|
||||
backupWindowsPath = configFile.getString("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||
enablePasspartu = configFile.getBoolean("Passpartu.enablePasspartu",false);
|
||||
isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
|
||||
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
allowCommands = (List<String>) configFile.getList("settings.restrictions.allowCommands");
|
||||
if (configFile.contains("allowCommands")) {
|
||||
if (!allowCommands.contains("/login"))
|
||||
allowCommands.add("/login");
|
||||
if (!allowCommands.contains("/register"))
|
||||
allowCommands.add("/register");
|
||||
if (!allowCommands.contains("/l"))
|
||||
allowCommands.add("/l");
|
||||
if (!allowCommands.contains("/reg"))
|
||||
allowCommands.add("/reg");
|
||||
if (!allowCommands.contains("/passpartu"))
|
||||
allowCommands.add("/passpartu");
|
||||
if (!allowCommands.contains("/email"))
|
||||
allowCommands.add("/email");
|
||||
if(!allowCommands.contains("/captcha"))
|
||||
allowCommands.add("/captcha");
|
||||
}
|
||||
rakamakUsers = configFile.getString("Converter.Rakamak.fileName", "users.rak");
|
||||
rakamakUsersIp = configFile.getString("Converter.Rakamak.ipFileName", "UsersIp.rak");
|
||||
rakamakUseIp = configFile.getBoolean("Converter.Rakamak.useIp", false);
|
||||
rakamakHash = getRakamakHash();
|
||||
noConsoleSpam = configFile.getBoolean("Security.console.noConsoleSpam", false);
|
||||
removePassword = configFile.getBoolean("Security.console.removePassword", true);
|
||||
getmailAccount = configFile.getString("Email.mailAccount", "");
|
||||
getmailPassword = configFile.getString("Email.mailPassword", "");
|
||||
getmailSMTP = configFile.getString("Email.mailSMTP", "smtp.gmail.com");
|
||||
getMailPort = configFile.getInt("Email.mailPort", 465);
|
||||
getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
|
||||
getMySQLOtherUsernameColumn = (List<String>) configFile.getList("ExternalBoardOptions.mySQLOtherUsernameColumns", new ArrayList<String>());
|
||||
displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
|
||||
getMySQLColumnId = configFile.getString("DataSource.mySQLColumnId", "id");
|
||||
getmailSenderName = configFile.getString("Email.mailSenderName", "");
|
||||
useCaptcha = configFile.getBoolean("Security.captcha.useCaptcha", false);
|
||||
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
|
||||
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
|
||||
getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password");
|
||||
getMailText = configFile.getString("Email.mailText", "Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword");
|
||||
emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
|
||||
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
|
||||
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
|
||||
multiverse = configFile.getBoolean("Hooks.multiverse", true);
|
||||
chestshop = configFile.getBoolean("Hooks.chestshop", true);
|
||||
notifications = configFile.getBoolean("Hooks.notifications", true);
|
||||
bungee = configFile.getBoolean("Hooks.bungeecord", false);
|
||||
getForcedWorlds = (List<String>) configFile.getList("settings.restrictions.ForceSpawnOnTheseWorlds");
|
||||
banUnsafeIp = configFile.getBoolean("settings.restrictions.banUnsafedIP", false);
|
||||
doubleEmailCheck = configFile.getBoolean("settings.registration.doubleEmailCheck", false);
|
||||
sessionExpireOnIpChange = configFile.getBoolean("settings.sessions.sessionExpireOnIpChange", false);
|
||||
useLogging = configFile.getBoolean("Security.console.logConsole", false);
|
||||
disableSocialSpy = configFile.getBoolean("Hooks.disableSocialSpy", true);
|
||||
useMultiThreading = configFile.getBoolean("Performances.useMultiThreading", true);
|
||||
bCryptLog2Rounds = configFile.getInt("ExternalBoardOptions.bCryptLog2Round", 10);
|
||||
forceOnlyAfterLogin = configFile.getBoolean("settings.GameMode.ForceOnlyAfterLogin", false);
|
||||
useEssentialsMotd = configFile.getBoolean("Hooks.useEssentialsMotd", false);
|
||||
usePurge = configFile.getBoolean("Purge.useAutoPurge", false);
|
||||
purgeDelay = configFile.getInt("Purge.daysBeforeRemovePlayer", 60);
|
||||
purgePlayerDat = configFile.getBoolean("Purge.removePlayerDat", false);
|
||||
purgeEssentialsFile = configFile.getBoolean("Purge.removeEssentialsFile", false);
|
||||
defaultWorld = configFile.getString("Purge.defaultWorld", "world");
|
||||
getPhpbbPrefix = configFile.getString("ExternalBoardOptions.phpbbTablePrefix", "phpbb_");
|
||||
getPhpbbGroup = configFile.getInt("ExternalBoardOptions.phpbbActivatedGroupId", 2);
|
||||
supportOldPassword = configFile.getBoolean("settings.security.supportOldPasswordHash", false);
|
||||
getWordPressPrefix = configFile.getString("ExternalBoardOptions.wordpressTablePrefix", "wp_");
|
||||
}
|
||||
|
||||
public void mergeConfig() {
|
||||
if(!contains("DataSource.mySQLColumnEmail"))
|
||||
set("DataSource.mySQLColumnEmail","email");
|
||||
if(!contains("Email.RecoveryPasswordLength"))
|
||||
set("Email.RecoveryPasswordLength", 8);
|
||||
if(!contains("Email.mailPort"))
|
||||
set("Email.mailPort", 465);
|
||||
if(!contains("Email.mailSMTP"))
|
||||
set("Email.mailSMTP", "smtp.gmail.com");
|
||||
if(!contains("Email.mailAccount"))
|
||||
set("Email.mailAccount", "");
|
||||
if(!contains("Email.mailPassword"))
|
||||
set("Email.mailPassword", "");
|
||||
if(!contains("ExternalBoardOptions.mySQLOtherUsernameColumns"))
|
||||
set("ExternalBoardOptions.mySQLOtherUsernameColumns", new ArrayList<String>());
|
||||
if(!contains("settings.restrictions.displayOtherAccounts"))
|
||||
set("settings.restrictions.displayOtherAccounts", true);
|
||||
if(!contains("DataSource.mySQLColumnId"))
|
||||
set("DataSource.mySQLColumnId", "id");
|
||||
if(!contains("Email.mailSenderName"))
|
||||
set("Email.mailSenderName", "");
|
||||
if(!contains("Security.captcha.useCaptcha"))
|
||||
set("Security.captcha.useCaptcha", false);
|
||||
if(!contains("Security.captcha.maxLoginTry"))
|
||||
set("Security.captcha.maxLoginTry", 5);
|
||||
if(!contains("Security.captcha.captchaLength"))
|
||||
set("Security.captcha.captchaLength", 5);
|
||||
if(!contains("Email.mailSubject"))
|
||||
set("Email.mailSubject", "");
|
||||
if(!contains("Email.mailText"))
|
||||
set("Email.mailText", "Dear <playername>, <br /><br /> This is your new AuthMe password for the server <br /><br /> <servername> : <br /><br /> <generatedpass><br /><br />Do not forget to change password after login! <br /> /changepassword <generatedpass> newPassword");
|
||||
if(contains("Email.mailText")) {
|
||||
try {
|
||||
String s = getString("Email.mailText");
|
||||
s = s.replaceAll("\n", "<br />");
|
||||
set("Email.mailText", null);
|
||||
set("Email.mailText", s);
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
if(!contains("settings.registration.enableEmailRegistrationSystem"))
|
||||
set("settings.registration.enableEmailRegistrationSystem", false);
|
||||
if(!contains("settings.security.doubleMD5SaltLength"))
|
||||
set("settings.security.doubleMD5SaltLength", 8);
|
||||
if(!contains("Email.maxRegPerEmail"))
|
||||
set("Email.maxRegPerEmail", 1);
|
||||
if(!contains("Hooks.multiverse")) {
|
||||
set("Hooks.multiverse", true);
|
||||
set("Hooks.chestshop", true);
|
||||
set("Hooks.notifications", true);
|
||||
set("Hooks.bungeecord", false);
|
||||
}
|
||||
if(!contains("settings.restrictions.ForceSpawnOnTheseWorlds"))
|
||||
set("settings.restrictions.ForceSpawnOnTheseWorlds", new ArrayList<String>());
|
||||
if(!contains("settings.restrictions.banUnsafedIP"))
|
||||
set("settings.restrictions.banUnsafedIP", false);
|
||||
if(!contains("settings.registration.doubleEmailCheck"))
|
||||
set("settings.registration.doubleEmailCheck", false);
|
||||
if(!contains("settings.sessions.sessionExpireOnIpChange"))
|
||||
set("settings.sessions.sessionExpireOnIpChange", false);
|
||||
if(!contains("Security.console.logConsole"))
|
||||
set("Security.console.logConsole", false);
|
||||
if(!contains("Hooks.disableSocialSpy"))
|
||||
set("Hooks.disableSocialSpy", true);
|
||||
if(!contains("Performances.useMultiThreading"))
|
||||
set("Performances.useMultiThreading", true);
|
||||
if(!contains("ExternalBoardOptions.bCryptLog2Round"))
|
||||
set("ExternalBoardOptions.bCryptLog2Round", 10);
|
||||
if(!contains("DataSource.mySQLlastlocWorld"))
|
||||
set("DataSource.mySQLlastlocWorld", "world");
|
||||
if(!contains("settings.GameMode.ForceOnlyAfterLogin"))
|
||||
set("settings.GameMode.ForceOnlyAfterLogin", false);
|
||||
if(!contains("Hooks.useEssentialsMotd"))
|
||||
set("Hooks.useEssentialsMotd", false);
|
||||
if(!contains("Purge.useAutoPurge")) {
|
||||
set("Purge.useAutoPurge", false);
|
||||
set("Purge.daysBeforeRemovePlayer", 60);
|
||||
set("Purge.removePlayerDat", false);
|
||||
set("Purge.removeEssentialsFile", false);
|
||||
set("Purge.defaultWorld", "world");
|
||||
}
|
||||
if(!contains("ExternalBoardOptions.phpbbTablePrefix")) {
|
||||
set("ExternalBoardOptions.phpbbTablePrefix", "phpbb_");
|
||||
set("ExternalBoardOptions.phpbbActivatedGroupId", 2);
|
||||
}
|
||||
if(!contains("settings.security.supportOldPasswordHash"))
|
||||
set("settings.security.supportOldPasswordHash", false);
|
||||
if(!contains("ExternalBoardOptions.wordpressTablePrefix"))
|
||||
set("ExternalBoardOptions.wordpressTablePrefix", "wp_");
|
||||
if(contains("Xenoforo.predefinedSalt"))
|
||||
set("Xenoforo.predefinedSalt", null);
|
||||
if(configFile.getString("settings.security.passwordHash","SHA256").toUpperCase().equals("XFSHA1") || configFile.getString("settings.security.passwordHash","SHA256").toUpperCase().equals("XFSHA256"))
|
||||
set("settings.security.passwordHash", "XENFORO");
|
||||
|
||||
plugin.getLogger().info("Merge new Config Options if needed..");
|
||||
plugin.saveConfig();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
private static HashAlgorithm getPasswordHash() {
|
||||
String key = "settings.security.passwordHash";
|
||||
try {
|
||||
return HashAlgorithm.valueOf(configFile.getString(key,"SHA256").toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
ConsoleLogger.showError("Unknown Hash Algorithm; defaulting to SHA256");
|
||||
return HashAlgorithm.SHA256;
|
||||
}
|
||||
}
|
||||
|
||||
private static HashAlgorithm getRakamakHash() {
|
||||
String key = "Converter.Rakamak.newPasswordHash";
|
||||
|
||||
try {
|
||||
return HashAlgorithm.valueOf(configFile.getString(key,"SHA256").toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
ConsoleLogger.showError("Unknown Hash Algorithm; defaulting to SHA256");
|
||||
return HashAlgorithm.SHA256;
|
||||
}
|
||||
}
|
||||
|
||||
private static DataSourceType getDataSource() {
|
||||
String key = "DataSource.backend";
|
||||
try {
|
||||
return DataSource.DataSourceType.valueOf(configFile.getString(key).toUpperCase());
|
||||
} catch (IllegalArgumentException ex) {
|
||||
ConsoleLogger.showError("Unknown database backend; defaulting to file database");
|
||||
return DataSource.DataSourceType.FILE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Config option for setting and check restricted user by
|
||||
* username;ip , return false if ip and name doesnt amtch with
|
||||
* player that join the server, so player has a restricted access
|
||||
*/
|
||||
public static Boolean getRestrictedIp(String name, String ip) {
|
||||
|
||||
Iterator<String> iter = getRestrictedIp.iterator();
|
||||
Boolean trueonce = false;
|
||||
Boolean namefound = false;
|
||||
while (iter.hasNext()) {
|
||||
String[] args = iter.next().split(";");
|
||||
String testname = args[0];
|
||||
String testip = args[1];
|
||||
if(testname.equalsIgnoreCase(name) ) {
|
||||
namefound = true;
|
||||
if(testip.equalsIgnoreCase(ip)) {
|
||||
trueonce = true;
|
||||
};
|
||||
}
|
||||
}
|
||||
if ( namefound == false){
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ( trueonce == true ){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration from disk
|
||||
*
|
||||
* @return True if loaded successfully
|
||||
*/
|
||||
public final boolean load() {
|
||||
try {
|
||||
load(file);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public final void reload() {
|
||||
load();
|
||||
loadDefaults(file.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration to disk
|
||||
*
|
||||
* @return True if saved successfully
|
||||
*/
|
||||
public final boolean save() {
|
||||
try {
|
||||
save(file);
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple function for if the Configuration file exists
|
||||
*
|
||||
* @return True if configuration exists on disk
|
||||
*/
|
||||
public final boolean exists() {
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a file from the plugin jar and sets as default
|
||||
*
|
||||
* @param filename The filename to open
|
||||
*/
|
||||
public final void loadDefaults(String filename) {
|
||||
InputStream stream = plugin.getResource(filename);
|
||||
if(stream == null) return;
|
||||
|
||||
setDefaults(YamlConfiguration.loadConfiguration(stream));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves current configuration (plus defaults) to disk.
|
||||
*
|
||||
* If defaults and configuration are empty, saves blank file.
|
||||
*
|
||||
* @return True if saved successfully
|
||||
*/
|
||||
public final boolean saveDefaults() {
|
||||
options().copyDefaults(true);
|
||||
options().copyHeader(true);
|
||||
boolean success = save();
|
||||
options().copyDefaults(false);
|
||||
options().copyHeader(false);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears current configuration defaults
|
||||
*/
|
||||
public final void clearDefaults() {
|
||||
setDefaults(new MemoryConfiguration());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check loaded defaults against current configuration
|
||||
*
|
||||
* @return false When all defaults aren't present in config
|
||||
*/
|
||||
public boolean checkDefaults() {
|
||||
if (getDefaults() == null) {
|
||||
return true;
|
||||
}
|
||||
return getKeys(true).containsAll(getDefaults().getKeys(true));
|
||||
}
|
||||
|
||||
public static String checkLang(String lang) {
|
||||
for(messagesLang language: messagesLang.values()) {
|
||||
if(lang.toLowerCase().contains(language.toString())) {
|
||||
ConsoleLogger.info("Set Language: "+lang);
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
ConsoleLogger.info("Set Default Language: En ");
|
||||
return "en";
|
||||
}
|
||||
|
||||
public enum messagesLang {
|
||||
en, de, br, cz, pl, fr, ru, hu, sk, es, zhtw, fi, zhcn, lt, it, ko, pt
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class Spawn extends CustomConfiguration {
|
||||
|
||||
private static Spawn spawn;
|
||||
private static List<String> emptyList = new ArrayList<String>();
|
||||
|
||||
public Spawn() {
|
||||
super(new File("./plugins/AuthMe/spawn.yml"));
|
||||
spawn = this;
|
||||
load();
|
||||
save();
|
||||
saveDefault();
|
||||
}
|
||||
|
||||
private void saveDefault() {
|
||||
if (!contains("spawn")) {
|
||||
set("spawn", emptyList);
|
||||
set("spawn.world", "");
|
||||
set("spawn.x", "");
|
||||
set("spawn.y", "");
|
||||
set("spawn.z", "");
|
||||
set("spawn.yaw", "");
|
||||
set("spawn.pitch", "");
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
public static Spawn getInstance() {
|
||||
if (spawn == null) {
|
||||
spawn = new Spawn();
|
||||
}
|
||||
return spawn;
|
||||
}
|
||||
|
||||
public boolean setSpawn(Location location) {
|
||||
try {
|
||||
set("spawn.world", location.getWorld().getName());
|
||||
set("spawn.x", location.getX());
|
||||
set("spawn.y", location.getY());
|
||||
set("spawn.z", location.getZ());
|
||||
set("spawn.yaw", location.getYaw());
|
||||
set("spawn.pitch", location.getPitch());
|
||||
save();
|
||||
return true;
|
||||
} catch (NullPointerException npe) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Location getLocation() {
|
||||
try {
|
||||
if (this.getString("spawn.world").isEmpty() || this.getString("spawn.world") == "") return null;
|
||||
Location location = new Location(Bukkit.getWorld(this.getString("spawn.world")), this.getDouble("spawn.x"), this.getDouble("spawn.y"), this.getDouble("spawn.z"), Float.parseFloat(this.getString("spawn.yaw")), Float.parseFloat(this.getString("spawn.pitch")));
|
||||
return location;
|
||||
} catch (NullPointerException npe) {
|
||||
return null;
|
||||
} catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SpoutCfg extends CustomConfiguration{
|
||||
|
||||
private static SpoutCfg instance = null;
|
||||
|
||||
public SpoutCfg(File file)
|
||||
{
|
||||
super(file);
|
||||
loadDefaults();
|
||||
load();
|
||||
save();
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private void loadDefaults() {
|
||||
this.set("Spout GUI enabled", true);
|
||||
this.set("LoginScreen.enabled", true);
|
||||
this.set("LoginScreen.exit button", "Quit");
|
||||
this.set("LoginScreen.exit message", "Good Bye");
|
||||
this.set("LoginScreen.login button", "Login");
|
||||
this.set("LoginScreen.title", "LOGIN");
|
||||
this.set("LoginScreen.text", new ArrayList<String>() {{
|
||||
add("Sample text");
|
||||
add("Change this at spout.yml");
|
||||
add("--- AuthMe Reloaded by ---");
|
||||
add("Xephi59");
|
||||
}});
|
||||
}
|
||||
|
||||
public static SpoutCfg getInstance() {
|
||||
if (instance == null) instance = new SpoutCfg(new File("plugins/AuthMe", "spout.yml"));
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package fr.xephi.authme.task;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
|
||||
|
||||
public class MessageTask implements Runnable {
|
||||
|
||||
private AuthMe plugin;
|
||||
private String name;
|
||||
private String msg;
|
||||
private int interval;
|
||||
|
||||
public MessageTask(AuthMe plugin, String name, String msg, int interval) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
this.msg = msg;
|
||||
this.interval = interval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
if (player.getName().toLowerCase().equals(name)) {
|
||||
player.sendMessage(msg);
|
||||
BukkitScheduler sched = plugin.getServer().getScheduler();
|
||||
BukkitTask late = sched.runTaskLater(plugin, this, interval * 20);
|
||||
if(LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(late.getTaskId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package fr.xephi.authme.task;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.cache.backup.FileCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.settings.Messages;
|
||||
|
||||
|
||||
|
||||
public class TimeoutTask implements Runnable {
|
||||
|
||||
private JavaPlugin plugin;
|
||||
private String name;
|
||||
private Messages m = Messages.getInstance();
|
||||
private FileCache playerCache = new FileCache();
|
||||
|
||||
public TimeoutTask(JavaPlugin plugin, String name) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
return;
|
||||
}
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
if (player.getName().toLowerCase().equals(name)) {
|
||||
if (LimboCache.getInstance().hasLimboPlayer(name)) {
|
||||
LimboPlayer inv = LimboCache.getInstance().getLimboPlayer(name);
|
||||
player.getServer().getScheduler().cancelTask(inv.getTimeoutTaskId());
|
||||
if(playerCache.doesCacheExist(name)) {
|
||||
playerCache.removeCache(name);
|
||||
}
|
||||
}
|
||||
int gm = AuthMePlayerListener.gameMode.get(name);
|
||||
player.setGameMode(GameMode.getByValue(gm));
|
||||
ConsoleLogger.info("Set " + player.getName() + " to gamemode: " + GameMode.getByValue(gm).name());
|
||||
player.kickPlayer(m._("timeout"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,579 @@
|
||||
package fr.xephi.authme.threads;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
|
||||
public class FlatFileThread extends Thread implements DataSource {
|
||||
|
||||
/* file layout:
|
||||
*
|
||||
* PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS:LASTPOSX:LASTPOSY:LASTPOSZ:LASTPOSWORLD
|
||||
*
|
||||
* Old but compatible:
|
||||
* PLAYERNAME:HASHSUM:IP:LOGININMILLIESECONDS
|
||||
* PLAYERNAME:HASHSUM:IP
|
||||
* PLAYERNAME:HASHSUM
|
||||
*
|
||||
*/
|
||||
private File source;
|
||||
|
||||
public void run() {
|
||||
source = new File(Settings.AUTH_FILE);
|
||||
try {
|
||||
source.createNewFile();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use FLAT FILE... SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 1 && args[0].equals(user)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
if (isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
BufferedWriter bw = null;
|
||||
try {
|
||||
bw = new BufferedWriter(new FileWriter(source, true));
|
||||
bw.write(auth.getNickname() + ":" + auth.getHash() + ":" + auth.getIp() + ":" + auth.getLastLogin() + ":" + auth.getQuitLocX() + ":" + auth.getQuitLocY() + ":" + auth.getQuitLocZ() + ":" + auth.getWorld() + "\n");
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth newAuth = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
switch (args.length) {
|
||||
case 4: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], Long.parseLong(args[3]), 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), "world");
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), args[7]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newAuth = new PlayerAuth(args[0], auth.getHash(), args[2], 0, 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAuth(auth.getNickname());
|
||||
saveAuth(newAuth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSession(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth newAuth = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
switch (args.length) {
|
||||
case 4: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), "world");
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), args[7]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
newAuth = new PlayerAuth(args[0], args[1], auth.getIp(), auth.getLastLogin(), 0, 0, 0, "world");
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAuth(auth.getNickname());
|
||||
saveAuth(newAuth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuitLoc(PlayerAuth auth) {
|
||||
if (!isAuthAvailable(auth.getNickname())) {
|
||||
return false;
|
||||
}
|
||||
PlayerAuth newAuth = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(auth.getNickname())) {
|
||||
newAuth = new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), auth.getQuitLocX(), auth.getQuitLocY(), auth.getQuitLocZ(), auth.getWorld());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
removeAuth(auth.getNickname());
|
||||
saveAuth(newAuth);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIps(String ip) {
|
||||
BufferedReader br = null;
|
||||
int countIp = 0;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 3 && args[2].equals(ip)) {
|
||||
countIp++;
|
||||
}
|
||||
}
|
||||
return countIp;
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int purgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
int cleared = 0;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length >= 4) {
|
||||
if (Long.parseLong(args[3]) >= until) {
|
||||
lines.add(line);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
cleared++;
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> autoPurgeDatabase(long until) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
List<String> cleared = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length >= 4) {
|
||||
if (Long.parseLong(args[3]) >= until) {
|
||||
lines.add(line);
|
||||
continue;
|
||||
} else {
|
||||
cleared.add(args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return cleared;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return cleared;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
if (!isAuthAvailable(user)) {
|
||||
return false;
|
||||
}
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 1 && !args[0].equals(user)) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args[0].equals(user)) {
|
||||
switch (args.length) {
|
||||
case 2:
|
||||
return new PlayerAuth(args[0], args[1], "198.18.0.1", 0);
|
||||
case 3:
|
||||
return new PlayerAuth(args[0], args[1], args[2], 0);
|
||||
case 4:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]));
|
||||
case 7:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), "unavailableworld");
|
||||
case 8:
|
||||
return new PlayerAuth(args[0], args[1], args[2], Long.parseLong(args[3]), Integer.parseInt(args[4]), Integer.parseInt(args[5]), Integer.parseInt(args[6]), args[7]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateEmail(PlayerAuth auth) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateSalt(PlayerAuth auth) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
BufferedReader br = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 3 && args[2].equals(auth.getIp())) {
|
||||
countIp.add(args[0]);
|
||||
}
|
||||
}
|
||||
return countIp;
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByIp(String ip) {
|
||||
BufferedReader br = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
if (args.length > 3 && args[2].equals(ip)) {
|
||||
countIp.add(args[0]);
|
||||
}
|
||||
}
|
||||
return countIp;
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAllAuthsByEmail(String email) {
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void purgeBanned(List<String> banned) {
|
||||
BufferedReader br = null;
|
||||
BufferedWriter bw = null;
|
||||
ArrayList<String> lines = new ArrayList<String>();
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(source));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] args = line.split(":");
|
||||
try {
|
||||
if (banned.contains(args[0])) {
|
||||
lines.add(line);
|
||||
}
|
||||
} catch (NullPointerException npe) {}
|
||||
catch (ArrayIndexOutOfBoundsException aioobe) {}
|
||||
}
|
||||
bw = new BufferedWriter(new FileWriter(source));
|
||||
for (String l : lines) {
|
||||
bw.write(l + "\n");
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return;
|
||||
} finally {
|
||||
if (br != null) {
|
||||
try {
|
||||
br.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
if (bw != null) {
|
||||
try {
|
||||
bw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,801 @@
|
||||
package fr.xephi.authme.threads;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.MiniConnectionPoolManager;
|
||||
import fr.xephi.authme.datasource.MiniConnectionPoolManager.TimeoutException;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
public class MySQLThread extends Thread implements DataSource {
|
||||
|
||||
private String host;
|
||||
private String port;
|
||||
private String username;
|
||||
private String password;
|
||||
private String database;
|
||||
private String tableName;
|
||||
private String columnName;
|
||||
private String columnPassword;
|
||||
private String columnIp;
|
||||
private String columnLastLogin;
|
||||
private String columnSalt;
|
||||
private String columnGroup;
|
||||
private String lastlocX;
|
||||
private String lastlocY;
|
||||
private String lastlocZ;
|
||||
private String lastlocWorld;
|
||||
private String columnEmail;
|
||||
private String columnID;
|
||||
private List<String> columnOthers;
|
||||
private MiniConnectionPoolManager conPool;
|
||||
|
||||
public void run() {
|
||||
this.host = Settings.getMySQLHost;
|
||||
this.port = Settings.getMySQLPort;
|
||||
this.username = Settings.getMySQLUsername;
|
||||
this.password = Settings.getMySQLPassword;
|
||||
this.database = Settings.getMySQLDatabase;
|
||||
this.tableName = Settings.getMySQLTablename;
|
||||
this.columnName = Settings.getMySQLColumnName;
|
||||
this.columnPassword = Settings.getMySQLColumnPassword;
|
||||
this.columnIp = Settings.getMySQLColumnIp;
|
||||
this.columnLastLogin = Settings.getMySQLColumnLastLogin;
|
||||
this.lastlocX = Settings.getMySQLlastlocX;
|
||||
this.lastlocY = Settings.getMySQLlastlocY;
|
||||
this.lastlocZ = Settings.getMySQLlastlocZ;
|
||||
this.lastlocWorld = Settings.getMySQLlastlocWorld;
|
||||
this.columnSalt = Settings.getMySQLColumnSalt;
|
||||
this.columnGroup = Settings.getMySQLColumnGroup;
|
||||
this.columnEmail = Settings.getMySQLColumnEmail;
|
||||
this.columnOthers = Settings.getMySQLOtherUsernameColumn;
|
||||
this.columnID = Settings.getMySQLColumnId;
|
||||
|
||||
try {
|
||||
this.connect();
|
||||
this.setup();
|
||||
} catch (ClassNotFoundException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use MySQL... Please input correct MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
return;
|
||||
} catch (SQLException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use MySQL... Please input correct MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
return;
|
||||
} catch (TimeoutException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use MySQL... Please input correct MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void connect() throws ClassNotFoundException, SQLException, TimeoutException {
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
ConsoleLogger.info("MySQL driver loaded");
|
||||
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
|
||||
dataSource.setDatabaseName(database);
|
||||
dataSource.setServerName(host);
|
||||
dataSource.setPort(Integer.parseInt(port));
|
||||
dataSource.setUser(username);
|
||||
dataSource.setPassword(password);
|
||||
conPool = new MiniConnectionPoolManager(dataSource, 10);
|
||||
ConsoleLogger.info("Connection pool ready");
|
||||
}
|
||||
|
||||
private synchronized void setup() throws SQLException {
|
||||
Connection con = null;
|
||||
Statement st = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
st = con.createStatement();
|
||||
st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ columnID + " INTEGER AUTO_INCREMENT,"
|
||||
+ columnName + " VARCHAR(255) NOT NULL UNIQUE,"
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL,"
|
||||
+ columnIp + " VARCHAR(40) NOT NULL,"
|
||||
+ columnLastLogin + " BIGINT,"
|
||||
+ lastlocX + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocY + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocZ + " smallint(6) DEFAULT '0',"
|
||||
+ lastlocWorld + " VARCHAR(255) DEFAULT 'world',"
|
||||
+ columnEmail + " VARCHAR(255) DEFAULT 'your@email.com',"
|
||||
+ "CONSTRAINT table_const_prim PRIMARY KEY (" + columnID + "));");
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnPassword);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnPassword + " VARCHAR(255) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnIp);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnIp + " VARCHAR(40) NOT NULL;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnLastLogin);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ columnLastLogin + " BIGINT;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocX);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocX + " smallint(6) NOT NULL DEFAULT '0' AFTER "
|
||||
+ columnLastLogin +" , ADD " + lastlocY + " smallint(6) NOT NULL DEFAULT '0' AFTER " + lastlocX + " , ADD " + lastlocZ + " smallint(6) NOT NULL DEFAULT '0' AFTER " + lastlocY + ";");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, lastlocWorld);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + lastlocWorld + " VARCHAR(255) NOT NULL DEFAULT 'world' AFTER " + lastlocZ + ";");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, columnEmail);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + columnEmail + " VARCHAR(255) DEFAULT 'your@email.com' AFTER " + lastlocZ +";");
|
||||
}
|
||||
} finally {
|
||||
close(rs);
|
||||
close(st);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isAuthAvailable(String user) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnName + "=?;");
|
||||
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
return rs.next();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized PlayerAuth getAuth(String user) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnName + "=?;");
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
if (rs.getString(columnIp).isEmpty() ) {
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), "198.18.0.1", rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld),rs.getString(columnEmail));
|
||||
} else {
|
||||
if(!columnSalt.isEmpty()){
|
||||
if(!columnGroup.isEmpty())
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword),rs.getString(columnSalt), rs.getInt(columnGroup), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail));
|
||||
else return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword),rs.getString(columnSalt), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld),rs.getString(columnEmail));
|
||||
} else {
|
||||
return new PlayerAuth(rs.getString(columnName), rs.getString(columnPassword), rs.getString(columnIp), rs.getLong(columnLastLogin), rs.getInt(lastlocX), rs.getInt(lastlocY), rs.getInt(lastlocZ), rs.getString(lastlocWorld), rs.getString(columnEmail));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return null;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean saveAuth(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
if ((columnSalt.isEmpty() || columnSalt == null) && (auth.getSalt().isEmpty() || auth.getSalt() == null)) {
|
||||
pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + ") VALUES (?,?,?,?);");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getHash());
|
||||
pst.setString(3, auth.getIp());
|
||||
pst.setLong(4, auth.getLastLogin());
|
||||
pst.executeUpdate();
|
||||
} else {
|
||||
pst = con.prepareStatement("INSERT INTO " + tableName + "(" + columnName + "," + columnPassword + "," + columnIp + "," + columnLastLogin + "," + columnSalt + ") VALUES (?,?,?,?,?);");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getHash());
|
||||
pst.setString(3, auth.getIp());
|
||||
pst.setLong(4, auth.getLastLogin());
|
||||
pst.setString(5, auth.getSalt());
|
||||
pst.executeUpdate();
|
||||
}
|
||||
if (!columnOthers.isEmpty()) {
|
||||
for(String column : columnOthers) {
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + tableName + "." + column + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
}
|
||||
}
|
||||
if (Settings.getPasswordHash == HashAlgorithm.PHPBB) {
|
||||
int id;
|
||||
ResultSet rs = null;
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
id = rs.getInt(columnID);
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getPhpbbPrefix + "user_group (group_id, user_id, group_leader, user_pending) VALUES (?,?,?,?);");
|
||||
pst.setInt(1, Settings.getPhpbbGroup);
|
||||
pst.setInt(2, id);
|
||||
pst.setInt(3, 0);
|
||||
pst.setInt(4, 0);
|
||||
pst.executeUpdate();
|
||||
}
|
||||
}
|
||||
if (Settings.getPasswordHash == HashAlgorithm.WORDPRESS) {
|
||||
int id;
|
||||
ResultSet rs = null;
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getNickname());
|
||||
rs = pst.executeQuery();
|
||||
if (rs.next()) {
|
||||
id = rs.getInt(columnID);
|
||||
// First Name
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "first_name");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
// Last Name
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "last_name");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
// Nick Name
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "nickname");
|
||||
pst.setString(3, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
// Description
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "description");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
// Rich_Editing
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "rich_editing");
|
||||
pst.setString(3, "true");
|
||||
pst.executeUpdate();
|
||||
// Comments_Shortcuts
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "comment_shortcuts");
|
||||
pst.setString(3, "false");
|
||||
pst.executeUpdate();
|
||||
// admin_color
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "admin_color");
|
||||
pst.setString(3, "fresh");
|
||||
pst.executeUpdate();
|
||||
// use_ssl
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "use_ssl");
|
||||
pst.setString(3, "0");
|
||||
pst.executeUpdate();
|
||||
// show_admin_bar_front
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "show_admin_bar_front");
|
||||
pst.setString(3, "true");
|
||||
pst.executeUpdate();
|
||||
// wp_capabilities
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "wp_capabilities");
|
||||
pst.setString(3, "a:1:{s:10:\"subscriber\";b:1;}");
|
||||
pst.executeUpdate();
|
||||
// wp_user_level
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "wp_user_level");
|
||||
pst.setString(3, "0");
|
||||
pst.executeUpdate();
|
||||
// default_password_nag
|
||||
pst = con.prepareStatement("INSERT INTO " + Settings.getWordPressPrefix + "usermeta (user_id, meta_key, meta_value) VALUES (?,?,?);");
|
||||
pst.setInt(1, id);
|
||||
pst.setString(2, "default_password_nag");
|
||||
pst.setString(3, "");
|
||||
pst.executeUpdate();
|
||||
}
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updatePassword(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnPassword + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getHash());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateSession(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET " + columnIp + "=?, " + columnLastLogin + "=? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getIp());
|
||||
pst.setLong(2, auth.getLastLogin());
|
||||
pst.setString(3, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int purgeDatabase(long until) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnLastLogin + "<?;");
|
||||
pst.setLong(1, until);
|
||||
return pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> autoPurgeDatabase(long until) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> list = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE " + columnLastLogin + "<?;");
|
||||
pst.setLong(1, until);
|
||||
rs = pst.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(rs.getString(columnName));
|
||||
}
|
||||
return list;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean removeAuth(String user) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, user);
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateQuitLoc(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET "+ lastlocX + " =?, "+ lastlocY +"=?, "+ lastlocZ +"=?, " + lastlocWorld + "=? WHERE " + columnName + "=?;");
|
||||
pst.setLong(1, auth.getQuitLocX());
|
||||
pst.setLong(2, auth.getQuitLocY());
|
||||
pst.setLong(3, auth.getQuitLocZ());
|
||||
pst.setString(4, auth.getWorld());
|
||||
pst.setString(5, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getIps(String ip) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
int countIp=0;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, ip);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp++;
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return 0;
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateEmail(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET "+ columnEmail + " =? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getEmail());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean updateSalt(PlayerAuth auth) {
|
||||
if (columnSalt.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("UPDATE " + tableName + " SET "+ columnSalt + " =? WHERE " + columnName + "=?;");
|
||||
pst.setString(1, auth.getSalt());
|
||||
pst.setString(2, auth.getNickname());
|
||||
pst.executeUpdate();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return false;
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
try {
|
||||
conPool.dispose();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
}
|
||||
|
||||
private void close(Statement st) {
|
||||
if (st != null) {
|
||||
try {
|
||||
st.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(ResultSet rs) {
|
||||
if (rs != null) {
|
||||
try {
|
||||
rs.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void close(Connection con) {
|
||||
if (con != null) {
|
||||
try {
|
||||
con.close();
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByName(PlayerAuth auth) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, auth.getIp());
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp.add(rs.getString(columnName));
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByIp(String ip) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countIp = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnIp + "=?;");
|
||||
pst.setString(1, ip);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countIp.add(rs.getString(columnName));
|
||||
}
|
||||
return countIp;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized List<String> getAllAuthsByEmail(String email) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
List<String> countEmail = new ArrayList<String>();
|
||||
try {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE "
|
||||
+ columnEmail + "=?;");
|
||||
pst.setString(1, email);
|
||||
rs = pst.executeQuery();
|
||||
while(rs.next()) {
|
||||
countEmail.add(rs.getString(columnName));
|
||||
}
|
||||
return countEmail;
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} catch (TimeoutException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
return new ArrayList<String>();
|
||||
} finally {
|
||||
close(rs);
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void purgeBanned(List<String> banned) {
|
||||
Connection con = null;
|
||||
PreparedStatement pst = null;
|
||||
try {
|
||||
for (String name : banned) {
|
||||
con = makeSureConnectionIsReady();
|
||||
pst = con.prepareStatement("DELETE FROM " + tableName + " WHERE " + columnName + "=?;");
|
||||
pst.setString(1, name);
|
||||
pst.executeUpdate();
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
ConsoleLogger.showError(ex.getMessage());
|
||||
} finally {
|
||||
close(pst);
|
||||
close(con);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Connection makeSureConnectionIsReady() {
|
||||
Connection con = null;
|
||||
try {
|
||||
con = conPool.getValidConnection();
|
||||
} catch (Exception te) {
|
||||
try {
|
||||
con = null;
|
||||
reconnect();
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
}
|
||||
} catch (AssertionError ae) {
|
||||
// Make sure assertionerror is caused by the connectionpoolmanager, else re-throw it
|
||||
if (!ae.getMessage().equalsIgnoreCase("AuthMeDatabaseError"))
|
||||
throw new AssertionError(ae.getMessage());
|
||||
try {
|
||||
con = null;
|
||||
reconnect();
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't reconnect to MySQL database... Please check your MySQL informations ! SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled)
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
}
|
||||
}
|
||||
if (con == null)
|
||||
con = conPool.getValidConnection();
|
||||
return con;
|
||||
}
|
||||
|
||||
private synchronized void reconnect() throws ClassNotFoundException, SQLException, TimeoutException {
|
||||
conPool.dispose();
|
||||
Class.forName("com.mysql.jdbc.Driver");
|
||||
MysqlConnectionPoolDataSource dataSource = new MysqlConnectionPoolDataSource();
|
||||
dataSource.setDatabaseName(database);
|
||||
dataSource.setServerName(host);
|
||||
dataSource.setPort(Integer.parseInt(port));
|
||||
dataSource.setUser(username);
|
||||
dataSource.setPassword(password);
|
||||
conPool = new MiniConnectionPoolManager(dataSource, 10);
|
||||
ConsoleLogger.info("ConnectionPool was unavailable... Reconnected!");
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user