2011-06-18 03:55:26 -04:00
|
|
|
package com.cypherx.xauth;
|
|
|
|
|
|
|
|
import com.cypherx.xauth.commands.*;
|
|
|
|
import com.cypherx.xauth.datamanager.*;
|
|
|
|
import com.cypherx.xauth.listeners.*;
|
|
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileReader;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.sql.Timestamp;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.World;
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.inventory.PlayerInventory;
|
|
|
|
import org.bukkit.plugin.PluginDescriptionFile;
|
|
|
|
import org.bukkit.plugin.java.JavaPlugin;
|
|
|
|
|
|
|
|
public class xAuth extends JavaPlugin {
|
|
|
|
public static PluginDescriptionFile desc;
|
|
|
|
public static File dataFolder;
|
|
|
|
private DataManager dataManager;
|
|
|
|
|
|
|
|
public void onDisable() {
|
|
|
|
Player[] players = getServer().getOnlinePlayers();
|
|
|
|
if (players.length > 0) {
|
|
|
|
for (Player player : players) {
|
2011-06-24 17:00:12 -04:00
|
|
|
xAuthPlayer xPlayer = dataManager.getPlayer(player.getName());
|
2011-06-18 03:55:26 -04:00
|
|
|
if (xPlayer.isGuest())
|
|
|
|
removeGuest(xPlayer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dataManager != null)
|
|
|
|
dataManager.close();
|
|
|
|
|
|
|
|
xAuthSettings.saveChanges();
|
|
|
|
xAuthLog.info("v" + desc.getVersion() + " Disabled!");
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onEnable() {
|
|
|
|
desc = getDescription();
|
|
|
|
dataFolder = getDataFolder();
|
|
|
|
|
|
|
|
if (!dataFolder.exists())
|
|
|
|
dataFolder.mkdirs();
|
|
|
|
|
|
|
|
xAuthSettings.setup(dataFolder);
|
|
|
|
xAuthMessages.setup(dataFolder);
|
|
|
|
|
2011-06-24 17:00:12 -04:00
|
|
|
if (xAuthSettings.autoDisable && getServer().getOnlineMode()) {
|
2011-06-18 03:55:26 -04:00
|
|
|
xAuthLog.warning("Disabling - Server is running in online-mode");
|
|
|
|
getServer().getPluginManager().disablePlugin(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
xAuthPermissions.setup(this);
|
|
|
|
xAuthHelp.setup(this);
|
|
|
|
|
|
|
|
dataManager = new DataManager();
|
|
|
|
if (!dataManager.isConnected()) {
|
|
|
|
xAuthLog.severe("Disabling - No connection to database");
|
|
|
|
getServer().getPluginManager().disablePlugin(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
dataManager.runStartupTasks();
|
|
|
|
|
|
|
|
File oldAuthFile = new File(dataFolder, "auths.txt");
|
|
|
|
if (oldAuthFile.exists())
|
|
|
|
importAccounts(oldAuthFile);
|
|
|
|
|
|
|
|
dataManager.printStats();
|
|
|
|
|
|
|
|
Player[] players = getServer().getOnlinePlayers();
|
|
|
|
if (players.length > 0) // /reload was used
|
|
|
|
handleReload(players);
|
|
|
|
|
|
|
|
(new xAuthPlayerListener(this)).registerEvents();
|
|
|
|
(new xAuthBlockListener(this)).registerEvents();
|
|
|
|
(new xAuthEntityListener(this)).registerEvents();
|
|
|
|
getCommand("register").setExecutor(new RegisterCommand(this));
|
|
|
|
getCommand("login").setExecutor(new LoginCommand(this));
|
|
|
|
getCommand("changepw").setExecutor(new ChangePasswordCommand(this));
|
|
|
|
getCommand("logout").setExecutor(new LogoutCommand(this));
|
|
|
|
getCommand("xauth").setExecutor(new xAuthCommand(this));
|
|
|
|
|
|
|
|
xAuthLog.info("v" + desc.getVersion() + " Enabled!");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void importAccounts(File oldAuthFile) {
|
|
|
|
xAuthLog.info("Importing old auths.txt file to new format..");
|
|
|
|
List<Account> accounts = new ArrayList<Account>();
|
|
|
|
BufferedReader reader = null;
|
|
|
|
|
|
|
|
try {
|
|
|
|
reader = new BufferedReader(new FileReader(oldAuthFile));
|
|
|
|
String line;
|
|
|
|
Account account;
|
|
|
|
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
String[] split = line.split(":");
|
|
|
|
account = new Account(split[0], split[1], null);
|
|
|
|
accounts.add(account);
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
} finally {
|
|
|
|
try {
|
|
|
|
if (reader != null)
|
|
|
|
reader.close();
|
|
|
|
} catch (IOException e) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
dataManager.insertAccounts(accounts);
|
|
|
|
|
|
|
|
if (oldAuthFile.renameTo(new File(dataFolder, "auths.txt.old")))
|
|
|
|
xAuthLog.info("Import complete! auths.txt renamed to auths.txt.old");
|
|
|
|
else
|
|
|
|
xAuthLog.info("Import complete! Verify that all accounts were imported then remove/rename auths.txt");
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleReload(Player[] players) {
|
|
|
|
for (Player player : players) {
|
2011-06-24 17:00:12 -04:00
|
|
|
xAuthPlayer xPlayer = dataManager.getPlayerJoin(player.getName());
|
2011-06-18 03:55:26 -04:00
|
|
|
boolean isRegistered = xPlayer.isRegistered();
|
|
|
|
|
|
|
|
if (!xPlayer.isAuthenticated() && (isRegistered || (!isRegistered && xPlayer.mustRegister()))) {
|
|
|
|
createGuest(xPlayer);
|
|
|
|
xAuthMessages.send("miscReloaded", player);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void createGuest(xAuthPlayer xPlayer) {
|
|
|
|
final Player player = xPlayer.getPlayer();
|
|
|
|
|
|
|
|
// remove old session (if any)
|
|
|
|
if (xPlayer.hasSession())
|
|
|
|
dataManager.deleteSession(xPlayer);
|
|
|
|
|
|
|
|
if (xAuthSettings.guestTimeout > 0 && xPlayer.isRegistered()) {
|
|
|
|
int taskId = getServer().getScheduler().scheduleAsyncDelayedTask(this, new Runnable() {
|
|
|
|
public void run() {
|
|
|
|
player.kickPlayer(xAuthMessages.get("miscKickTimeout", player, null));
|
|
|
|
}
|
|
|
|
}, xAuthSettings.guestTimeout * 20);
|
|
|
|
|
|
|
|
xPlayer.setTimeoutTaskId(taskId);
|
|
|
|
}
|
|
|
|
|
|
|
|
protect(xPlayer);
|
|
|
|
xPlayer.setLastNotifyTime(Util.getNow());
|
|
|
|
xPlayer.setGuest(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void removeGuest(xAuthPlayer xPlayer) {
|
2011-07-04 00:58:01 -04:00
|
|
|
if (!xPlayer.isGuest())
|
|
|
|
return;
|
|
|
|
|
2011-06-18 03:55:26 -04:00
|
|
|
getServer().getScheduler().cancelTask(xPlayer.getTimeoutTaskId());
|
|
|
|
restore(xPlayer);
|
|
|
|
xPlayer.setGuest(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void protect(xAuthPlayer xPlayer) {
|
|
|
|
Player player = xPlayer.getPlayer();
|
|
|
|
PlayerInventory playerInv = player.getInventory();
|
|
|
|
|
2011-06-24 17:00:12 -04:00
|
|
|
dataManager.insertInventory(xPlayer);
|
2011-06-18 03:55:26 -04:00
|
|
|
playerInv.clear();
|
|
|
|
playerInv.setHelmet(null);
|
|
|
|
playerInv.setChestplate(null);
|
|
|
|
playerInv.setLeggings(null);
|
|
|
|
playerInv.setBoots(null);
|
|
|
|
player.saveData();
|
|
|
|
|
|
|
|
if (player.getHealth() > 0)
|
|
|
|
xPlayer.setLocation(player.getLocation());
|
|
|
|
|
2011-07-04 00:58:01 -04:00
|
|
|
if (xAuthSettings.protectLoc)
|
|
|
|
player.teleport(getLocationToTeleport(player.getWorld()));
|
2011-06-18 03:55:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public void restore(xAuthPlayer xPlayer) {
|
|
|
|
Player player = xPlayer.getPlayer();
|
|
|
|
PlayerInventory playerInv = player.getInventory();
|
|
|
|
|
2011-06-24 17:00:12 -04:00
|
|
|
ItemStack[] inv = dataManager.getInventory(xPlayer);
|
|
|
|
ItemStack[] items = new ItemStack[inv.length - 4];
|
|
|
|
ItemStack[] armor = new ItemStack[4];
|
|
|
|
|
|
|
|
for (int i = 0; i < inv.length - 4; i++)
|
|
|
|
items[i] = inv[i];
|
|
|
|
|
|
|
|
//Backpack fix
|
|
|
|
if (playerInv.getSize() > items.length) {
|
|
|
|
ItemStack[] newItems = new ItemStack[playerInv.getSize()];
|
|
|
|
|
|
|
|
for(int i = 0; i < items.length; i++)
|
|
|
|
newItems[i] = items[i];
|
|
|
|
|
|
|
|
items = newItems;
|
|
|
|
}
|
|
|
|
//end Backpack fix
|
|
|
|
|
|
|
|
armor[0] = inv[inv.length - 4];
|
|
|
|
armor[1] = inv[inv.length - 3];
|
|
|
|
armor[2] = inv[inv.length - 2];
|
|
|
|
armor[3] = inv[inv.length - 1];
|
|
|
|
|
|
|
|
playerInv.setContents(items);
|
|
|
|
playerInv.setArmorContents(armor);
|
|
|
|
dataManager.deleteInventory(xPlayer);
|
|
|
|
|
2011-06-18 03:55:26 -04:00
|
|
|
if (xPlayer.getLocation() != null)
|
|
|
|
xPlayer.getPlayer().teleport(xPlayer.getLocation());
|
|
|
|
player.saveData();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void login(xAuthPlayer xPlayer) {
|
|
|
|
Account account = xPlayer.getAccount();
|
|
|
|
account.setLastLoginDate(Util.getNow());
|
|
|
|
account.setLastLoginHost(Util.getHostFromPlayer(xPlayer.getPlayer()));
|
|
|
|
dataManager.saveAccount(account);
|
|
|
|
|
|
|
|
Session session = new Session(account.getId(), account.getLastLoginHost());
|
|
|
|
xPlayer.setSession(session);
|
|
|
|
dataManager.insertSession(session);
|
|
|
|
|
|
|
|
removeGuest(xPlayer);
|
2011-06-19 17:28:51 -04:00
|
|
|
xPlayer.setStrikes(0);
|
2011-06-18 03:55:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public void changePassword(Account account, String newPass) {
|
|
|
|
account.setPassword(Util.encrypt(newPass));
|
|
|
|
dataManager.saveAccount(account);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean checkPassword(Account account, String checkPass) {
|
|
|
|
String realPass = account.getPassword();
|
|
|
|
|
|
|
|
// check for old encryption (md5 or whirlpool)
|
|
|
|
if (realPass.length() == 32 || realPass.length() == 128) {
|
|
|
|
String hash = (realPass.length() == 32 ? Util.md5(checkPass) : Util.whirlpool(checkPass));
|
|
|
|
if (realPass.equals(hash)) {
|
|
|
|
changePassword(account, checkPass); // change password to use new encryption
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// xAuth 2 encryption
|
|
|
|
int saltPos = (checkPass.length() >= realPass.length() ? realPass.length() : checkPass.length());
|
|
|
|
|
|
|
|
// extract salt
|
2011-06-19 04:42:33 -04:00
|
|
|
String salt = realPass.substring(saltPos, saltPos + 12);
|
2011-06-18 03:55:26 -04:00
|
|
|
|
|
|
|
// encrypt salt + checkPass
|
|
|
|
Whirlpool w = new Whirlpool();
|
|
|
|
byte[] digest = new byte[Whirlpool.DIGESTBYTES];
|
|
|
|
w.NESSIEinit();
|
|
|
|
w.NESSIEadd(salt + checkPass);
|
|
|
|
w.NESSIEfinalize(digest);
|
|
|
|
String hash = Whirlpool.display(digest);
|
|
|
|
return (hash.substring(0, saltPos) + salt + hash.substring(saltPos)).equals(realPass);
|
|
|
|
}
|
|
|
|
|
|
|
|
public Location getLocationToTeleport(World world) {
|
|
|
|
TeleLocation teleLocation = dataManager.getTeleLocation(world.getName());
|
|
|
|
return (teleLocation == null ? world.getSpawnLocation() : teleLocation.getLocation());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void strikeout(xAuthPlayer xPlayer) {
|
|
|
|
Player player = xPlayer.getPlayer();
|
|
|
|
|
|
|
|
if (xAuthSettings.strikeAction.equals("banip")) {
|
|
|
|
StrikeBan ban = new StrikeBan(Util.getHostFromPlayer(player));
|
|
|
|
getDataManager().insertStrikeBan(ban);
|
|
|
|
xAuthLog.info(ban.getHost() + " banned by strike system");
|
|
|
|
}
|
|
|
|
|
|
|
|
player.kickPlayer(xAuthMessages.get("miscKickStrike", player, null));
|
|
|
|
if (xAuthSettings.strikeAction.equals("kick"))
|
|
|
|
xAuthLog.info(player.getName() + " kicked by strike system");
|
2011-06-19 17:28:51 -04:00
|
|
|
|
|
|
|
xPlayer.setStrikes(0);
|
2011-06-18 03:55:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isBanned(String host) {
|
|
|
|
final StrikeBan ban = dataManager.loadStrikeBan(host);
|
|
|
|
if (ban == null)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (xAuthSettings.banLength == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
Timestamp unbanTime = new Timestamp(ban.getBanTime().getTime() + (xAuthSettings.banLength * 1000));
|
|
|
|
if (unbanTime.compareTo(Util.getNow()) > 0) // still banned
|
|
|
|
return true;
|
|
|
|
else // no longer banned, remove from database
|
|
|
|
dataManager.deleteStrikeBan(ban);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void reload() {
|
|
|
|
xAuthSettings.setup(dataFolder);
|
|
|
|
xAuthMessages.setup(dataFolder);
|
|
|
|
}
|
|
|
|
|
|
|
|
public DataManager getDataManager() {
|
|
|
|
return dataManager;
|
|
|
|
}
|
|
|
|
}
|