/* * Copyright (C) 2016 eccentric_nz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package me.eccentric_nz.TARDIS.database; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; 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 java.util.Map; import java.util.Properties; import java.util.UUID; import me.eccentric_nz.TARDIS.TARDIS; import me.eccentric_nz.TARDIS.utility.TARDISUUIDFetcher; import org.bukkit.ChatColor; import org.bukkit.util.FileUtil; /** * * @author eccentric_nz */ public class TARDISUUIDConverter { private final TARDIS plugin; private final TARDISDatabaseConnection service = TARDISDatabaseConnection.getInstance(); private final Connection connection = service.getConnection(); private final List<String> timelords = new ArrayList<String>(); private final String prefix; public TARDISUUIDConverter(TARDIS plugin) { this.plugin = plugin; this.prefix = this.plugin.getPrefix(); } public boolean convert() { // get if server is online-mode=true (as required to retrieve correct player UUIDs) if (!getOnlineMode()) { plugin.getConsole().sendMessage(plugin.getPluginName() + ChatColor.RED + "UUID conversion requires the server online-mode to be TRUE!"); return false; } // backup database if (plugin.getConfig().getString("storage.database").equalsIgnoreCase("sqlite")) { plugin.getConsole().sendMessage(plugin.getPluginName() + plugin.getLanguage().getString("BACKUP_DB")); File oldFile = new File(plugin.getDataFolder() + File.separator + "TARDIS.db"); File newFile = new File(plugin.getDataFolder() + File.separator + "TARDIS_" + System.currentTimeMillis() + ".db"); FileUtil.copy(oldFile, newFile); } // get all TARDIS owners from database Statement statement = null; PreparedStatement ps_ach = null; PreparedStatement ps_ars = null; PreparedStatement ps_pla = null; PreparedStatement ps_sto = null; PreparedStatement ps_tco = null; PreparedStatement ps_tar = null; PreparedStatement ps_tra = null; ResultSet rsa = null; ResultSet rsc = null; ResultSet rsp = null; ResultSet rsr = null; ResultSet rss = null; ResultSet rst = null; ResultSet rsv = null; String querya = "SELECT player FROM " + prefix + "achievements"; String queryc = "SELECT player FROM " + prefix + "t_count"; String queryp = "SELECT player FROM " + prefix + "player_prefs"; String queryr = "SELECT player FROM " + prefix + "ars"; String querys = "SELECT owner FROM " + prefix + "storage"; String queryt = "SELECT owner FROM " + prefix + "tardis"; String queryv = "SELECT player FROM " + prefix + "travellers"; String a_update = "UPDATE " + prefix + "achievements SET uuid = ? WHERE player = ?"; String c_update = "UPDATE " + prefix + "t_count SET uuid = ? WHERE player = ?"; String p_update = "UPDATE " + prefix + "player_prefs SET uuid = ? WHERE player = ?"; String r_update = "UPDATE " + prefix + "ars SET uuid = ? WHERE player = ?"; String s_update = "UPDATE " + prefix + "storage SET uuid = ? WHERE owner = ?"; String t_update = "UPDATE " + prefix + "tardis SET uuid = ? WHERE owner = ?"; String v_update = "UPDATE " + prefix + "travellers SET uuid = ? WHERE player = ?"; int count = 0; // we need to query all tables as there are potentially players in some table that aren't in others try { service.testConnection(connection); statement = connection.createStatement(); rst = statement.executeQuery(queryt); if (rst.isBeforeFirst()) { while (rst.next()) { if (!rst.getString("owner").isEmpty()) { timelords.add(rst.getString("owner")); } } } rsa = statement.executeQuery(querya); if (rsa.isBeforeFirst()) { while (rsa.next()) { // only add them if we haven't already if (!timelords.contains(rsa.getString("player")) && !rsa.getString("player").isEmpty()) { timelords.add(rsa.getString("player")); } } } rsc = statement.executeQuery(queryc); if (rsc.isBeforeFirst()) { while (rsc.next()) { if (!timelords.contains(rsc.getString("player")) && !rsc.getString("player").isEmpty()) { timelords.add(rsc.getString("player")); } } } rsp = statement.executeQuery(queryp); if (rsp.isBeforeFirst()) { while (rsp.next()) { if (!timelords.contains(rsp.getString("player")) && !rsp.getString("player").isEmpty()) { timelords.add(rsp.getString("player")); } } } rsr = statement.executeQuery(queryr); if (rsr.isBeforeFirst()) { while (rsr.next()) { if (!timelords.contains(rsr.getString("player")) && !rsr.getString("player").isEmpty()) { timelords.add(rsr.getString("player")); } } } rss = statement.executeQuery(querys); if (rss.isBeforeFirst()) { while (rss.next()) { if (!timelords.contains(rss.getString("owner")) && !rss.getString("owner").isEmpty()) { timelords.add(rss.getString("owner")); } } } rsv = statement.executeQuery(queryv); if (rsv.isBeforeFirst()) { while (rsv.next()) { if (!timelords.contains(rsv.getString("player")) && !rsv.getString("player").isEmpty()) { timelords.add(rsv.getString("player")); } } } // don't bother if the player list is empty if (timelords.size() > 0) { TARDISUUIDFetcher fetcher = new TARDISUUIDFetcher(timelords); // get UUIDs Map<String, UUID> response = null; try { response = fetcher.call(); } catch (Exception e) { plugin.debug("Exception while running TARDISUUIDFetcher: " + e.getMessage()); return false; } if (response != null) { // update all TARDIS owners to UUIDs ps_ach = connection.prepareStatement(a_update); ps_ars = connection.prepareStatement(r_update); ps_sto = connection.prepareStatement(p_update); ps_pla = connection.prepareStatement(s_update); ps_tco = connection.prepareStatement(c_update); ps_tar = connection.prepareStatement(t_update); ps_tra = connection.prepareStatement(v_update); for (Map.Entry<String, UUID> map : response.entrySet()) { ps_ach.setString(1, map.getValue().toString()); ps_ach.setString(2, map.getKey()); count += ps_ach.executeUpdate(); ps_ars.setString(1, map.getValue().toString()); ps_ars.setString(2, map.getKey()); count += ps_ars.executeUpdate(); ps_pla.setString(1, map.getValue().toString()); ps_pla.setString(2, map.getKey()); count += ps_pla.executeUpdate(); ps_sto.setString(1, map.getValue().toString()); ps_sto.setString(2, map.getKey()); count += ps_sto.executeUpdate(); ps_tco.setString(1, map.getValue().toString()); ps_tco.setString(2, map.getKey()); count += ps_tco.executeUpdate(); ps_tar.setString(1, map.getValue().toString()); ps_tar.setString(2, map.getKey()); count += ps_tar.executeUpdate(); ps_tra.setString(1, map.getValue().toString()); ps_tra.setString(2, map.getKey()); count += ps_tra.executeUpdate(); } } } } catch (SQLException e) { plugin.debug("ResultSet error for UUID updating! " + e.getMessage()); return false; } finally { try { if (rsa != null) { rsa.close(); } if (rsc != null) { rsc.close(); } if (rsp != null) { rsp.close(); } if (rsr != null) { rsr.close(); } if (rss != null) { rss.close(); } if (rst != null) { rst.close(); } if (rsv != null) { rsv.close(); } if (statement != null) { statement.close(); } if (ps_ach != null) { ps_ach.close(); } if (ps_ars != null) { ps_ars.close(); } if (ps_pla != null) { ps_pla.close(); } if (ps_sto != null) { ps_sto.close(); } if (ps_tco != null) { ps_tco.close(); } if (ps_tar != null) { ps_tar.close(); } if (ps_tra != null) { ps_tra.close(); } } catch (SQLException e) { plugin.debug("Error closing tardis table! " + e.getMessage()); } } plugin.getConsole().sendMessage(plugin.getPluginName() + "Converted " + count + " Time Lord names to UUIDs."); return true; } /** * Gets the server default resource pack. Will use the Minecraft default * pack if none is specified. Until Minecraft/Bukkit lets us set the RP back * to Default, we'll have to host it on DropBox * * @return The server specified texture pack. */ public boolean getOnlineMode() { FileInputStream in = null; try { Properties properties = new Properties(); String path = "server.properties"; in = new FileInputStream(path); properties.load(in); String online = properties.getProperty("online-mode"); return (online != null && online.equalsIgnoreCase("true")); } catch (FileNotFoundException ex) { plugin.debug("Could not find server.properties!"); return false; } catch (IOException ex) { plugin.debug("Could not read server.properties!"); return false; } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { plugin.debug("Could not close server.properties!"); } } } }