SQLDatabaseManager.java 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713
  1. package com.gmail.nossr50.database;
  2. import java.sql.Connection;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.ResultSetMetaData;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.ArrayList;
  9. import java.util.EnumMap;
  10. import java.util.HashMap;
  11. import java.util.List;
  12. import java.util.Map;
  13. import java.util.UUID;
  14. import java.util.concurrent.locks.ReentrantLock;
  15. import org.bukkit.scheduler.BukkitRunnable;
  16. import com.gmail.nossr50.mcMMO;
  17. import com.gmail.nossr50.config.Config;
  18. import com.gmail.nossr50.datatypes.MobHealthbarType;
  19. import com.gmail.nossr50.datatypes.database.DatabaseType;
  20. import com.gmail.nossr50.datatypes.database.PlayerStat;
  21. import com.gmail.nossr50.datatypes.database.UpgradeType;
  22. import com.gmail.nossr50.datatypes.player.PlayerProfile;
  23. import com.gmail.nossr50.datatypes.skills.AbilityType;
  24. import com.gmail.nossr50.datatypes.skills.SkillType;
  25. import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
  26. import com.gmail.nossr50.util.Misc;
  27. import org.apache.tomcat.jdbc.pool.DataSource;
  28. import org.apache.tomcat.jdbc.pool.PoolProperties;
  29. public final class SQLDatabaseManager implements DatabaseManager {
  30. private static final String ALL_QUERY_VERSION = "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy";
  31. private String tablePrefix = Config.getInstance().getMySQLTablePrefix();
  32. private final Map<UUID, Integer> cachedUserIDs = new HashMap<UUID, Integer>();
  33. private DataSource miscPool;
  34. private DataSource loadPool;
  35. private DataSource savePool;
  36. private ReentrantLock massUpdateLock = new ReentrantLock();
  37. protected SQLDatabaseManager() {
  38. String connectionString = "jdbc:mysql://" + Config.getInstance().getMySQLServerName() + ":" + Config.getInstance().getMySQLServerPort() + "/" + Config.getInstance().getMySQLDatabaseName();
  39. try {
  40. // Force driver to load if not yet loaded
  41. Class.forName("com.mysql.jdbc.Driver");
  42. }
  43. catch (ClassNotFoundException e) {
  44. e.printStackTrace();
  45. return;
  46. //throw e; // aborts onEnable() Riking if you want to do this, fully implement it.
  47. }
  48. PoolProperties poolProperties = new PoolProperties();
  49. poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
  50. poolProperties.setUrl(connectionString);
  51. poolProperties.setUsername(Config.getInstance().getMySQLUserName());
  52. poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
  53. poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC));
  54. poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC));
  55. poolProperties.setInitialSize(0);
  56. poolProperties.setMaxWait(-1);
  57. poolProperties.setRemoveAbandoned(true);
  58. poolProperties.setRemoveAbandonedTimeout(60);
  59. poolProperties.setTestOnBorrow(true);
  60. poolProperties.setValidationQuery("SELECT 1");
  61. poolProperties.setValidationInterval(30000);
  62. miscPool = new DataSource(poolProperties);
  63. poolProperties = new PoolProperties();
  64. poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
  65. poolProperties.setUrl(connectionString);
  66. poolProperties.setUsername(Config.getInstance().getMySQLUserName());
  67. poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
  68. poolProperties.setInitialSize(0);
  69. poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE));
  70. poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE));
  71. poolProperties.setMaxWait(-1);
  72. poolProperties.setRemoveAbandoned(true);
  73. poolProperties.setRemoveAbandonedTimeout(60);
  74. poolProperties.setTestOnBorrow(true);
  75. poolProperties.setValidationQuery("SELECT 1");
  76. poolProperties.setValidationInterval(30000);
  77. savePool = new DataSource(poolProperties);
  78. poolProperties = new PoolProperties();
  79. poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
  80. poolProperties.setUrl(connectionString);
  81. poolProperties.setUsername(Config.getInstance().getMySQLUserName());
  82. poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
  83. poolProperties.setInitialSize(0);
  84. poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD));
  85. poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD));
  86. poolProperties.setMaxWait(-1);
  87. poolProperties.setRemoveAbandoned(true);
  88. poolProperties.setRemoveAbandonedTimeout(60);
  89. poolProperties.setTestOnBorrow(true);
  90. poolProperties.setValidationQuery("SELECT 1");
  91. poolProperties.setValidationInterval(30000);
  92. loadPool = new DataSource(poolProperties);
  93. checkStructure();
  94. }
  95. public void purgePowerlessUsers() {
  96. massUpdateLock.lock();
  97. mcMMO.p.getLogger().info("Purging powerless users...");
  98. Connection connection = null;
  99. Statement statement = null;
  100. int purged = 0;
  101. try {
  102. connection = getConnection(PoolIdentifier.MISC);
  103. statement = connection.createStatement();
  104. purged = statement.executeUpdate("DELETE FROM " + tablePrefix + "skills WHERE "
  105. + "taming = 0 AND mining = 0 AND woodcutting = 0 AND repair = 0 "
  106. + "AND unarmed = 0 AND herbalism = 0 AND excavation = 0 AND "
  107. + "archery = 0 AND swords = 0 AND axes = 0 AND acrobatics = 0 "
  108. + "AND fishing = 0 AND alchemy = 0;");
  109. statement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "experience`.`user_id` = `s`.`user_id`)");
  110. statement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "huds`.`user_id` = `s`.`user_id`)");
  111. statement.executeUpdate("DELETE FROM `" + tablePrefix + "cooldowns` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "cooldowns`.`user_id` = `s`.`user_id`)");
  112. statement.executeUpdate("DELETE FROM `" + tablePrefix + "users` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "skills` `s` WHERE `" + tablePrefix + "users`.`id` = `s`.`user_id`)");
  113. }
  114. catch (SQLException ex) {
  115. printErrors(ex);
  116. }
  117. finally {
  118. if (statement != null) {
  119. try {
  120. statement.close();
  121. }
  122. catch (SQLException e) {
  123. // Ignore
  124. }
  125. }
  126. if (connection != null) {
  127. try {
  128. connection.close();
  129. }
  130. catch (SQLException e) {
  131. // Ignore
  132. }
  133. }
  134. massUpdateLock.unlock();
  135. }
  136. mcMMO.p.getLogger().info("Purged " + purged + " users from the database.");
  137. }
  138. public void purgeOldUsers() {
  139. massUpdateLock.lock();
  140. mcMMO.p.getLogger().info("Purging inactive users older than " + (PURGE_TIME / 2630000000L) + " months...");
  141. Connection connection = null;
  142. Statement statement = null;
  143. int purged = 0;
  144. try {
  145. connection = getConnection(PoolIdentifier.MISC);
  146. statement = connection.createStatement();
  147. purged = statement.executeUpdate("DELETE FROM u, e, h, s, c USING " + tablePrefix + "users u " +
  148. "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " +
  149. "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " +
  150. "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " +
  151. "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " +
  152. "WHERE ((UNIX_TIMESTAMP() - lastlogin) > " + PURGE_TIME + ")");
  153. }
  154. catch (SQLException ex) {
  155. printErrors(ex);
  156. }
  157. finally {
  158. if (statement != null) {
  159. try {
  160. statement.close();
  161. }
  162. catch (SQLException e) {
  163. // Ignore
  164. }
  165. }
  166. if (connection != null) {
  167. try {
  168. connection.close();
  169. }
  170. catch (SQLException e) {
  171. // Ignore
  172. }
  173. }
  174. massUpdateLock.unlock();
  175. }
  176. mcMMO.p.getLogger().info("Purged " + purged + " users from the database.");
  177. }
  178. public boolean removeUser(String playerName) {
  179. boolean success = false;
  180. Connection connection = null;
  181. PreparedStatement statement = null;
  182. try {
  183. connection = getConnection(PoolIdentifier.MISC);
  184. statement = connection.prepareStatement("DELETE FROM u, e, h, s, c " +
  185. "USING " + tablePrefix + "users u " +
  186. "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) " +
  187. "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) " +
  188. "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) " +
  189. "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) " +
  190. "WHERE u.user = ?");
  191. statement.setString(1, playerName);
  192. success = statement.executeUpdate() != 0;
  193. }
  194. catch (SQLException ex) {
  195. printErrors(ex);
  196. }
  197. finally {
  198. if (statement != null) {
  199. try {
  200. statement.close();
  201. }
  202. catch (SQLException e) {
  203. // Ignore
  204. }
  205. }
  206. if (connection != null) {
  207. try {
  208. connection.close();
  209. }
  210. catch (SQLException e) {
  211. // Ignore
  212. }
  213. }
  214. }
  215. if (success) {
  216. Misc.profileCleanup(playerName);
  217. }
  218. return success;
  219. }
  220. public boolean saveUser(PlayerProfile profile) {
  221. boolean success = true;
  222. PreparedStatement statement = null;
  223. Connection connection = null;
  224. try {
  225. connection = getConnection(PoolIdentifier.SAVE);
  226. int id = getUserID(connection, profile.getPlayerName(), profile.getUniqueId());
  227. if (id == -1) {
  228. id = newUser(connection, profile.getPlayerName(), profile.getUniqueId());
  229. if (id == -1) {
  230. mcMMO.p.getLogger().severe("Failed to create new account for " + profile.getPlayerName());
  231. return false;
  232. }
  233. }
  234. statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET lastlogin = UNIX_TIMESTAMP() WHERE id = ?");
  235. statement.setInt(1, id);
  236. success &= (statement.executeUpdate() != 0);
  237. statement.close();
  238. if (!success) {
  239. mcMMO.p.getLogger().severe("Failed to update last login for " + profile.getPlayerName());
  240. return false;
  241. }
  242. statement = connection.prepareStatement("UPDATE " + tablePrefix + "skills SET "
  243. + " taming = ?, mining = ?, repair = ?, woodcutting = ?"
  244. + ", unarmed = ?, herbalism = ?, excavation = ?"
  245. + ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
  246. + ", fishing = ?, alchemy = ? WHERE user_id = ?");
  247. statement.setInt(1, profile.getSkillLevel(SkillType.TAMING));
  248. statement.setInt(2, profile.getSkillLevel(SkillType.MINING));
  249. statement.setInt(3, profile.getSkillLevel(SkillType.REPAIR));
  250. statement.setInt(4, profile.getSkillLevel(SkillType.WOODCUTTING));
  251. statement.setInt(5, profile.getSkillLevel(SkillType.UNARMED));
  252. statement.setInt(6, profile.getSkillLevel(SkillType.HERBALISM));
  253. statement.setInt(7, profile.getSkillLevel(SkillType.EXCAVATION));
  254. statement.setInt(8, profile.getSkillLevel(SkillType.ARCHERY));
  255. statement.setInt(9, profile.getSkillLevel(SkillType.SWORDS));
  256. statement.setInt(10, profile.getSkillLevel(SkillType.AXES));
  257. statement.setInt(11, profile.getSkillLevel(SkillType.ACROBATICS));
  258. statement.setInt(12, profile.getSkillLevel(SkillType.FISHING));
  259. statement.setInt(13, profile.getSkillLevel(SkillType.ALCHEMY));
  260. statement.setInt(14, id);
  261. success &= (statement.executeUpdate() != 0);
  262. statement.close();
  263. if (!success) {
  264. mcMMO.p.getLogger().severe("Failed to update skills for " + profile.getPlayerName());
  265. return false;
  266. }
  267. statement = connection.prepareStatement("UPDATE " + tablePrefix + "experience SET "
  268. + " taming = ?, mining = ?, repair = ?, woodcutting = ?"
  269. + ", unarmed = ?, herbalism = ?, excavation = ?"
  270. + ", archery = ?, swords = ?, axes = ?, acrobatics = ?"
  271. + ", fishing = ?, alchemy = ? WHERE user_id = ?");
  272. statement.setInt(1, profile.getSkillXpLevel(SkillType.TAMING));
  273. statement.setInt(2, profile.getSkillXpLevel(SkillType.MINING));
  274. statement.setInt(3, profile.getSkillXpLevel(SkillType.REPAIR));
  275. statement.setInt(4, profile.getSkillXpLevel(SkillType.WOODCUTTING));
  276. statement.setInt(5, profile.getSkillXpLevel(SkillType.UNARMED));
  277. statement.setInt(6, profile.getSkillXpLevel(SkillType.HERBALISM));
  278. statement.setInt(7, profile.getSkillXpLevel(SkillType.EXCAVATION));
  279. statement.setInt(8, profile.getSkillXpLevel(SkillType.ARCHERY));
  280. statement.setInt(9, profile.getSkillXpLevel(SkillType.SWORDS));
  281. statement.setInt(10, profile.getSkillXpLevel(SkillType.AXES));
  282. statement.setInt(11, profile.getSkillXpLevel(SkillType.ACROBATICS));
  283. statement.setInt(12, profile.getSkillXpLevel(SkillType.FISHING));
  284. statement.setInt(13, profile.getSkillXpLevel(SkillType.ALCHEMY));
  285. statement.setInt(14, id);
  286. success &= (statement.executeUpdate() != 0);
  287. statement.close();
  288. if (!success) {
  289. mcMMO.p.getLogger().severe("Failed to update experience for " + profile.getPlayerName());
  290. return false;
  291. }
  292. statement = connection.prepareStatement("UPDATE " + tablePrefix + "cooldowns SET "
  293. + " mining = ?, woodcutting = ?, unarmed = ?"
  294. + ", herbalism = ?, excavation = ?, swords = ?"
  295. + ", axes = ?, blast_mining = ? WHERE user_id = ?");
  296. statement.setLong(1, profile.getAbilityDATS(AbilityType.SUPER_BREAKER));
  297. statement.setLong(2, profile.getAbilityDATS(AbilityType.TREE_FELLER));
  298. statement.setLong(3, profile.getAbilityDATS(AbilityType.BERSERK));
  299. statement.setLong(4, profile.getAbilityDATS(AbilityType.GREEN_TERRA));
  300. statement.setLong(5, profile.getAbilityDATS(AbilityType.GIGA_DRILL_BREAKER));
  301. statement.setLong(6, profile.getAbilityDATS(AbilityType.SERRATED_STRIKES));
  302. statement.setLong(7, profile.getAbilityDATS(AbilityType.SKULL_SPLITTER));
  303. statement.setLong(8, profile.getAbilityDATS(AbilityType.BLAST_MINING));
  304. statement.setInt(9, id);
  305. success = (statement.executeUpdate() != 0);
  306. statement.close();
  307. if (!success) {
  308. mcMMO.p.getLogger().severe("Failed to update cooldowns for " + profile.getPlayerName());
  309. return false;
  310. }
  311. statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?, scoreboardtips = ? WHERE user_id = ?");
  312. statement.setString(1, profile.getMobHealthbarType() == null ? Config.getInstance().getMobHealthbarDefault().name() : profile.getMobHealthbarType().name());
  313. statement.setInt(2, profile.getScoreboardTipsShown());
  314. statement.setInt(3, id);
  315. success = (statement.executeUpdate() != 0);
  316. statement.close();
  317. if (!success) {
  318. mcMMO.p.getLogger().severe("Failed to update hud settings for " + profile.getPlayerName());
  319. return false;
  320. }
  321. }
  322. catch (SQLException ex) {
  323. printErrors(ex);
  324. }
  325. finally {
  326. if (statement != null) {
  327. try {
  328. statement.close();
  329. }
  330. catch (SQLException e) {
  331. // Ignore
  332. }
  333. }
  334. if (connection != null) {
  335. try {
  336. connection.close();
  337. }
  338. catch (SQLException e) {
  339. // Ignore
  340. }
  341. }
  342. }
  343. return success;
  344. }
  345. public List<PlayerStat> readLeaderboard(SkillType skill, int pageNumber, int statsPerPage) {
  346. List<PlayerStat> stats = new ArrayList<PlayerStat>();
  347. String query = skill == null ? ALL_QUERY_VERSION : skill.name().toLowerCase();
  348. ResultSet resultSet = null;
  349. PreparedStatement statement = null;
  350. Connection connection = null;
  351. try {
  352. connection = getConnection(PoolIdentifier.MISC);
  353. statement = connection.prepareStatement("SELECT " + query + ", user, NOW() FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON (user_id = id) WHERE " + query + " > 0 AND NOT user = '\\_INVALID\\_OLD\\_USERNAME\\_' ORDER BY " + query + " DESC, user LIMIT ?, ?");
  354. statement.setInt(1, (pageNumber * statsPerPage) - statsPerPage);
  355. statement.setInt(2, statsPerPage);
  356. resultSet = statement.executeQuery();
  357. while (resultSet.next()) {
  358. ArrayList<String> column = new ArrayList<String>();
  359. for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
  360. column.add(resultSet.getString(i));
  361. }
  362. stats.add(new PlayerStat(column.get(1), Integer.valueOf(column.get(0))));
  363. }
  364. }
  365. catch (SQLException ex) {
  366. printErrors(ex);
  367. }
  368. finally {
  369. if (resultSet != null) {
  370. try {
  371. resultSet.close();
  372. }
  373. catch (SQLException e) {
  374. // Ignore
  375. }
  376. }
  377. if (statement != null) {
  378. try {
  379. statement.close();
  380. }
  381. catch (SQLException e) {
  382. // Ignore
  383. }
  384. }
  385. if (connection != null) {
  386. try {
  387. connection.close();
  388. }
  389. catch (SQLException e) {
  390. // Ignore
  391. }
  392. }
  393. }
  394. return stats;
  395. }
  396. public Map<SkillType, Integer> readRank(String playerName) {
  397. Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>();
  398. ResultSet resultSet = null;
  399. PreparedStatement statement = null;
  400. Connection connection = null;
  401. try {
  402. connection = getConnection(PoolIdentifier.MISC);
  403. for (SkillType skillType : SkillType.NON_CHILD_SKILLS) {
  404. String skillName = skillType.name().toLowerCase();
  405. String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
  406. "AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
  407. "WHERE user = ?)";
  408. statement = connection.prepareStatement(sql);
  409. statement.setString(1, playerName);
  410. resultSet = statement.executeQuery();
  411. resultSet.next();
  412. int rank = resultSet.getInt("rank");
  413. sql = "SELECT user, " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
  414. "AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
  415. "WHERE user = '" + playerName + "') ORDER BY user";
  416. resultSet.close();
  417. statement.close();
  418. statement = connection.prepareStatement(sql);
  419. resultSet = statement.executeQuery();
  420. while (resultSet.next()) {
  421. if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
  422. skills.put(skillType, rank + resultSet.getRow());
  423. break;
  424. }
  425. }
  426. resultSet.close();
  427. statement.close();
  428. }
  429. String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
  430. "WHERE " + ALL_QUERY_VERSION + " > 0 " +
  431. "AND " + ALL_QUERY_VERSION + " > " +
  432. "(SELECT " + ALL_QUERY_VERSION + " " +
  433. "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?)";
  434. statement = connection.prepareStatement(sql);
  435. statement.setString(1, playerName);
  436. resultSet = statement.executeQuery();
  437. resultSet.next();
  438. int rank = resultSet.getInt("rank");
  439. resultSet.close();
  440. statement.close();
  441. sql = "SELECT user, " + ALL_QUERY_VERSION + " " +
  442. "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
  443. "WHERE " + ALL_QUERY_VERSION + " > 0 " +
  444. "AND " + ALL_QUERY_VERSION + " = " +
  445. "(SELECT " + ALL_QUERY_VERSION + " " +
  446. "FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE user = ?) ORDER BY user";
  447. statement = connection.prepareStatement(sql);
  448. statement.setString(1, playerName);
  449. resultSet = statement.executeQuery();
  450. while (resultSet.next()) {
  451. if (resultSet.getString("user").equalsIgnoreCase(playerName)) {
  452. skills.put(null, rank + resultSet.getRow());
  453. break;
  454. }
  455. }
  456. resultSet.close();
  457. statement.close();
  458. }
  459. catch (SQLException ex) {
  460. printErrors(ex);
  461. }
  462. finally {
  463. if (resultSet != null) {
  464. try {
  465. resultSet.close();
  466. }
  467. catch (SQLException e) {
  468. // Ignore
  469. }
  470. }
  471. if (statement != null) {
  472. try {
  473. statement.close();
  474. }
  475. catch (SQLException e) {
  476. // Ignore
  477. }
  478. }
  479. if (connection != null) {
  480. try {
  481. connection.close();
  482. }
  483. catch (SQLException e) {
  484. // Ignore
  485. }
  486. }
  487. }
  488. return skills;
  489. }
  490. public void newUser(String playerName, UUID uuid) {
  491. Connection connection = null;
  492. try {
  493. connection = getConnection(PoolIdentifier.MISC);
  494. newUser(connection, playerName, uuid);
  495. }
  496. catch (SQLException ex) {
  497. printErrors(ex);
  498. }
  499. finally {
  500. if (connection != null) {
  501. try {
  502. connection.close();
  503. }
  504. catch (SQLException e) {
  505. // Ignore
  506. }
  507. }
  508. }
  509. }
  510. private int newUser(Connection connection, String playerName, UUID uuid) {
  511. ResultSet resultSet = null;
  512. PreparedStatement statement = null;
  513. try {
  514. statement = connection.prepareStatement(
  515. "UPDATE `" + tablePrefix + "users` "
  516. + "SET user = ? "
  517. + "WHERE user = ?");
  518. statement.setString(1, "_INVALID_OLD_USERNAME_");
  519. statement.setString(2, playerName);
  520. statement.executeUpdate();
  521. statement.close();
  522. statement = connection.prepareStatement("INSERT INTO " + tablePrefix + "users (user, uuid, lastlogin) VALUES (?, ?, UNIX_TIMESTAMP())", Statement.RETURN_GENERATED_KEYS);
  523. statement.setString(1, playerName);
  524. statement.setString(2, uuid != null ? uuid.toString() : null);
  525. statement.executeUpdate();
  526. resultSet = statement.getGeneratedKeys();
  527. if (!resultSet.next()) {
  528. mcMMO.p.getLogger().severe("Unable to create new user account in DB");
  529. return -1;
  530. }
  531. writeMissingRows(connection, resultSet.getInt(1));
  532. return resultSet.getInt(1);
  533. }
  534. catch (SQLException ex) {
  535. printErrors(ex);
  536. }
  537. finally {
  538. if (resultSet != null) {
  539. try {
  540. resultSet.close();
  541. }
  542. catch (SQLException e) {
  543. // Ignore
  544. }
  545. }
  546. if (statement != null) {
  547. try {
  548. statement.close();
  549. }
  550. catch (SQLException e) {
  551. // Ignore
  552. }
  553. }
  554. }
  555. return -1;
  556. }
  557. @Deprecated
  558. public PlayerProfile loadPlayerProfile(String playerName, boolean create) {
  559. return loadPlayerProfile(playerName, null, false, true);
  560. }
  561. public PlayerProfile loadPlayerProfile(UUID uuid) {
  562. return loadPlayerProfile("", uuid, false, true);
  563. }
  564. public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create) {
  565. return loadPlayerProfile(playerName, uuid, create, true);
  566. }
  567. private PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create, boolean retry) {
  568. PreparedStatement statement = null;
  569. Connection connection = null;
  570. ResultSet resultSet = null;
  571. try {
  572. connection = getConnection(PoolIdentifier.LOAD);
  573. int id = getUserID(connection, playerName, uuid);
  574. if (id == -1) {
  575. // There is no such user
  576. if (create) {
  577. id = newUser(connection, playerName, uuid);
  578. create = false;
  579. if (id == -1) {
  580. return new PlayerProfile(playerName, false);
  581. }
  582. } else {
  583. return new PlayerProfile(playerName, false);
  584. }
  585. }
  586. // There is such a user
  587. writeMissingRows(connection, id);
  588. statement = connection.prepareStatement(
  589. "SELECT "
  590. + "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, "
  591. + "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, "
  592. + "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, "
  593. + "h.mobhealthbar, h.scoreboardtips, u.uuid, u.user "
  594. + "FROM " + tablePrefix + "users u "
  595. + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
  596. + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) "
  597. + "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) "
  598. + "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) "
  599. + "WHERE u.id = ?");
  600. statement.setInt(1, id);
  601. resultSet = statement.executeQuery();
  602. if (resultSet.next()) {
  603. try {
  604. PlayerProfile profile = loadFromResult(playerName, resultSet);
  605. String name = resultSet.getString(42); // TODO: Magic Number, make sure it stays updated
  606. resultSet.close();
  607. statement.close();
  608. if (!playerName.isEmpty() && !playerName.equals(name)) {
  609. statement = connection.prepareStatement(
  610. "UPDATE `" + tablePrefix + "users` "
  611. + "SET user = ? "
  612. + "WHERE user = ?");
  613. statement.setString(1, "_INVALID_OLD_USERNAME_");
  614. statement.setString(2, name);
  615. statement.executeUpdate();
  616. statement.close();
  617. statement = connection.prepareStatement(
  618. "UPDATE `" + tablePrefix + "users` "
  619. + "SET user = ?, uuid = ? "
  620. + "WHERE id = ?");
  621. statement.setString(1, playerName);
  622. statement.setString(2, uuid.toString());
  623. statement.setInt(3, id);
  624. statement.executeUpdate();
  625. statement.close();
  626. }
  627. return profile;
  628. }
  629. catch (SQLException e) {
  630. printErrors(e);
  631. }
  632. }
  633. resultSet.close();
  634. }
  635. catch (SQLException ex) {
  636. printErrors(ex);
  637. }
  638. finally {
  639. if (resultSet != null) {
  640. try {
  641. resultSet.close();
  642. }
  643. catch (SQLException e) {
  644. // Ignore
  645. }
  646. }
  647. if (statement != null) {
  648. try {
  649. statement.close();
  650. }
  651. catch (SQLException e) {
  652. // Ignore
  653. }
  654. }
  655. if (connection != null) {
  656. try {
  657. connection.close();
  658. }
  659. catch (SQLException e) {
  660. // Ignore
  661. }
  662. }
  663. }
  664. // Problem, nothing was returned
  665. // return unloaded profile
  666. if (!retry) {
  667. return new PlayerProfile(playerName, false);
  668. }
  669. // Retry, and abort on re-failure
  670. return loadPlayerProfile(playerName, uuid, create, false);
  671. }
  672. public void convertUsers(DatabaseManager destination) {
  673. PreparedStatement statement = null;
  674. Connection connection = null;
  675. ResultSet resultSet = null;
  676. try {
  677. connection = getConnection(PoolIdentifier.MISC);
  678. statement = connection.prepareStatement(
  679. "SELECT "
  680. + "s.taming, s.mining, s.repair, s.woodcutting, s.unarmed, s.herbalism, s.excavation, s.archery, s.swords, s.axes, s.acrobatics, s.fishing, s.alchemy, "
  681. + "e.taming, e.mining, e.repair, e.woodcutting, e.unarmed, e.herbalism, e.excavation, e.archery, e.swords, e.axes, e.acrobatics, e.fishing, e.alchemy, "
  682. + "c.taming, c.mining, c.repair, c.woodcutting, c.unarmed, c.herbalism, c.excavation, c.archery, c.swords, c.axes, c.acrobatics, c.blast_mining, "
  683. + "h.mobhealthbar, h.scoreboardtips, u.uuid "
  684. + "FROM " + tablePrefix + "users u "
  685. + "JOIN " + tablePrefix + "skills s ON (u.id = s.user_id) "
  686. + "JOIN " + tablePrefix + "experience e ON (u.id = e.user_id) "
  687. + "JOIN " + tablePrefix + "cooldowns c ON (u.id = c.user_id) "
  688. + "JOIN " + tablePrefix + "huds h ON (u.id = h.user_id) "
  689. + "WHERE u.user = ?");
  690. List<String> usernames = getStoredUsers();
  691. int convertedUsers = 0;
  692. long startMillis = System.currentTimeMillis();
  693. for (String playerName : usernames) {
  694. statement.setString(1, playerName);
  695. try {
  696. resultSet = statement.executeQuery();
  697. resultSet.next();
  698. destination.saveUser(loadFromResult(playerName, resultSet));
  699. resultSet.close();
  700. }
  701. catch (SQLException e) {
  702. printErrors(e);
  703. // Ignore
  704. }
  705. convertedUsers++;
  706. Misc.printProgress(convertedUsers, progressInterval, startMillis);
  707. }
  708. }
  709. catch (SQLException e) {
  710. printErrors(e);
  711. }
  712. finally {
  713. if (resultSet != null) {
  714. try {
  715. resultSet.close();
  716. }
  717. catch (SQLException e) {
  718. // Ignore
  719. }
  720. }
  721. if (statement != null) {
  722. try {
  723. statement.close();
  724. }
  725. catch (SQLException e) {
  726. // Ignore
  727. }
  728. }
  729. if (connection != null) {
  730. try {
  731. connection.close();
  732. }
  733. catch (SQLException e) {
  734. // Ignore
  735. }
  736. }
  737. }
  738. }
  739. public boolean saveUserUUID(String userName, UUID uuid) {
  740. PreparedStatement statement = null;
  741. Connection connection = null;
  742. try {
  743. connection = getConnection(PoolIdentifier.MISC);
  744. statement = connection.prepareStatement(
  745. "UPDATE `" + tablePrefix + "users` SET "
  746. + " uuid = ? WHERE user = ?");
  747. statement.setString(1, uuid.toString());
  748. statement.setString(2, userName);
  749. statement.execute();
  750. return true;
  751. }
  752. catch (SQLException ex) {
  753. printErrors(ex);
  754. return false;
  755. }
  756. finally {
  757. if (statement != null) {
  758. try {
  759. statement.close();
  760. }
  761. catch (SQLException e) {
  762. // Ignore
  763. }
  764. }
  765. if (connection != null) {
  766. try {
  767. connection.close();
  768. }
  769. catch (SQLException e) {
  770. // Ignore
  771. }
  772. }
  773. }
  774. }
  775. public boolean saveUserUUIDs(Map<String, UUID> fetchedUUIDs) {
  776. PreparedStatement statement = null;
  777. int count = 0;
  778. Connection connection = null;
  779. try {
  780. connection = getConnection(PoolIdentifier.MISC);
  781. statement = connection.prepareStatement("UPDATE " + tablePrefix + "users SET uuid = ? WHERE user = ?");
  782. for (Map.Entry<String, UUID> entry : fetchedUUIDs.entrySet()) {
  783. statement.setString(1, entry.getValue().toString());
  784. statement.setString(2, entry.getKey());
  785. statement.addBatch();
  786. count++;
  787. if ((count % 500) == 0) {
  788. statement.executeBatch();
  789. count = 0;
  790. }
  791. }
  792. if (count != 0) {
  793. statement.executeBatch();
  794. }
  795. return true;
  796. }
  797. catch (SQLException ex) {
  798. printErrors(ex);
  799. return false;
  800. }
  801. finally {
  802. if (statement != null) {
  803. try {
  804. statement.close();
  805. }
  806. catch (SQLException e) {
  807. // Ignore
  808. }
  809. }
  810. if (connection != null) {
  811. try {
  812. connection.close();
  813. }
  814. catch (SQLException e) {
  815. // Ignore
  816. }
  817. }
  818. }
  819. }
  820. public List<String> getStoredUsers() {
  821. ArrayList<String> users = new ArrayList<String>();
  822. Statement statement = null;
  823. Connection connection = null;
  824. ResultSet resultSet = null;
  825. try {
  826. connection = getConnection(PoolIdentifier.MISC);
  827. statement = connection.createStatement();
  828. resultSet = statement.executeQuery("SELECT user FROM " + tablePrefix + "users");
  829. while (resultSet.next()) {
  830. users.add(resultSet.getString("user"));
  831. }
  832. }
  833. catch (SQLException e) {
  834. printErrors(e);
  835. }
  836. finally {
  837. if (resultSet != null) {
  838. try {
  839. resultSet.close();
  840. }
  841. catch (SQLException e) {
  842. // Ignore
  843. }
  844. }
  845. if (statement != null) {
  846. try {
  847. statement.close();
  848. }
  849. catch (SQLException e) {
  850. // Ignore
  851. }
  852. }
  853. if (connection != null) {
  854. try {
  855. connection.close();
  856. }
  857. catch (SQLException e) {
  858. // Ignore
  859. }
  860. }
  861. }
  862. return users;
  863. }
  864. /**
  865. * Checks that the database structure is present and correct
  866. */
  867. private void checkStructure() {
  868. PreparedStatement statement = null;
  869. Statement createStatement = null;
  870. ResultSet resultSet = null;
  871. Connection connection = null;
  872. try {
  873. connection = getConnection(PoolIdentifier.MISC);
  874. statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES"
  875. + " WHERE table_schema = ?"
  876. + " AND table_name = ?");
  877. statement.setString(1, Config.getInstance().getMySQLDatabaseName());
  878. statement.setString(2, tablePrefix + "users");
  879. resultSet = statement.executeQuery();
  880. if (!resultSet.next()) {
  881. createStatement = connection.createStatement();
  882. createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "users` ("
  883. + "`id` int(10) unsigned NOT NULL AUTO_INCREMENT,"
  884. + "`user` varchar(40) NOT NULL,"
  885. + "`uuid` varchar(36) NULL DEFAULT NULL,"
  886. + "`lastlogin` int(32) unsigned NOT NULL,"
  887. + "PRIMARY KEY (`id`),"
  888. + "INDEX(`user`(20) ASC),"
  889. + "UNIQUE KEY `uuid` (`uuid`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;");
  890. createStatement.close();
  891. }
  892. resultSet.close();
  893. statement.setString(1, Config.getInstance().getMySQLDatabaseName());
  894. statement.setString(2, tablePrefix + "huds");
  895. resultSet = statement.executeQuery();
  896. if (!resultSet.next()) {
  897. createStatement = connection.createStatement();
  898. createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
  899. + "`user_id` int(10) unsigned NOT NULL,"
  900. + "`mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "',"
  901. + "`scoreboardtips` int(10) NOT NULL DEFAULT '0',"
  902. + "PRIMARY KEY (`user_id`)) "
  903. + "DEFAULT CHARSET=latin1;");
  904. createStatement.close();
  905. }
  906. resultSet.close();
  907. statement.setString(1, Config.getInstance().getMySQLDatabaseName());
  908. statement.setString(2, tablePrefix + "cooldowns");
  909. resultSet = statement.executeQuery();
  910. if (!resultSet.next()) {
  911. createStatement = connection.createStatement();
  912. createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "cooldowns` ("
  913. + "`user_id` int(10) unsigned NOT NULL,"
  914. + "`taming` int(32) unsigned NOT NULL DEFAULT '0',"
  915. + "`mining` int(32) unsigned NOT NULL DEFAULT '0',"
  916. + "`woodcutting` int(32) unsigned NOT NULL DEFAULT '0',"
  917. + "`repair` int(32) unsigned NOT NULL DEFAULT '0',"
  918. + "`unarmed` int(32) unsigned NOT NULL DEFAULT '0',"
  919. + "`herbalism` int(32) unsigned NOT NULL DEFAULT '0',"
  920. + "`excavation` int(32) unsigned NOT NULL DEFAULT '0',"
  921. + "`archery` int(32) unsigned NOT NULL DEFAULT '0',"
  922. + "`swords` int(32) unsigned NOT NULL DEFAULT '0',"
  923. + "`axes` int(32) unsigned NOT NULL DEFAULT '0',"
  924. + "`acrobatics` int(32) unsigned NOT NULL DEFAULT '0',"
  925. + "`blast_mining` int(32) unsigned NOT NULL DEFAULT '0',"
  926. + "PRIMARY KEY (`user_id`)) "
  927. + "DEFAULT CHARSET=latin1;");
  928. createStatement.close();
  929. }
  930. resultSet.close();
  931. statement.setString(1, Config.getInstance().getMySQLDatabaseName());
  932. statement.setString(2, tablePrefix + "skills");
  933. resultSet = statement.executeQuery();
  934. if (!resultSet.next()) {
  935. createStatement = connection.createStatement();
  936. createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "skills` ("
  937. + "`user_id` int(10) unsigned NOT NULL,"
  938. + "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
  939. + "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
  940. + "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
  941. + "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
  942. + "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
  943. + "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
  944. + "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
  945. + "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
  946. + "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
  947. + "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
  948. + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
  949. + "`fishing` int(10) unsigned NOT NULL DEFAULT '0',"
  950. + "`alchemy` int(10) unsigned NOT NULL DEFAULT '0',"
  951. + "PRIMARY KEY (`user_id`)) "
  952. + "DEFAULT CHARSET=latin1;");
  953. createStatement.close();
  954. }
  955. resultSet.close();
  956. statement.setString(1, Config.getInstance().getMySQLDatabaseName());
  957. statement.setString(2, tablePrefix + "experience");
  958. resultSet = statement.executeQuery();
  959. if (!resultSet.next()) {
  960. createStatement = connection.createStatement();
  961. createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "experience` ("
  962. + "`user_id` int(10) unsigned NOT NULL,"
  963. + "`taming` int(10) unsigned NOT NULL DEFAULT '0',"
  964. + "`mining` int(10) unsigned NOT NULL DEFAULT '0',"
  965. + "`woodcutting` int(10) unsigned NOT NULL DEFAULT '0',"
  966. + "`repair` int(10) unsigned NOT NULL DEFAULT '0',"
  967. + "`unarmed` int(10) unsigned NOT NULL DEFAULT '0',"
  968. + "`herbalism` int(10) unsigned NOT NULL DEFAULT '0',"
  969. + "`excavation` int(10) unsigned NOT NULL DEFAULT '0',"
  970. + "`archery` int(10) unsigned NOT NULL DEFAULT '0',"
  971. + "`swords` int(10) unsigned NOT NULL DEFAULT '0',"
  972. + "`axes` int(10) unsigned NOT NULL DEFAULT '0',"
  973. + "`acrobatics` int(10) unsigned NOT NULL DEFAULT '0',"
  974. + "`fishing` int(10) unsigned NOT NULL DEFAULT '0',"
  975. + "`alchemy` int(10) unsigned NOT NULL DEFAULT '0',"
  976. + "PRIMARY KEY (`user_id`)) "
  977. + "DEFAULT CHARSET=latin1;");
  978. createStatement.close();
  979. }
  980. resultSet.close();
  981. statement.close();
  982. for (UpgradeType updateType : UpgradeType.values()) {
  983. checkDatabaseStructure(connection, updateType);
  984. }
  985. mcMMO.p.getLogger().info("Killing orphans");
  986. createStatement = connection.createStatement();
  987. createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "experience` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "experience`.`user_id` = `u`.`id`)");
  988. createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "huds` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "huds`.`user_id` = `u`.`id`)");
  989. createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "cooldowns` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "cooldowns`.`user_id` = `u`.`id`)");
  990. createStatement.executeUpdate("DELETE FROM `" + tablePrefix + "skills` WHERE NOT EXISTS (SELECT * FROM `" + tablePrefix + "users` `u` WHERE `" + tablePrefix + "skills`.`user_id` = `u`.`id`)");
  991. }
  992. catch (SQLException ex) {
  993. printErrors(ex);
  994. }
  995. finally {
  996. if (resultSet != null) {
  997. try {
  998. resultSet.close();
  999. }
  1000. catch (SQLException e) {
  1001. // Ignore
  1002. }
  1003. }
  1004. if (statement != null) {
  1005. try {
  1006. statement.close();
  1007. }
  1008. catch (SQLException e) {
  1009. // Ignore
  1010. }
  1011. }
  1012. if (createStatement != null) {
  1013. try {
  1014. createStatement.close();
  1015. }
  1016. catch (SQLException e) {
  1017. // Ignore
  1018. }
  1019. }
  1020. if (connection != null) {
  1021. try {
  1022. connection.close();
  1023. }
  1024. catch (SQLException e) {
  1025. // Ignore
  1026. }
  1027. }
  1028. }
  1029. }
  1030. private Connection getConnection(PoolIdentifier identifier) throws SQLException {
  1031. Connection connection = null;
  1032. switch (identifier) {
  1033. case LOAD:
  1034. connection = loadPool.getConnection();
  1035. break;
  1036. case MISC:
  1037. connection = miscPool.getConnection();
  1038. break;
  1039. case SAVE:
  1040. connection = savePool.getConnection();
  1041. break;
  1042. }
  1043. if (connection == null) {
  1044. throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase() + " pool timed out. Increase max connections settings.");
  1045. }
  1046. return connection;
  1047. }
  1048. /**
  1049. * Check database structure for necessary upgrades.
  1050. *
  1051. * @param upgrade Upgrade to attempt to apply
  1052. */
  1053. private void checkDatabaseStructure(Connection connection, UpgradeType upgrade) {
  1054. if (!mcMMO.getUpgradeManager().shouldUpgrade(upgrade)) {
  1055. mcMMO.p.debug("Skipping " + upgrade.name() + " upgrade (unneeded)");
  1056. return;
  1057. }
  1058. Statement statement = null;
  1059. try {
  1060. statement = connection.createStatement();
  1061. switch (upgrade) {
  1062. case ADD_FISHING:
  1063. checkUpgradeAddFishing(statement);
  1064. break;
  1065. case ADD_BLAST_MINING_COOLDOWN:
  1066. checkUpgradeAddBlastMiningCooldown(statement);
  1067. break;
  1068. case ADD_SQL_INDEXES:
  1069. checkUpgradeAddSQLIndexes(statement);
  1070. break;
  1071. case ADD_MOB_HEALTHBARS:
  1072. checkUpgradeAddMobHealthbars(statement);
  1073. break;
  1074. case DROP_SQL_PARTY_NAMES:
  1075. checkUpgradeDropPartyNames(statement);
  1076. break;
  1077. case DROP_SPOUT:
  1078. checkUpgradeDropSpout(statement);
  1079. break;
  1080. case ADD_ALCHEMY:
  1081. checkUpgradeAddAlchemy(statement);
  1082. break;
  1083. case ADD_UUIDS:
  1084. checkUpgradeAddUUIDs(statement);
  1085. return;
  1086. case ADD_SCOREBOARD_TIPS:
  1087. checkUpgradeAddScoreboardTips(statement);
  1088. return;
  1089. case DROP_NAME_UNIQUENESS:
  1090. checkNameUniqueness(statement);
  1091. return;
  1092. default:
  1093. break;
  1094. }
  1095. mcMMO.getUpgradeManager().setUpgradeCompleted(upgrade);
  1096. }
  1097. catch (SQLException ex) {
  1098. printErrors(ex);
  1099. }
  1100. finally {
  1101. if (statement != null) {
  1102. try {
  1103. statement.close();
  1104. }
  1105. catch (SQLException e) {
  1106. // Ignore
  1107. }
  1108. }
  1109. }
  1110. }
  1111. private void writeMissingRows(Connection connection, int id) {
  1112. PreparedStatement statement = null;
  1113. try {
  1114. statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "experience (user_id) VALUES (?)");
  1115. statement.setInt(1, id);
  1116. statement.execute();
  1117. statement.close();
  1118. statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "skills (user_id) VALUES (?)");
  1119. statement.setInt(1, id);
  1120. statement.execute();
  1121. statement.close();
  1122. statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "cooldowns (user_id) VALUES (?)");
  1123. statement.setInt(1, id);
  1124. statement.execute();
  1125. statement.close();
  1126. statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "huds (user_id, mobhealthbar, scoreboardtips) VALUES (?, ?, ?)");
  1127. statement.setInt(1, id);
  1128. statement.setString(2, Config.getInstance().getMobHealthbarDefault().name());
  1129. statement.setInt(3, 0);
  1130. statement.execute();
  1131. statement.close();
  1132. }
  1133. catch (SQLException ex) {
  1134. printErrors(ex);
  1135. }
  1136. finally {
  1137. if (statement != null) {
  1138. try {
  1139. statement.close();
  1140. }
  1141. catch (SQLException e) {
  1142. // Ignore
  1143. }
  1144. }
  1145. }
  1146. }
  1147. private PlayerProfile loadFromResult(String playerName, ResultSet result) throws SQLException {
  1148. Map<SkillType, Integer> skills = new EnumMap<SkillType, Integer>(SkillType.class); // Skill & Level
  1149. Map<SkillType, Float> skillsXp = new EnumMap<SkillType, Float>(SkillType.class); // Skill & XP
  1150. Map<AbilityType, Integer> skillsDATS = new EnumMap<AbilityType, Integer>(AbilityType.class); // Ability & Cooldown
  1151. MobHealthbarType mobHealthbarType;
  1152. UUID uuid;
  1153. int scoreboardTipsShown;
  1154. final int OFFSET_SKILLS = 0; // TODO update these numbers when the query
  1155. // changes (a new skill is added)
  1156. final int OFFSET_XP = 13;
  1157. final int OFFSET_DATS = 26;
  1158. final int OFFSET_OTHER = 38;
  1159. skills.put(SkillType.TAMING, result.getInt(OFFSET_SKILLS + 1));
  1160. skills.put(SkillType.MINING, result.getInt(OFFSET_SKILLS + 2));
  1161. skills.put(SkillType.REPAIR, result.getInt(OFFSET_SKILLS + 3));
  1162. skills.put(SkillType.WOODCUTTING, result.getInt(OFFSET_SKILLS + 4));
  1163. skills.put(SkillType.UNARMED, result.getInt(OFFSET_SKILLS + 5));
  1164. skills.put(SkillType.HERBALISM, result.getInt(OFFSET_SKILLS + 6));
  1165. skills.put(SkillType.EXCAVATION, result.getInt(OFFSET_SKILLS + 7));
  1166. skills.put(SkillType.ARCHERY, result.getInt(OFFSET_SKILLS + 8));
  1167. skills.put(SkillType.SWORDS, result.getInt(OFFSET_SKILLS + 9));
  1168. skills.put(SkillType.AXES, result.getInt(OFFSET_SKILLS + 10));
  1169. skills.put(SkillType.ACROBATICS, result.getInt(OFFSET_SKILLS + 11));
  1170. skills.put(SkillType.FISHING, result.getInt(OFFSET_SKILLS + 12));
  1171. skills.put(SkillType.ALCHEMY, result.getInt(OFFSET_SKILLS + 13));
  1172. skillsXp.put(SkillType.TAMING, result.getFloat(OFFSET_XP + 1));
  1173. skillsXp.put(SkillType.MINING, result.getFloat(OFFSET_XP + 2));
  1174. skillsXp.put(SkillType.REPAIR, result.getFloat(OFFSET_XP + 3));
  1175. skillsXp.put(SkillType.WOODCUTTING, result.getFloat(OFFSET_XP + 4));
  1176. skillsXp.put(SkillType.UNARMED, result.getFloat(OFFSET_XP + 5));
  1177. skillsXp.put(SkillType.HERBALISM, result.getFloat(OFFSET_XP + 6));
  1178. skillsXp.put(SkillType.EXCAVATION, result.getFloat(OFFSET_XP + 7));
  1179. skillsXp.put(SkillType.ARCHERY, result.getFloat(OFFSET_XP + 8));
  1180. skillsXp.put(SkillType.SWORDS, result.getFloat(OFFSET_XP + 9));
  1181. skillsXp.put(SkillType.AXES, result.getFloat(OFFSET_XP + 10));
  1182. skillsXp.put(SkillType.ACROBATICS, result.getFloat(OFFSET_XP + 11));
  1183. skillsXp.put(SkillType.FISHING, result.getFloat(OFFSET_XP + 12));
  1184. skillsXp.put(SkillType.ALCHEMY, result.getFloat(OFFSET_XP + 13));
  1185. // Taming - Unused - result.getInt(OFFSET_DATS + 1)
  1186. skillsDATS.put(AbilityType.SUPER_BREAKER, result.getInt(OFFSET_DATS + 2));
  1187. // Repair - Unused - result.getInt(OFFSET_DATS + 3)
  1188. skillsDATS.put(AbilityType.TREE_FELLER, result.getInt(OFFSET_DATS + 4));
  1189. skillsDATS.put(AbilityType.BERSERK, result.getInt(OFFSET_DATS + 5));
  1190. skillsDATS.put(AbilityType.GREEN_TERRA, result.getInt(OFFSET_DATS + 6));
  1191. skillsDATS.put(AbilityType.GIGA_DRILL_BREAKER, result.getInt(OFFSET_DATS + 7));
  1192. // Archery - Unused - result.getInt(OFFSET_DATS + 8)
  1193. skillsDATS.put(AbilityType.SERRATED_STRIKES, result.getInt(OFFSET_DATS + 9));
  1194. skillsDATS.put(AbilityType.SKULL_SPLITTER, result.getInt(OFFSET_DATS + 10));
  1195. // Acrobatics - Unused - result.getInt(OFFSET_DATS + 11)
  1196. skillsDATS.put(AbilityType.BLAST_MINING, result.getInt(OFFSET_DATS + 12));
  1197. try {
  1198. mobHealthbarType = MobHealthbarType.valueOf(result.getString(OFFSET_OTHER + 1));
  1199. }
  1200. catch (Exception e) {
  1201. mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
  1202. }
  1203. try {
  1204. scoreboardTipsShown = result.getInt(OFFSET_OTHER + 2);
  1205. }
  1206. catch (Exception e) {
  1207. scoreboardTipsShown = 0;
  1208. }
  1209. try {
  1210. uuid = UUID.fromString(result.getString(OFFSET_OTHER + 3));
  1211. }
  1212. catch (Exception e) {
  1213. uuid = null;
  1214. }
  1215. return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown);
  1216. }
  1217. private void printErrors(SQLException ex) {
  1218. StackTraceElement element = ex.getStackTrace()[0];
  1219. mcMMO.p.getLogger().severe("Location: " + element.getClassName() + " " + element.getMethodName() + " " + element.getLineNumber());
  1220. mcMMO.p.getLogger().severe("SQLException: " + ex.getMessage());
  1221. mcMMO.p.getLogger().severe("SQLState: " + ex.getSQLState());
  1222. mcMMO.p.getLogger().severe("VendorError: " + ex.getErrorCode());
  1223. }
  1224. public DatabaseType getDatabaseType() {
  1225. return DatabaseType.SQL;
  1226. }
  1227. private void checkNameUniqueness(final Statement statement) throws SQLException {
  1228. ResultSet resultSet = null;
  1229. try {
  1230. resultSet = statement.executeQuery("SHOW INDEXES "
  1231. + "FROM `" + tablePrefix + "users` "
  1232. + "WHERE Column_name='user' "
  1233. + " AND NOT Non_unique");
  1234. if (!resultSet.next()) {
  1235. return;
  1236. }
  1237. resultSet.close();
  1238. mcMMO.p.getLogger().info("Updating mcMMO MySQL tables to drop name uniqueness...");
  1239. statement.execute("ALTER TABLE `" + tablePrefix + "users` "
  1240. + "DROP INDEX `user`,"
  1241. + "ADD INDEX `user` (`user`(20) ASC)");
  1242. } catch (SQLException ex) {
  1243. } finally {
  1244. if (resultSet != null) {
  1245. try {
  1246. resultSet.close();
  1247. }
  1248. catch (SQLException e) {
  1249. // Ignore
  1250. }
  1251. }
  1252. }
  1253. }
  1254. private void checkUpgradeAddAlchemy(final Statement statement) throws SQLException {
  1255. try {
  1256. statement.executeQuery("SELECT `alchemy` FROM `" + tablePrefix + "skills` LIMIT 1");
  1257. }
  1258. catch (SQLException ex) {
  1259. mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Alchemy...");
  1260. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `alchemy` int(10) NOT NULL DEFAULT '0'");
  1261. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `alchemy` int(10) NOT NULL DEFAULT '0'");
  1262. }
  1263. }
  1264. private void checkUpgradeAddBlastMiningCooldown(final Statement statement) throws SQLException {
  1265. try {
  1266. statement.executeQuery("SELECT `blast_mining` FROM `" + tablePrefix + "cooldowns` LIMIT 1");
  1267. }
  1268. catch (SQLException ex) {
  1269. mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Blast Mining...");
  1270. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0'");
  1271. }
  1272. }
  1273. private void checkUpgradeAddFishing(final Statement statement) throws SQLException {
  1274. try {
  1275. statement.executeQuery("SELECT `fishing` FROM `" + tablePrefix + "skills` LIMIT 1");
  1276. }
  1277. catch (SQLException ex) {
  1278. mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for Fishing...");
  1279. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD `fishing` int(10) NOT NULL DEFAULT '0'");
  1280. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "experience` ADD `fishing` int(10) NOT NULL DEFAULT '0'");
  1281. }
  1282. }
  1283. private void checkUpgradeAddMobHealthbars(final Statement statement) throws SQLException {
  1284. try {
  1285. statement.executeQuery("SELECT `mobhealthbar` FROM `" + tablePrefix + "huds` LIMIT 1");
  1286. }
  1287. catch (SQLException ex) {
  1288. mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
  1289. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "'");
  1290. }
  1291. }
  1292. private void checkUpgradeAddScoreboardTips(final Statement statement) throws SQLException {
  1293. try {
  1294. statement.executeQuery("SELECT `scoreboardtips` FROM `" + tablePrefix + "huds` LIMIT 1");
  1295. }
  1296. catch (SQLException ex) {
  1297. mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for scoreboard tips...");
  1298. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `scoreboardtips` int(10) NOT NULL DEFAULT '0' ;");
  1299. }
  1300. }
  1301. private void checkUpgradeAddSQLIndexes(final Statement statement) throws SQLException {
  1302. ResultSet resultSet = null;
  1303. try {
  1304. resultSet = statement.executeQuery("SHOW INDEX FROM `" + tablePrefix + "skills` WHERE `Key_name` LIKE 'idx\\_%'");
  1305. resultSet.last();
  1306. if (resultSet.getRow() != SkillType.NON_CHILD_SKILLS.size()) {
  1307. mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
  1308. for (SkillType skill : SkillType.NON_CHILD_SKILLS) {
  1309. String skill_name = skill.name().toLowerCase();
  1310. try {
  1311. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_" + skill_name + "` (`" + skill_name + "`) USING BTREE");
  1312. }
  1313. catch (SQLException ex) {
  1314. // Ignore
  1315. }
  1316. }
  1317. }
  1318. }
  1319. catch (SQLException ex) {
  1320. printErrors(ex);
  1321. }
  1322. finally {
  1323. if (resultSet != null) {
  1324. try {
  1325. resultSet.close();
  1326. }
  1327. catch (SQLException e) {
  1328. // Ignore
  1329. }
  1330. }
  1331. }
  1332. }
  1333. private void checkUpgradeAddUUIDs(final Statement statement) {
  1334. ResultSet resultSet = null;
  1335. try {
  1336. resultSet = statement.executeQuery("SELECT * FROM `" + tablePrefix + "users` LIMIT 1");
  1337. ResultSetMetaData rsmeta = resultSet.getMetaData();
  1338. boolean column_exists = false;
  1339. for (int i = 1; i <= rsmeta.getColumnCount(); i++) {
  1340. if (rsmeta.getColumnName(i).equalsIgnoreCase("uuid")) {
  1341. column_exists = true;
  1342. break;
  1343. }
  1344. }
  1345. if (!column_exists) {
  1346. mcMMO.p.getLogger().info("Adding UUIDs to mcMMO MySQL user table...");
  1347. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD `uuid` varchar(36) NULL DEFAULT NULL");
  1348. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` ADD UNIQUE INDEX `uuid` (`uuid`) USING BTREE");
  1349. }
  1350. }
  1351. catch (SQLException ex) {
  1352. printErrors(ex);
  1353. }
  1354. finally {
  1355. if (resultSet != null) {
  1356. try {
  1357. resultSet.close();
  1358. }
  1359. catch (SQLException e) {
  1360. // Ignore
  1361. }
  1362. }
  1363. }
  1364. new GetUUIDUpdatesRequired().runTaskLaterAsynchronously(mcMMO.p, 100); // wait until after first purge
  1365. }
  1366. private class GetUUIDUpdatesRequired extends BukkitRunnable {
  1367. public void run() {
  1368. massUpdateLock.lock();
  1369. List<String> names = new ArrayList<String>();
  1370. Connection connection = null;
  1371. Statement statement = null;
  1372. ResultSet resultSet = null;
  1373. try {
  1374. try {
  1375. connection = miscPool.getConnection();
  1376. statement = connection.createStatement();
  1377. resultSet = statement.executeQuery("SELECT `user` FROM `" + tablePrefix + "users` WHERE `uuid` IS NULL");
  1378. while (resultSet.next()) {
  1379. names.add(resultSet.getString("user"));
  1380. }
  1381. } catch (SQLException ex) {
  1382. printErrors(ex);
  1383. } finally {
  1384. if (resultSet != null) {
  1385. try {
  1386. resultSet.close();
  1387. } catch (SQLException e) {
  1388. // Ignore
  1389. }
  1390. }
  1391. if (statement != null) {
  1392. try {
  1393. statement.close();
  1394. } catch (SQLException e) {
  1395. // Ignore
  1396. }
  1397. }
  1398. if (connection != null) {
  1399. try {
  1400. connection.close();
  1401. } catch (SQLException e) {
  1402. // Ignore
  1403. }
  1404. }
  1405. }
  1406. if (!names.isEmpty()) {
  1407. new UUIDUpdateAsyncTask(mcMMO.p, names).run();;
  1408. }
  1409. } finally {
  1410. massUpdateLock.unlock();
  1411. }
  1412. }
  1413. }
  1414. private void checkUpgradeDropPartyNames(final Statement statement) {
  1415. ResultSet resultSet = null;
  1416. try {
  1417. resultSet = statement.executeQuery("SELECT * FROM `" + tablePrefix + "users` LIMIT 1");
  1418. ResultSetMetaData rsmeta = resultSet.getMetaData();
  1419. boolean column_exists = false;
  1420. for (int i = 1; i <= rsmeta.getColumnCount(); i++) {
  1421. if (rsmeta.getColumnName(i).equalsIgnoreCase("party")) {
  1422. column_exists = true;
  1423. break;
  1424. }
  1425. }
  1426. if (column_exists) {
  1427. mcMMO.p.getLogger().info("Removing party name from users table...");
  1428. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "users` DROP COLUMN `party`");
  1429. }
  1430. }
  1431. catch (SQLException ex) {
  1432. printErrors(ex);
  1433. }
  1434. finally {
  1435. if (resultSet != null) {
  1436. try {
  1437. resultSet.close();
  1438. }
  1439. catch (SQLException e) {
  1440. // Ignore
  1441. }
  1442. }
  1443. }
  1444. }
  1445. private void checkUpgradeDropSpout(final Statement statement) {
  1446. ResultSet resultSet = null;
  1447. try {
  1448. resultSet = statement.executeQuery("SELECT * FROM `" + tablePrefix + "huds` LIMIT 1");
  1449. ResultSetMetaData rsmeta = resultSet.getMetaData();
  1450. boolean column_exists = false;
  1451. for (int i = 1; i <= rsmeta.getColumnCount(); i++) {
  1452. if (rsmeta.getColumnName(i).equalsIgnoreCase("hudtype")) {
  1453. column_exists = true;
  1454. break;
  1455. }
  1456. }
  1457. if (column_exists) {
  1458. mcMMO.p.getLogger().info("Removing Spout HUD type from huds table...");
  1459. statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` DROP COLUMN `hudtype`");
  1460. }
  1461. }
  1462. catch (SQLException ex) {
  1463. printErrors(ex);
  1464. }
  1465. finally {
  1466. if (resultSet != null) {
  1467. try {
  1468. resultSet.close();
  1469. }
  1470. catch (SQLException e) {
  1471. // Ignore
  1472. }
  1473. }
  1474. }
  1475. }
  1476. private int getUserID(final Connection connection, final String playerName, final UUID uuid) {
  1477. if (cachedUserIDs.containsKey(uuid)) {
  1478. return cachedUserIDs.get(uuid);
  1479. }
  1480. ResultSet resultSet = null;
  1481. PreparedStatement statement = null;
  1482. try {
  1483. statement = connection.prepareStatement("SELECT id, user FROM " + tablePrefix + "users WHERE uuid = ? OR (uuid IS NULL AND user = ?)");
  1484. statement.setString(1, uuid == null ? null : uuid.toString());
  1485. statement.setString(2, playerName);
  1486. resultSet = statement.executeQuery();
  1487. if (resultSet.next()) {
  1488. int id = resultSet.getInt("id");
  1489. cachedUserIDs.put(uuid, id);
  1490. return id;
  1491. }
  1492. }
  1493. catch (SQLException ex) {
  1494. printErrors(ex);
  1495. }
  1496. finally {
  1497. if (resultSet != null) {
  1498. try {
  1499. resultSet.close();
  1500. }
  1501. catch (SQLException e) {
  1502. // Ignore
  1503. }
  1504. }
  1505. if (statement != null) {
  1506. try {
  1507. statement.close();
  1508. }
  1509. catch (SQLException e) {
  1510. // Ignore
  1511. }
  1512. }
  1513. }
  1514. return -1;
  1515. }
  1516. @Override
  1517. public void onDisable() {
  1518. mcMMO.p.debug("Releasing connection pool resource...");
  1519. miscPool.close();
  1520. loadPool.close();
  1521. savePool.close();
  1522. }
  1523. public enum PoolIdentifier {
  1524. MISC,
  1525. LOAD,
  1526. SAVE;
  1527. }
  1528. }