2013-04-18 23:37:36 +02:00
package com.gmail.nossr50.database ;
2019-01-18 22:10:45 +01:00
import com.gmail.nossr50.config.AdvancedConfig ;
2013-04-18 23:37:36 +02:00
import com.gmail.nossr50.config.Config ;
2013-06-04 18:14:43 +02:00
import com.gmail.nossr50.datatypes.MobHealthbarType ;
2013-08-22 15:11:33 +02:00
import com.gmail.nossr50.datatypes.database.DatabaseType ;
2013-06-04 18:14:43 +02:00
import com.gmail.nossr50.datatypes.database.PlayerStat ;
2014-07-23 02:01:26 +02:00
import com.gmail.nossr50.datatypes.database.UpgradeType ;
2013-06-04 18:14:43 +02:00
import com.gmail.nossr50.datatypes.player.PlayerProfile ;
2019-01-11 08:52:11 +01:00
import com.gmail.nossr50.datatypes.player.UniqueDataType ;
2019-01-13 08:54:53 +01:00
import com.gmail.nossr50.datatypes.skills.PrimarySkillType ;
2019-01-13 04:56:54 +01:00
import com.gmail.nossr50.datatypes.skills.SuperAbilityType ;
2018-07-24 04:13:57 +02:00
import com.gmail.nossr50.mcMMO ;
2014-08-01 20:17:15 +02:00
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask ;
2013-04-18 23:37:36 +02:00
import com.gmail.nossr50.util.Misc ;
2014-02-09 18:12:00 +01:00
import org.apache.tomcat.jdbc.pool.DataSource ;
import org.apache.tomcat.jdbc.pool.PoolProperties ;
2018-07-24 04:13:57 +02:00
import org.bukkit.scheduler.BukkitRunnable ;
import java.sql.* ;
import java.util.* ;
import java.util.concurrent.locks.ReentrantLock ;
2014-02-09 18:12:00 +01:00
2013-06-04 18:14:43 +02:00
public final class SQLDatabaseManager implements DatabaseManager {
2018-11-15 02:31:57 +01:00
private static final String ALL_QUERY_VERSION = " total " ;
2013-06-04 18:14:43 +02:00
private String tablePrefix = Config . getInstance ( ) . getMySQLTablePrefix ( ) ;
2013-04-18 23:37:36 +02:00
2014-08-01 19:35:36 +02:00
private final Map < UUID , Integer > cachedUserIDs = new HashMap < UUID , Integer > ( ) ;
2013-04-18 23:37:36 +02:00
2014-10-15 05:59:41 +02:00
private DataSource miscPool ;
private DataSource loadPool ;
private DataSource savePool ;
2013-04-18 23:37:36 +02:00
2014-08-04 17:42:02 +02:00
private ReentrantLock massUpdateLock = new ReentrantLock ( ) ;
2014-08-01 19:35:36 +02:00
protected SQLDatabaseManager ( ) {
2019-01-11 10:47:36 +01:00
String connectionString = " jdbc:mysql:// " + Config . getInstance ( ) . getMySQLServerName ( )
+ " : " + Config . getInstance ( ) . getMySQLServerPort ( ) + " / " + Config . getInstance ( ) . getMySQLDatabaseName ( ) ;
2013-04-18 23:37:36 +02:00
2019-01-13 02:26:17 +01:00
if ( Config . getInstance ( ) . getMySQLSSL ( ) )
2019-01-13 04:08:54 +01:00
connectionString + =
2019-01-13 02:26:17 +01:00
" ?verifyServerCertificate=false " +
" &useSSL=true " +
" &requireSSL=true " ;
2019-01-15 05:37:30 +01:00
else
connectionString + =
" ?useSSL=false " ;
2019-01-13 02:26:17 +01:00
2014-08-01 19:35:36 +02:00
try {
// Force driver to load if not yet loaded
Class . forName ( " com.mysql.jdbc.Driver " ) ;
}
catch ( ClassNotFoundException e ) {
e . printStackTrace ( ) ;
return ;
//throw e; // aborts onEnable() Riking if you want to do this, fully implement it.
}
2013-04-18 23:37:36 +02:00
2014-10-15 05:59:41 +02:00
PoolProperties poolProperties = new PoolProperties ( ) ;
poolProperties . setDriverClassName ( " com.mysql.jdbc.Driver " ) ;
poolProperties . setUrl ( connectionString ) ;
poolProperties . setUsername ( Config . getInstance ( ) . getMySQLUserName ( ) ) ;
poolProperties . setPassword ( Config . getInstance ( ) . getMySQLUserPassword ( ) ) ;
poolProperties . setMaxIdle ( Config . getInstance ( ) . getMySQLMaxPoolSize ( PoolIdentifier . MISC ) ) ;
poolProperties . setMaxActive ( Config . getInstance ( ) . getMySQLMaxConnections ( PoolIdentifier . MISC ) ) ;
poolProperties . setInitialSize ( 0 ) ;
poolProperties . setMaxWait ( - 1 ) ;
poolProperties . setRemoveAbandoned ( true ) ;
poolProperties . setRemoveAbandonedTimeout ( 60 ) ;
poolProperties . setTestOnBorrow ( true ) ;
poolProperties . setValidationQuery ( " SELECT 1 " ) ;
poolProperties . setValidationInterval ( 30000 ) ;
miscPool = new DataSource ( poolProperties ) ;
poolProperties = new PoolProperties ( ) ;
poolProperties . setDriverClassName ( " com.mysql.jdbc.Driver " ) ;
poolProperties . setUrl ( connectionString ) ;
poolProperties . setUsername ( Config . getInstance ( ) . getMySQLUserName ( ) ) ;
poolProperties . setPassword ( Config . getInstance ( ) . getMySQLUserPassword ( ) ) ;
poolProperties . setInitialSize ( 0 ) ;
poolProperties . setMaxIdle ( Config . getInstance ( ) . getMySQLMaxPoolSize ( PoolIdentifier . SAVE ) ) ;
poolProperties . setMaxActive ( Config . getInstance ( ) . getMySQLMaxConnections ( PoolIdentifier . SAVE ) ) ;
poolProperties . setMaxWait ( - 1 ) ;
poolProperties . setRemoveAbandoned ( true ) ;
poolProperties . setRemoveAbandonedTimeout ( 60 ) ;
poolProperties . setTestOnBorrow ( true ) ;
poolProperties . setValidationQuery ( " SELECT 1 " ) ;
poolProperties . setValidationInterval ( 30000 ) ;
savePool = new DataSource ( poolProperties ) ;
poolProperties = new PoolProperties ( ) ;
poolProperties . setDriverClassName ( " com.mysql.jdbc.Driver " ) ;
poolProperties . setUrl ( connectionString ) ;
poolProperties . setUsername ( Config . getInstance ( ) . getMySQLUserName ( ) ) ;
poolProperties . setPassword ( Config . getInstance ( ) . getMySQLUserPassword ( ) ) ;
poolProperties . setInitialSize ( 0 ) ;
poolProperties . setMaxIdle ( Config . getInstance ( ) . getMySQLMaxPoolSize ( PoolIdentifier . LOAD ) ) ;
poolProperties . setMaxActive ( Config . getInstance ( ) . getMySQLMaxConnections ( PoolIdentifier . LOAD ) ) ;
poolProperties . setMaxWait ( - 1 ) ;
poolProperties . setRemoveAbandoned ( true ) ;
poolProperties . setRemoveAbandonedTimeout ( 60 ) ;
poolProperties . setTestOnBorrow ( true ) ;
poolProperties . setValidationQuery ( " SELECT 1 " ) ;
poolProperties . setValidationInterval ( 30000 ) ;
loadPool = new DataSource ( poolProperties ) ;
2013-10-05 23:55:34 +02:00
2014-10-15 05:59:41 +02:00
checkStructure ( ) ;
2013-06-04 18:14:43 +02:00
}
2013-04-18 23:37:36 +02:00
2013-06-04 18:14:43 +02:00
public void purgePowerlessUsers ( ) {
2014-08-04 17:42:02 +02:00
massUpdateLock . lock ( ) ;
2013-06-04 18:14:43 +02:00
mcMMO . p . getLogger ( ) . info ( " Purging powerless users... " ) ;
2013-04-18 23:37:36 +02:00
2014-08-01 19:35:36 +02:00
Connection connection = null ;
Statement statement = null ;
2014-08-04 03:14:24 +02:00
int purged = 0 ;
2014-08-01 19:35:36 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
statement = connection . createStatement ( ) ;
2014-08-18 03:23:27 +02:00
purged = statement . executeUpdate ( " DELETE FROM " + tablePrefix + " skills WHERE "
+ " taming = 0 AND mining = 0 AND woodcutting = 0 AND repair = 0 "
+ " AND unarmed = 0 AND herbalism = 0 AND excavation = 0 AND "
+ " archery = 0 AND swords = 0 AND axes = 0 AND acrobatics = 0 "
+ " AND fishing = 0 AND alchemy = 0; " ) ;
statement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " experience` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " skills` `s` WHERE ` " + tablePrefix + " experience`.`user_id` = `s`.`user_id`) " ) ;
statement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " huds` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " skills` `s` WHERE ` " + tablePrefix + " huds`.`user_id` = `s`.`user_id`) " ) ;
statement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " cooldowns` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " skills` `s` WHERE ` " + tablePrefix + " cooldowns`.`user_id` = `s`.`user_id`) " ) ;
statement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " users` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " skills` `s` WHERE ` " + tablePrefix + " users`.`id` = `s`.`user_id`) " ) ;
2014-08-01 19:35:36 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-04 17:42:02 +02:00
massUpdateLock . unlock ( ) ;
2014-08-01 19:35:36 +02:00
}
2013-04-18 23:37:36 +02:00
2014-08-04 03:14:24 +02:00
mcMMO . p . getLogger ( ) . info ( " Purged " + purged + " users from the database. " ) ;
2013-06-04 18:14:43 +02:00
}
2013-04-18 23:37:36 +02:00
2013-06-04 18:14:43 +02:00
public void purgeOldUsers ( ) {
2014-08-04 17:42:02 +02:00
massUpdateLock . lock ( ) ;
2015-06-12 00:10:53 +02:00
mcMMO . p . getLogger ( ) . info ( " Purging inactive users older than " + ( PURGE_TIME / 2630000000L ) + " months... " ) ;
2014-08-01 19:35:36 +02:00
Connection connection = null ;
Statement statement = null ;
2014-08-04 03:14:24 +02:00
int purged = 0 ;
2014-08-01 19:35:36 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
statement = connection . createStatement ( ) ;
2013-04-18 23:37:36 +02:00
2014-08-04 03:14:24 +02:00
purged = statement . executeUpdate ( " DELETE FROM u, e, h, s, c USING " + tablePrefix + " users u " +
2014-08-01 19:35:36 +02:00
" JOIN " + tablePrefix + " experience e ON (u.id = e.user_id) " +
" JOIN " + tablePrefix + " huds h ON (u.id = h.user_id) " +
" JOIN " + tablePrefix + " skills s ON (u.id = s.user_id) " +
" JOIN " + tablePrefix + " cooldowns c ON (u.id = c.user_id) " +
2014-08-07 19:54:28 +02:00
" WHERE ((UNIX_TIMESTAMP() - lastlogin) > " + PURGE_TIME + " ) " ) ;
2014-08-01 19:35:36 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-04 17:42:02 +02:00
massUpdateLock . unlock ( ) ;
2014-08-01 19:35:36 +02:00
}
2013-06-04 18:14:43 +02:00
2014-08-04 03:14:24 +02:00
mcMMO . p . getLogger ( ) . info ( " Purged " + purged + " users from the database. " ) ;
2013-04-18 23:37:36 +02:00
}
2013-06-04 18:14:43 +02:00
public boolean removeUser ( String playerName ) {
2014-08-01 19:35:36 +02:00
boolean success = false ;
Connection connection = null ;
PreparedStatement statement = null ;
2013-08-28 17:44:58 +02:00
2014-08-01 19:35:36 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( " DELETE FROM u, e, h, s, c " +
" USING " + tablePrefix + " users u " +
" JOIN " + tablePrefix + " experience e ON (u.id = e.user_id) " +
" JOIN " + tablePrefix + " huds h ON (u.id = h.user_id) " +
" JOIN " + tablePrefix + " skills s ON (u.id = s.user_id) " +
" JOIN " + tablePrefix + " cooldowns c ON (u.id = c.user_id) " +
" WHERE u.user = ? " ) ;
statement . setString ( 1 , playerName ) ;
success = statement . executeUpdate ( ) ! = 0 ;
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-01 19:35:36 +02:00
}
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
if ( success ) {
Misc . profileCleanup ( playerName ) ;
}
2013-04-18 23:37:36 +02:00
2013-06-04 18:14:43 +02:00
return success ;
2013-04-18 23:37:36 +02:00
}
2013-10-06 00:18:10 +02:00
public boolean saveUser ( PlayerProfile profile ) {
2014-08-01 19:35:36 +02:00
boolean success = true ;
PreparedStatement statement = null ;
Connection connection = null ;
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . SAVE ) ;
2014-08-01 19:35:36 +02:00
2014-08-07 20:16:28 +02:00
int id = getUserID ( connection , profile . getPlayerName ( ) , profile . getUniqueId ( ) ) ;
2013-08-28 17:44:58 +02:00
2014-08-01 19:35:36 +02:00
if ( id = = - 1 ) {
2014-08-08 05:45:40 +02:00
id = newUser ( connection , profile . getPlayerName ( ) , profile . getUniqueId ( ) ) ;
2014-08-01 19:35:36 +02:00
if ( id = = - 1 ) {
2015-02-24 02:36:30 +01:00
mcMMO . p . getLogger ( ) . severe ( " Failed to create new account for " + profile . getPlayerName ( ) ) ;
2014-08-01 19:35:36 +02:00
return false ;
}
2013-06-29 00:02:58 +02:00
}
2014-08-01 19:35:36 +02:00
2014-08-07 20:16:28 +02:00
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " users SET lastlogin = UNIX_TIMESTAMP() WHERE id = ? " ) ;
statement . setInt ( 1 , id ) ;
2014-08-01 19:35:36 +02:00
success & = ( statement . executeUpdate ( ) ! = 0 ) ;
statement . close ( ) ;
2015-02-24 02:36:30 +01:00
if ( ! success ) {
mcMMO . p . getLogger ( ) . severe ( " Failed to update last login for " + profile . getPlayerName ( ) ) ;
return false ;
}
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " skills SET "
+ " taming = ?, mining = ?, repair = ?, woodcutting = ? "
+ " , unarmed = ?, herbalism = ?, excavation = ? "
+ " , archery = ?, swords = ?, axes = ?, acrobatics = ? "
2018-11-15 02:31:57 +01:00
+ " , fishing = ?, alchemy = ?, total = ? WHERE user_id = ? " ) ;
2019-01-13 08:54:53 +01:00
statement . setInt ( 1 , profile . getSkillLevel ( PrimarySkillType . TAMING ) ) ;
statement . setInt ( 2 , profile . getSkillLevel ( PrimarySkillType . MINING ) ) ;
statement . setInt ( 3 , profile . getSkillLevel ( PrimarySkillType . REPAIR ) ) ;
statement . setInt ( 4 , profile . getSkillLevel ( PrimarySkillType . WOODCUTTING ) ) ;
statement . setInt ( 5 , profile . getSkillLevel ( PrimarySkillType . UNARMED ) ) ;
statement . setInt ( 6 , profile . getSkillLevel ( PrimarySkillType . HERBALISM ) ) ;
statement . setInt ( 7 , profile . getSkillLevel ( PrimarySkillType . EXCAVATION ) ) ;
statement . setInt ( 8 , profile . getSkillLevel ( PrimarySkillType . ARCHERY ) ) ;
statement . setInt ( 9 , profile . getSkillLevel ( PrimarySkillType . SWORDS ) ) ;
statement . setInt ( 10 , profile . getSkillLevel ( PrimarySkillType . AXES ) ) ;
statement . setInt ( 11 , profile . getSkillLevel ( PrimarySkillType . ACROBATICS ) ) ;
statement . setInt ( 12 , profile . getSkillLevel ( PrimarySkillType . FISHING ) ) ;
statement . setInt ( 13 , profile . getSkillLevel ( PrimarySkillType . ALCHEMY ) ) ;
2018-11-15 02:31:57 +01:00
int total = 0 ;
2019-01-13 08:54:53 +01:00
for ( PrimarySkillType primarySkillType : PrimarySkillType . NON_CHILD_SKILLS )
total + = profile . getSkillLevel ( primarySkillType ) ;
2018-11-15 02:31:57 +01:00
statement . setInt ( 14 , total ) ;
statement . setInt ( 15 , id ) ;
2014-08-01 19:35:36 +02:00
success & = ( statement . executeUpdate ( ) ! = 0 ) ;
statement . close ( ) ;
2015-02-24 02:36:30 +01:00
if ( ! success ) {
mcMMO . p . getLogger ( ) . severe ( " Failed to update skills for " + profile . getPlayerName ( ) ) ;
return false ;
}
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " experience SET "
+ " taming = ?, mining = ?, repair = ?, woodcutting = ? "
+ " , unarmed = ?, herbalism = ?, excavation = ? "
+ " , archery = ?, swords = ?, axes = ?, acrobatics = ? "
+ " , fishing = ?, alchemy = ? WHERE user_id = ? " ) ;
2019-01-13 08:54:53 +01:00
statement . setInt ( 1 , profile . getSkillXpLevel ( PrimarySkillType . TAMING ) ) ;
statement . setInt ( 2 , profile . getSkillXpLevel ( PrimarySkillType . MINING ) ) ;
statement . setInt ( 3 , profile . getSkillXpLevel ( PrimarySkillType . REPAIR ) ) ;
statement . setInt ( 4 , profile . getSkillXpLevel ( PrimarySkillType . WOODCUTTING ) ) ;
statement . setInt ( 5 , profile . getSkillXpLevel ( PrimarySkillType . UNARMED ) ) ;
statement . setInt ( 6 , profile . getSkillXpLevel ( PrimarySkillType . HERBALISM ) ) ;
statement . setInt ( 7 , profile . getSkillXpLevel ( PrimarySkillType . EXCAVATION ) ) ;
statement . setInt ( 8 , profile . getSkillXpLevel ( PrimarySkillType . ARCHERY ) ) ;
statement . setInt ( 9 , profile . getSkillXpLevel ( PrimarySkillType . SWORDS ) ) ;
statement . setInt ( 10 , profile . getSkillXpLevel ( PrimarySkillType . AXES ) ) ;
statement . setInt ( 11 , profile . getSkillXpLevel ( PrimarySkillType . ACROBATICS ) ) ;
statement . setInt ( 12 , profile . getSkillXpLevel ( PrimarySkillType . FISHING ) ) ;
statement . setInt ( 13 , profile . getSkillXpLevel ( PrimarySkillType . ALCHEMY ) ) ;
2014-08-01 19:35:36 +02:00
statement . setInt ( 14 , id ) ;
success & = ( statement . executeUpdate ( ) ! = 0 ) ;
statement . close ( ) ;
2015-02-24 02:36:30 +01:00
if ( ! success ) {
mcMMO . p . getLogger ( ) . severe ( " Failed to update experience for " + profile . getPlayerName ( ) ) ;
return false ;
}
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " cooldowns SET "
+ " mining = ?, woodcutting = ?, unarmed = ? "
+ " , herbalism = ?, excavation = ?, swords = ? "
2019-01-11 08:52:11 +01:00
+ " , axes = ?, blast_mining = ?, chimaera_wing = ? WHERE user_id = ? " ) ;
2019-01-13 04:56:54 +01:00
statement . setLong ( 1 , profile . getAbilityDATS ( SuperAbilityType . SUPER_BREAKER ) ) ;
statement . setLong ( 2 , profile . getAbilityDATS ( SuperAbilityType . TREE_FELLER ) ) ;
statement . setLong ( 3 , profile . getAbilityDATS ( SuperAbilityType . BERSERK ) ) ;
statement . setLong ( 4 , profile . getAbilityDATS ( SuperAbilityType . GREEN_TERRA ) ) ;
statement . setLong ( 5 , profile . getAbilityDATS ( SuperAbilityType . GIGA_DRILL_BREAKER ) ) ;
statement . setLong ( 6 , profile . getAbilityDATS ( SuperAbilityType . SERRATED_STRIKES ) ) ;
statement . setLong ( 7 , profile . getAbilityDATS ( SuperAbilityType . SKULL_SPLITTER ) ) ;
statement . setLong ( 8 , profile . getAbilityDATS ( SuperAbilityType . BLAST_MINING ) ) ;
2019-01-11 08:52:11 +01:00
statement . setLong ( 9 , profile . getUniqueData ( UniqueDataType . CHIMAERA_WING_DATS ) ) ;
statement . setInt ( 10 , id ) ;
2014-08-01 19:35:36 +02:00
success = ( statement . executeUpdate ( ) ! = 0 ) ;
statement . close ( ) ;
2015-02-24 02:36:30 +01:00
if ( ! success ) {
mcMMO . p . getLogger ( ) . severe ( " Failed to update cooldowns for " + profile . getPlayerName ( ) ) ;
return false ;
}
2014-08-01 19:35:36 +02:00
2014-02-09 18:12:00 +01:00
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " huds SET mobhealthbar = ?, scoreboardtips = ? WHERE user_id = ? " ) ;
2014-08-01 19:35:36 +02:00
statement . setString ( 1 , profile . getMobHealthbarType ( ) = = null ? Config . getInstance ( ) . getMobHealthbarDefault ( ) . name ( ) : profile . getMobHealthbarType ( ) . name ( ) ) ;
2014-02-09 18:12:00 +01:00
statement . setInt ( 2 , profile . getScoreboardTipsShown ( ) ) ;
statement . setInt ( 3 , id ) ;
2014-08-01 19:35:36 +02:00
success = ( statement . executeUpdate ( ) ! = 0 ) ;
2014-08-21 22:33:50 +02:00
statement . close ( ) ;
2015-02-24 02:36:30 +01:00
if ( ! success ) {
mcMMO . p . getLogger ( ) . severe ( " Failed to update hud settings for " + profile . getPlayerName ( ) ) ;
return false ;
}
2013-06-29 00:02:58 +02:00
}
2014-08-01 19:35:36 +02:00
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-01 19:35:36 +02:00
}
2013-10-06 00:18:10 +02:00
return success ;
2013-06-04 18:14:43 +02:00
}
2013-04-18 23:37:36 +02:00
2019-01-13 08:54:53 +01:00
public List < PlayerStat > readLeaderboard ( PrimarySkillType skill , int pageNumber , int statsPerPage ) {
2013-06-04 18:14:43 +02:00
List < PlayerStat > stats = new ArrayList < PlayerStat > ( ) ;
2014-08-01 19:35:36 +02:00
String query = skill = = null ? ALL_QUERY_VERSION : skill . name ( ) . toLowerCase ( ) ;
ResultSet resultSet = null ;
PreparedStatement statement = null ;
Connection connection = null ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2018-07-24 04:13:57 +02:00
statement = connection . prepareStatement ( " SELECT " + query + " , user 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 ?, ? " ) ;
2014-08-01 19:35:36 +02:00
statement . setInt ( 1 , ( pageNumber * statsPerPage ) - statsPerPage ) ;
statement . setInt ( 2 , statsPerPage ) ;
resultSet = statement . executeQuery ( ) ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
while ( resultSet . next ( ) ) {
ArrayList < String > column = new ArrayList < String > ( ) ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
for ( int i = 1 ; i < = resultSet . getMetaData ( ) . getColumnCount ( ) ; i + + ) {
column . add ( resultSet . getString ( i ) ) ;
}
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
stats . add ( new PlayerStat ( column . get ( 1 ) , Integer . valueOf ( column . get ( 0 ) ) ) ) ;
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( connection ) ;
2013-04-18 23:37:36 +02:00
}
2013-06-04 18:14:43 +02:00
return stats ;
2013-04-18 23:37:36 +02:00
}
2019-01-13 08:54:53 +01:00
public Map < PrimarySkillType , Integer > readRank ( String playerName ) {
Map < PrimarySkillType , Integer > skills = new HashMap < PrimarySkillType , Integer > ( ) ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
ResultSet resultSet = null ;
PreparedStatement statement = null ;
Connection connection = null ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2019-01-13 08:54:53 +01:00
for ( PrimarySkillType primarySkillType : PrimarySkillType . NON_CHILD_SKILLS ) {
String skillName = primarySkillType . name ( ) . toLowerCase ( ) ;
2015-11-04 19:48:29 +01:00
// Get count of all users with higher skill level than player
2014-08-01 19:35:36 +02:00
String sql = " SELECT COUNT(*) AS rank FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id WHERE " + skillName + " > 0 " +
" AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id " +
" WHERE user = ?) " ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( sql ) ;
2013-06-04 18:14:43 +02:00
statement . setString ( 1 , playerName ) ;
resultSet = statement . executeQuery ( ) ;
resultSet . next ( ) ;
int rank = resultSet . getInt ( " rank " ) ;
2015-11-04 19:48:29 +01:00
// Ties are settled by alphabetical order
2014-08-01 19:35:36 +02:00
sql = " SELECT user, " + skillName + " FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id WHERE " + skillName + " > 0 " +
" AND " + skillName + " = (SELECT " + skillName + " FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id " +
" WHERE user = ' " + playerName + " ') ORDER BY user " ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
resultSet . close ( ) ;
statement . close ( ) ;
2013-06-04 18:14:43 +02:00
statement = connection . prepareStatement ( sql ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) ) {
if ( resultSet . getString ( " user " ) . equalsIgnoreCase ( playerName ) ) {
2019-01-13 08:54:53 +01:00
skills . put ( primarySkillType , rank + resultSet . getRow ( ) ) ;
2013-06-04 18:14:43 +02:00
break ;
}
}
2014-08-01 19:35:36 +02:00
resultSet . close ( ) ;
2013-06-04 18:14:43 +02:00
statement . close ( ) ;
}
2013-04-18 23:37:36 +02:00
2014-08-01 19:35:36 +02:00
String sql = " SELECT COUNT(*) AS rank FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id " +
" WHERE " + ALL_QUERY_VERSION + " > 0 " +
" AND " + ALL_QUERY_VERSION + " > " +
" (SELECT " + ALL_QUERY_VERSION + " " +
" FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id WHERE user = ?) " ;
2013-04-18 23:37:36 +02:00
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( sql ) ;
statement . setString ( 1 , playerName ) ;
resultSet = statement . executeQuery ( ) ;
2013-08-28 17:44:58 +02:00
2014-08-01 19:35:36 +02:00
resultSet . next ( ) ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
int rank = resultSet . getInt ( " rank " ) ;
resultSet . close ( ) ;
statement . close ( ) ;
sql = " SELECT user, " + ALL_QUERY_VERSION + " " +
" FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id " +
" WHERE " + ALL_QUERY_VERSION + " > 0 " +
" AND " + ALL_QUERY_VERSION + " = " +
" (SELECT " + ALL_QUERY_VERSION + " " +
" FROM " + tablePrefix + " users JOIN " + tablePrefix + " skills ON user_id = id WHERE user = ?) ORDER BY user " ;
statement = connection . prepareStatement ( sql ) ;
2013-06-04 18:14:43 +02:00
statement . setString ( 1 , playerName ) ;
2014-08-01 19:35:36 +02:00
resultSet = statement . executeQuery ( ) ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
while ( resultSet . next ( ) ) {
if ( resultSet . getString ( " user " ) . equalsIgnoreCase ( playerName ) ) {
skills . put ( null , rank + resultSet . getRow ( ) ) ;
break ;
}
}
resultSet . close ( ) ;
statement . close ( ) ;
2013-04-18 23:37:36 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-01 19:35:36 +02:00
}
2013-04-18 23:37:36 +02:00
2014-08-01 19:35:36 +02:00
return skills ;
}
2014-08-07 19:54:28 +02:00
public void newUser ( String playerName , UUID uuid ) {
2014-08-01 19:35:36 +02:00
Connection connection = null ;
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
newUser ( connection , playerName , uuid ) ;
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( connection ) ;
2014-08-01 19:35:36 +02:00
}
}
2014-08-08 05:45:40 +02:00
private int newUser ( Connection connection , String playerName , UUID uuid ) {
2014-08-01 19:35:36 +02:00
ResultSet resultSet = null ;
PreparedStatement statement = null ;
try {
2015-06-20 18:57:01 +02:00
statement = connection . prepareStatement (
" UPDATE ` " + tablePrefix + " users` "
+ " SET user = ? "
+ " WHERE user = ? " ) ;
statement . setString ( 1 , " _INVALID_OLD_USERNAME_ " ) ;
statement . setString ( 2 , playerName ) ;
statement . executeUpdate ( ) ;
statement . close ( ) ;
2014-08-08 05:45:40 +02:00
statement = connection . prepareStatement ( " INSERT INTO " + tablePrefix + " users (user, uuid, lastlogin) VALUES (?, ?, UNIX_TIMESTAMP()) " , Statement . RETURN_GENERATED_KEYS ) ;
2014-08-01 19:35:36 +02:00
statement . setString ( 1 , playerName ) ;
2015-02-24 02:36:30 +01:00
statement . setString ( 2 , uuid ! = null ? uuid . toString ( ) : null ) ;
2014-08-01 19:35:36 +02:00
statement . executeUpdate ( ) ;
resultSet = statement . getGeneratedKeys ( ) ;
if ( ! resultSet . next ( ) ) {
2015-02-24 02:36:30 +01:00
mcMMO . p . getLogger ( ) . severe ( " Unable to create new user account in DB " ) ;
2014-08-08 05:45:40 +02:00
return - 1 ;
2014-08-01 20:17:15 +02:00
}
2014-08-01 19:35:36 +02:00
writeMissingRows ( connection , resultSet . getInt ( 1 ) ) ;
2014-08-08 05:45:40 +02:00
return resultSet . getInt ( 1 ) ;
2014-08-01 19:35:36 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
2013-08-28 17:44:58 +02:00
}
2014-08-01 19:35:36 +02:00
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
2014-08-01 19:35:36 +02:00
}
2014-08-08 05:45:40 +02:00
return - 1 ;
2014-08-01 19:35:36 +02:00
}
2013-08-28 17:44:58 +02:00
2014-08-01 20:17:15 +02:00
@Deprecated
public PlayerProfile loadPlayerProfile ( String playerName , boolean create ) {
2014-08-07 19:54:28 +02:00
return loadPlayerProfile ( playerName , null , false , true ) ;
2014-08-01 20:17:15 +02:00
}
2014-08-01 19:35:36 +02:00
public PlayerProfile loadPlayerProfile ( UUID uuid ) {
2014-08-07 19:54:28 +02:00
return loadPlayerProfile ( " " , uuid , false , true ) ;
2014-08-01 20:17:15 +02:00
}
public PlayerProfile loadPlayerProfile ( String playerName , UUID uuid , boolean create ) {
2014-08-07 19:54:28 +02:00
return loadPlayerProfile ( playerName , uuid , create , true ) ;
2014-08-01 20:17:15 +02:00
}
2014-08-07 19:54:28 +02:00
private PlayerProfile loadPlayerProfile ( String playerName , UUID uuid , boolean create , boolean retry ) {
2014-08-01 20:17:15 +02:00
PreparedStatement statement = null ;
2014-08-01 19:35:36 +02:00
Connection connection = null ;
ResultSet resultSet = null ;
2014-08-01 20:17:15 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . LOAD ) ;
2014-08-07 20:16:28 +02:00
int id = getUserID ( connection , playerName , uuid ) ;
2014-08-01 19:35:36 +02:00
if ( id = = - 1 ) {
// There is no such user
if ( create ) {
2014-08-08 05:45:40 +02:00
id = newUser ( connection , playerName , uuid ) ;
create = false ;
if ( id = = - 1 ) {
return new PlayerProfile ( playerName , false ) ;
}
} else {
return new PlayerProfile ( playerName , false ) ;
2014-08-01 19:35:36 +02:00
}
}
// There is such a user
writeMissingRows ( connection , id ) ;
2014-08-01 20:17:15 +02:00
statement = connection . prepareStatement (
" SELECT "
+ " 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, "
+ " 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, "
2019-01-11 08:52:11 +01:00
+ " 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, c.chimaera_wing, "
2015-06-12 00:10:53 +02:00
+ " h.mobhealthbar, h.scoreboardtips, u.uuid, u.user "
2014-08-01 20:17:15 +02:00
+ " FROM " + tablePrefix + " users u "
+ " JOIN " + tablePrefix + " skills s ON (u.id = s.user_id) "
+ " JOIN " + tablePrefix + " experience e ON (u.id = e.user_id) "
+ " JOIN " + tablePrefix + " cooldowns c ON (u.id = c.user_id) "
+ " JOIN " + tablePrefix + " huds h ON (u.id = h.user_id) "
2014-08-07 20:16:28 +02:00
+ " WHERE u.id = ? " ) ;
statement . setInt ( 1 , id ) ;
2014-08-01 20:17:15 +02:00
2014-08-01 19:35:36 +02:00
resultSet = statement . executeQuery ( ) ;
2014-08-01 20:17:15 +02:00
2014-08-01 19:35:36 +02:00
if ( resultSet . next ( ) ) {
2014-08-01 20:17:15 +02:00
try {
2014-08-01 19:35:36 +02:00
PlayerProfile profile = loadFromResult ( playerName , resultSet ) ;
2015-06-12 00:10:53 +02:00
String name = resultSet . getString ( 42 ) ; // TODO: Magic Number, make sure it stays updated
2014-08-01 19:35:36 +02:00
resultSet . close ( ) ;
statement . close ( ) ;
2014-08-01 20:17:15 +02:00
2019-01-26 16:51:30 +01:00
if ( ! playerName . isEmpty ( ) & & ! playerName . equalsIgnoreCase ( name ) & & uuid ! = null ) {
2015-06-20 18:57:01 +02:00
statement = connection . prepareStatement (
" UPDATE ` " + tablePrefix + " users` "
+ " SET user = ? "
+ " WHERE user = ? " ) ;
statement . setString ( 1 , " _INVALID_OLD_USERNAME_ " ) ;
statement . setString ( 2 , name ) ;
statement . executeUpdate ( ) ;
statement . close ( ) ;
2014-08-01 20:17:15 +02:00
statement = connection . prepareStatement (
" UPDATE ` " + tablePrefix + " users` "
2014-08-07 20:16:28 +02:00
+ " SET user = ?, uuid = ? "
+ " WHERE id = ? " ) ;
2014-08-01 20:17:15 +02:00
statement . setString ( 1 , playerName ) ;
2014-08-07 19:54:28 +02:00
statement . setString ( 2 , uuid . toString ( ) ) ;
2014-08-07 20:16:28 +02:00
statement . setInt ( 3 , id ) ;
2014-08-01 19:35:36 +02:00
statement . executeUpdate ( ) ;
statement . close ( ) ;
2014-08-01 20:17:15 +02:00
}
return profile ;
}
catch ( SQLException e ) {
2015-02-16 04:03:41 +01:00
printErrors ( e ) ;
2014-08-01 20:17:15 +02:00
}
}
2014-08-01 19:35:36 +02:00
resultSet . close ( ) ;
2014-08-01 20:17:15 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-01 20:17:15 +02:00
}
// Problem, nothing was returned
2014-08-07 20:16:28 +02:00
// return unloaded profile
2014-08-01 20:17:15 +02:00
if ( ! retry ) {
2014-08-07 20:16:28 +02:00
return new PlayerProfile ( playerName , false ) ;
2014-08-01 20:17:15 +02:00
}
// Retry, and abort on re-failure
return loadPlayerProfile ( playerName , uuid , create , false ) ;
2013-06-29 00:02:58 +02:00
}
2013-06-04 18:14:43 +02:00
2013-06-29 00:02:58 +02:00
public void convertUsers ( DatabaseManager destination ) {
PreparedStatement statement = null ;
2014-08-01 19:35:36 +02:00
Connection connection = null ;
ResultSet resultSet = null ;
2013-06-29 00:02:58 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2013-06-29 00:02:58 +02:00
statement = connection . prepareStatement (
" SELECT "
2014-07-23 02:01:26 +02:00
+ " 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, "
+ " 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, "
2019-01-11 08:52:11 +01:00
+ " 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, c.chimaera_wing, "
2014-02-09 18:12:00 +01:00
+ " h.mobhealthbar, h.scoreboardtips, u.uuid "
2014-07-23 02:01:26 +02:00
+ " FROM " + tablePrefix + " users u "
+ " JOIN " + tablePrefix + " skills s ON (u.id = s.user_id) "
+ " JOIN " + tablePrefix + " experience e ON (u.id = e.user_id) "
+ " JOIN " + tablePrefix + " cooldowns c ON (u.id = c.user_id) "
+ " JOIN " + tablePrefix + " huds h ON (u.id = h.user_id) "
+ " WHERE u.user = ? " ) ;
2013-06-29 00:02:58 +02:00
List < String > usernames = getStoredUsers ( ) ;
2013-10-16 03:32:54 +02:00
int convertedUsers = 0 ;
long startMillis = System . currentTimeMillis ( ) ;
2013-06-29 00:02:58 +02:00
for ( String playerName : usernames ) {
statement . setString ( 1 , playerName ) ;
try {
2014-01-20 22:58:40 +01:00
resultSet = statement . executeQuery ( ) ;
resultSet . next ( ) ;
destination . saveUser ( loadFromResult ( playerName , resultSet ) ) ;
resultSet . close ( ) ;
2013-06-29 00:02:58 +02:00
}
catch ( SQLException e ) {
2015-02-17 03:43:51 +01:00
printErrors ( e ) ;
2013-06-29 00:02:58 +02:00
// Ignore
}
2013-10-16 03:32:54 +02:00
convertedUsers + + ;
2013-10-18 16:43:37 +02:00
Misc . printProgress ( convertedUsers , progressInterval , startMillis ) ;
2013-06-29 00:02:58 +02:00
}
}
catch ( SQLException e ) {
printErrors ( e ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-01 20:17:15 +02:00
}
2013-04-18 23:37:36 +02:00
}
2014-08-01 19:35:36 +02:00
public boolean saveUserUUID ( String userName , UUID uuid ) {
2013-06-04 18:14:43 +02:00
PreparedStatement statement = null ;
2014-08-01 19:35:36 +02:00
Connection connection = null ;
2013-06-04 18:14:43 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement (
" UPDATE ` " + tablePrefix + " users` SET "
+ " uuid = ? WHERE user = ? " ) ;
statement . setString ( 1 , uuid . toString ( ) ) ;
statement . setString ( 2 , userName ) ;
statement . execute ( ) ;
2013-06-04 18:14:43 +02:00
return true ;
}
catch ( SQLException ex ) {
2014-08-01 19:35:36 +02:00
printErrors ( ex ) ;
2013-06-04 18:14:43 +02:00
return false ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
tryClose ( connection ) ;
2013-06-04 18:14:43 +02:00
}
}
2014-08-01 19:35:36 +02:00
public boolean saveUserUUIDs ( Map < String , UUID > fetchedUUIDs ) {
2013-06-04 18:14:43 +02:00
PreparedStatement statement = null ;
2014-08-01 19:35:36 +02:00
int count = 0 ;
Connection connection = null ;
2013-06-04 18:14:43 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " users SET uuid = ? WHERE user = ? " ) ;
for ( Map . Entry < String , UUID > entry : fetchedUUIDs . entrySet ( ) ) {
statement . setString ( 1 , entry . getValue ( ) . toString ( ) ) ;
statement . setString ( 2 , entry . getKey ( ) ) ;
statement . addBatch ( ) ;
count + + ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
if ( ( count % 500 ) = = 0 ) {
statement . executeBatch ( ) ;
count = 0 ;
}
}
if ( count ! = 0 ) {
statement . executeBatch ( ) ;
2013-06-04 18:14:43 +02:00
}
2013-10-06 00:18:10 +02:00
return true ;
2013-06-04 18:14:43 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
2013-10-06 00:18:10 +02:00
return false ;
2013-06-04 18:14:43 +02:00
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
tryClose ( connection ) ;
2013-06-04 18:14:43 +02:00
}
}
2014-08-01 19:35:36 +02:00
public List < String > getStoredUsers ( ) {
ArrayList < String > users = new ArrayList < String > ( ) ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
Statement statement = null ;
Connection connection = null ;
ResultSet resultSet = null ;
2013-06-04 18:14:43 +02:00
2014-08-01 19:35:36 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-01 19:35:36 +02:00
statement = connection . createStatement ( ) ;
resultSet = statement . executeQuery ( " SELECT user FROM " + tablePrefix + " users " ) ;
while ( resultSet . next ( ) ) {
users . add ( resultSet . getString ( " user " ) ) ;
2013-06-04 18:14:43 +02:00
}
}
2014-08-01 19:35:36 +02:00
catch ( SQLException e ) {
printErrors ( e ) ;
2013-06-04 18:14:43 +02:00
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( connection ) ;
2013-06-04 18:14:43 +02:00
}
2014-08-01 19:35:36 +02:00
return users ;
2013-06-04 18:14:43 +02:00
}
2013-07-01 07:37:24 +02:00
/ * *
2014-08-01 19:35:36 +02:00
* Checks that the database structure is present and correct
2013-07-01 07:37:24 +02:00
* /
2014-08-01 19:35:36 +02:00
private void checkStructure ( ) {
2013-06-04 18:14:43 +02:00
2014-08-08 06:42:33 +02:00
PreparedStatement statement = null ;
Statement createStatement = null ;
ResultSet resultSet = null ;
2014-08-01 19:35:36 +02:00
Connection connection = null ;
2014-08-01 20:17:15 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = getConnection ( PoolIdentifier . MISC ) ;
2014-08-08 06:42:33 +02:00
statement = connection . prepareStatement ( " SELECT table_name FROM INFORMATION_SCHEMA.TABLES "
+ " WHERE table_schema = ? "
+ " AND table_name = ? " ) ;
statement . setString ( 1 , Config . getInstance ( ) . getMySQLDatabaseName ( ) ) ;
statement . setString ( 2 , tablePrefix + " users " ) ;
resultSet = statement . executeQuery ( ) ;
if ( ! resultSet . next ( ) ) {
createStatement = connection . createStatement ( ) ;
createStatement . executeUpdate ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " users` ( "
2014-08-01 19:35:36 +02:00
+ " `id` int(10) unsigned NOT NULL AUTO_INCREMENT, "
+ " `user` varchar(40) NOT NULL, "
+ " `uuid` varchar(36) NULL DEFAULT NULL, "
+ " `lastlogin` int(32) unsigned NOT NULL, "
+ " PRIMARY KEY (`id`), "
2015-06-20 18:57:01 +02:00
+ " INDEX(`user`(20) ASC), "
2014-08-01 19:35:36 +02:00
+ " UNIQUE KEY `uuid` (`uuid`)) DEFAULT CHARSET=latin1 AUTO_INCREMENT=1; " ) ;
2015-11-13 01:10:09 +01:00
tryClose ( createStatement ) ;
2014-08-08 06:42:33 +02:00
}
2015-11-13 01:10:09 +01:00
tryClose ( resultSet ) ;
2014-08-08 06:42:33 +02:00
statement . setString ( 1 , Config . getInstance ( ) . getMySQLDatabaseName ( ) ) ;
statement . setString ( 2 , tablePrefix + " huds " ) ;
resultSet = statement . executeQuery ( ) ;
if ( ! resultSet . next ( ) ) {
createStatement = connection . createStatement ( ) ;
createStatement . executeUpdate ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " huds` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
+ " `mobhealthbar` varchar(50) NOT NULL DEFAULT ' " + Config . getInstance ( ) . getMobHealthbarDefault ( ) + " ', "
2014-02-09 18:12:00 +01:00
+ " `scoreboardtips` int(10) NOT NULL DEFAULT '0', "
2014-08-08 06:42:33 +02:00
+ " PRIMARY KEY (`user_id`)) "
+ " DEFAULT CHARSET=latin1; " ) ;
2015-11-13 01:10:09 +01:00
tryClose ( createStatement ) ;
2014-08-08 06:42:33 +02:00
}
2015-11-13 01:10:09 +01:00
tryClose ( resultSet ) ;
2014-08-08 06:42:33 +02:00
statement . setString ( 1 , Config . getInstance ( ) . getMySQLDatabaseName ( ) ) ;
statement . setString ( 2 , tablePrefix + " cooldowns " ) ;
resultSet = statement . executeQuery ( ) ;
if ( ! resultSet . next ( ) ) {
createStatement = connection . createStatement ( ) ;
createStatement . executeUpdate ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " cooldowns` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
+ " `taming` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `mining` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `woodcutting` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `repair` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `unarmed` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `herbalism` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `excavation` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `archery` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `swords` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `axes` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `acrobatics` int(32) unsigned NOT NULL DEFAULT '0', "
+ " `blast_mining` int(32) unsigned NOT NULL DEFAULT '0', "
2019-01-11 08:52:11 +01:00
+ " `chimaera_wing` int(32) unsigned NOT NULL DEFAULT '0', "
2014-08-08 06:42:33 +02:00
+ " PRIMARY KEY (`user_id`)) "
+ " DEFAULT CHARSET=latin1; " ) ;
2015-11-13 01:10:09 +01:00
tryClose ( createStatement ) ;
2014-08-08 06:42:33 +02:00
}
2015-11-13 01:10:09 +01:00
tryClose ( resultSet ) ;
2014-08-08 06:42:33 +02:00
statement . setString ( 1 , Config . getInstance ( ) . getMySQLDatabaseName ( ) ) ;
statement . setString ( 2 , tablePrefix + " skills " ) ;
resultSet = statement . executeQuery ( ) ;
if ( ! resultSet . next ( ) ) {
2019-01-18 22:10:45 +01:00
String startingLevel = " ' " + AdvancedConfig . getInstance ( ) . getStartingLevel ( ) + " ' " ;
String totalLevel = " ' " + ( AdvancedConfig . getInstance ( ) . getStartingLevel ( ) * ( PrimarySkillType . values ( ) . length - PrimarySkillType . CHILD_SKILLS . size ( ) ) ) + " ' " ;
2014-08-08 06:42:33 +02:00
createStatement = connection . createStatement ( ) ;
createStatement . executeUpdate ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " skills` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
2019-01-18 22:10:45 +01:00
+ " `taming` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `mining` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `woodcutting` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `repair` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `unarmed` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `herbalism` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `excavation` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `archery` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `swords` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `axes` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `acrobatics` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `fishing` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `alchemy` int(10) unsigned NOT NULL DEFAULT " + startingLevel + " , "
+ " `total` int(10) unsigned NOT NULL DEFAULT " + totalLevel + " , "
2014-08-08 06:42:33 +02:00
+ " PRIMARY KEY (`user_id`)) "
+ " DEFAULT CHARSET=latin1; " ) ;
2015-11-13 01:10:09 +01:00
tryClose ( createStatement ) ;
2014-08-08 06:42:33 +02:00
}
2015-11-13 01:10:09 +01:00
tryClose ( resultSet ) ;
2014-08-08 06:42:33 +02:00
statement . setString ( 1 , Config . getInstance ( ) . getMySQLDatabaseName ( ) ) ;
statement . setString ( 2 , tablePrefix + " experience " ) ;
resultSet = statement . executeQuery ( ) ;
if ( ! resultSet . next ( ) ) {
createStatement = connection . createStatement ( ) ;
createStatement . executeUpdate ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " experience` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
+ " `taming` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `mining` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `woodcutting` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `repair` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `unarmed` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `herbalism` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `excavation` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `archery` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `swords` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `axes` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `acrobatics` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `fishing` int(10) unsigned NOT NULL DEFAULT '0', "
+ " `alchemy` int(10) unsigned NOT NULL DEFAULT '0', "
+ " PRIMARY KEY (`user_id`)) "
+ " DEFAULT CHARSET=latin1; " ) ;
2015-11-13 01:10:09 +01:00
tryClose ( createStatement ) ;
2014-08-08 06:42:33 +02:00
}
2015-11-13 01:10:09 +01:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
2014-08-01 19:35:36 +02:00
for ( UpgradeType updateType : UpgradeType . values ( ) ) {
checkDatabaseStructure ( connection , updateType ) ;
}
2015-11-13 01:10:09 +01:00
if ( Config . getInstance ( ) . getTruncateSkills ( ) ) {
2019-01-13 08:54:53 +01:00
for ( PrimarySkillType skill : PrimarySkillType . NON_CHILD_SKILLS ) {
2015-11-13 01:10:09 +01:00
int cap = Config . getInstance ( ) . getLevelCap ( skill ) ;
if ( cap ! = Integer . MAX_VALUE ) {
statement = connection . prepareStatement ( " UPDATE ` " + tablePrefix + " skills` SET ` " + skill . name ( ) . toLowerCase ( ) + " ` = " + cap + " WHERE ` " + skill . name ( ) . toLowerCase ( ) + " ` > " + cap ) ;
statement . executeUpdate ( ) ;
tryClose ( statement ) ;
}
}
}
2014-08-01 19:35:36 +02:00
mcMMO . p . getLogger ( ) . info ( " Killing orphans " ) ;
2014-08-08 06:42:33 +02:00
createStatement = connection . createStatement ( ) ;
createStatement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " experience` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " users` `u` WHERE ` " + tablePrefix + " experience`.`user_id` = `u`.`id`) " ) ;
createStatement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " huds` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " users` `u` WHERE ` " + tablePrefix + " huds`.`user_id` = `u`.`id`) " ) ;
createStatement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " cooldowns` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " users` `u` WHERE ` " + tablePrefix + " cooldowns`.`user_id` = `u`.`id`) " ) ;
createStatement . executeUpdate ( " DELETE FROM ` " + tablePrefix + " skills` WHERE NOT EXISTS (SELECT * FROM ` " + tablePrefix + " users` `u` WHERE ` " + tablePrefix + " skills`.`user_id` = `u`.`id`) " ) ;
2014-08-01 20:17:15 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( createStatement ) ;
tryClose ( connection ) ;
2014-08-01 20:17:15 +02:00
}
2014-08-01 19:35:36 +02:00
2014-08-01 20:17:15 +02:00
}
2014-08-19 23:57:52 +02:00
private Connection getConnection ( PoolIdentifier identifier ) throws SQLException {
Connection connection = null ;
switch ( identifier ) {
case LOAD :
2014-10-15 05:59:41 +02:00
connection = loadPool . getConnection ( ) ;
2014-08-19 23:57:52 +02:00
break ;
case MISC :
2014-10-15 05:59:41 +02:00
connection = miscPool . getConnection ( ) ;
2014-08-19 23:57:52 +02:00
break ;
case SAVE :
2014-10-15 05:59:41 +02:00
connection = savePool . getConnection ( ) ;
2014-08-19 23:57:52 +02:00
break ;
}
2014-08-12 17:39:43 +02:00
if ( connection = = null ) {
2014-08-19 23:57:52 +02:00
throw new RuntimeException ( " getConnection() for " + identifier . name ( ) . toLowerCase ( ) + " pool timed out. Increase max connections settings. " ) ;
2014-08-12 17:39:43 +02:00
}
return connection ;
}
2014-08-01 19:35:36 +02:00
/ * *
* Check database structure for necessary upgrades .
*
* @param upgrade Upgrade to attempt to apply
* /
private void checkDatabaseStructure ( Connection connection , UpgradeType upgrade ) {
if ( ! mcMMO . getUpgradeManager ( ) . shouldUpgrade ( upgrade ) ) {
mcMMO . p . debug ( " Skipping " + upgrade . name ( ) + " upgrade (unneeded) " ) ;
return ;
}
Statement statement = null ;
2013-06-04 18:14:43 +02:00
try {
2014-08-01 19:35:36 +02:00
statement = connection . createStatement ( ) ;
switch ( upgrade ) {
case ADD_FISHING :
checkUpgradeAddFishing ( statement ) ;
break ;
case ADD_BLAST_MINING_COOLDOWN :
checkUpgradeAddBlastMiningCooldown ( statement ) ;
break ;
case ADD_SQL_INDEXES :
checkUpgradeAddSQLIndexes ( statement ) ;
break ;
case ADD_MOB_HEALTHBARS :
checkUpgradeAddMobHealthbars ( statement ) ;
break ;
case DROP_SQL_PARTY_NAMES :
checkUpgradeDropPartyNames ( statement ) ;
break ;
case DROP_SPOUT :
checkUpgradeDropSpout ( statement ) ;
break ;
case ADD_ALCHEMY :
checkUpgradeAddAlchemy ( statement ) ;
break ;
case ADD_UUIDS :
checkUpgradeAddUUIDs ( statement ) ;
return ;
2014-02-09 18:12:00 +01:00
case ADD_SCOREBOARD_TIPS :
checkUpgradeAddScoreboardTips ( statement ) ;
return ;
2015-06-20 18:57:01 +02:00
case DROP_NAME_UNIQUENESS :
checkNameUniqueness ( statement ) ;
return ;
2018-11-15 02:31:57 +01:00
case ADD_SKILL_TOTAL :
checkUpgradeSkillTotal ( connection ) ;
break ;
2019-01-11 08:52:11 +01:00
case ADD_UNIQUE_PLAYER_DATA :
checkUpgradeAddUniqueChimaeraWing ( statement ) ;
break ;
2018-11-15 02:31:57 +01:00
2014-08-01 19:35:36 +02:00
default :
break ;
}
mcMMO . getUpgradeManager ( ) . setUpgradeCompleted ( upgrade ) ;
2013-06-04 18:14:43 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
2013-06-04 18:14:43 +02:00
}
}
2014-08-01 19:35:36 +02:00
private void writeMissingRows ( Connection connection , int id ) {
2013-06-04 18:14:43 +02:00
PreparedStatement statement = null ;
try {
2014-08-01 19:35:36 +02:00
statement = connection . prepareStatement ( " INSERT IGNORE INTO " + tablePrefix + " experience (user_id) VALUES (?) " ) ;
statement . setInt ( 1 , id ) ;
2013-06-04 18:14:43 +02:00
statement . execute ( ) ;
2014-08-01 19:35:36 +02:00
statement . close ( ) ;
statement = connection . prepareStatement ( " INSERT IGNORE INTO " + tablePrefix + " skills (user_id) VALUES (?) " ) ;
statement . setInt ( 1 , id ) ;
statement . execute ( ) ;
statement . close ( ) ;
statement = connection . prepareStatement ( " INSERT IGNORE INTO " + tablePrefix + " cooldowns (user_id) VALUES (?) " ) ;
statement . setInt ( 1 , id ) ;
statement . execute ( ) ;
statement . close ( ) ;
2014-02-09 18:12:00 +01:00
statement = connection . prepareStatement ( " INSERT IGNORE INTO " + tablePrefix + " huds (user_id, mobhealthbar, scoreboardtips) VALUES (?, ?, ?) " ) ;
2014-08-01 19:35:36 +02:00
statement . setInt ( 1 , id ) ;
statement . setString ( 2 , Config . getInstance ( ) . getMobHealthbarDefault ( ) . name ( ) ) ;
2014-02-09 18:12:00 +01:00
statement . setInt ( 3 , 0 ) ;
2014-08-01 19:35:36 +02:00
statement . execute ( ) ;
statement . close ( ) ;
2013-06-04 18:14:43 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( statement ) ;
2013-06-04 18:14:43 +02:00
}
2014-08-01 19:35:36 +02:00
}
2013-06-29 00:02:58 +02:00
private PlayerProfile loadFromResult ( String playerName , ResultSet result ) throws SQLException {
2019-01-13 08:54:53 +01:00
Map < PrimarySkillType , Integer > skills = new EnumMap < PrimarySkillType , Integer > ( PrimarySkillType . class ) ; // Skill & Level
Map < PrimarySkillType , Float > skillsXp = new EnumMap < PrimarySkillType , Float > ( PrimarySkillType . class ) ; // Skill & XP
2019-01-13 04:56:54 +01:00
Map < SuperAbilityType , Integer > skillsDATS = new EnumMap < SuperAbilityType , Integer > ( SuperAbilityType . class ) ; // Ability & Cooldown
2019-01-11 08:52:11 +01:00
Map < UniqueDataType , Integer > uniqueData = new EnumMap < UniqueDataType , Integer > ( UniqueDataType . class ) ; //Chimaera wing cooldown and other misc info
2013-06-29 00:02:58 +02:00
MobHealthbarType mobHealthbarType ;
2014-08-01 20:17:15 +02:00
UUID uuid ;
2014-02-09 18:12:00 +01:00
int scoreboardTipsShown ;
2013-06-29 00:02:58 +02:00
2014-08-01 19:35:36 +02:00
final int OFFSET_SKILLS = 0 ; // TODO update these numbers when the query
// changes (a new skill is added)
2014-01-21 20:16:39 +01:00
final int OFFSET_XP = 13 ;
final int OFFSET_DATS = 26 ;
2019-01-11 08:52:11 +01:00
final int OFFSET_OTHER = 39 ;
2013-06-29 00:02:58 +02:00
2019-01-13 08:54:53 +01:00
skills . put ( PrimarySkillType . TAMING , result . getInt ( OFFSET_SKILLS + 1 ) ) ;
skills . put ( PrimarySkillType . MINING , result . getInt ( OFFSET_SKILLS + 2 ) ) ;
skills . put ( PrimarySkillType . REPAIR , result . getInt ( OFFSET_SKILLS + 3 ) ) ;
skills . put ( PrimarySkillType . WOODCUTTING , result . getInt ( OFFSET_SKILLS + 4 ) ) ;
skills . put ( PrimarySkillType . UNARMED , result . getInt ( OFFSET_SKILLS + 5 ) ) ;
skills . put ( PrimarySkillType . HERBALISM , result . getInt ( OFFSET_SKILLS + 6 ) ) ;
skills . put ( PrimarySkillType . EXCAVATION , result . getInt ( OFFSET_SKILLS + 7 ) ) ;
skills . put ( PrimarySkillType . ARCHERY , result . getInt ( OFFSET_SKILLS + 8 ) ) ;
skills . put ( PrimarySkillType . SWORDS , result . getInt ( OFFSET_SKILLS + 9 ) ) ;
skills . put ( PrimarySkillType . AXES , result . getInt ( OFFSET_SKILLS + 10 ) ) ;
skills . put ( PrimarySkillType . ACROBATICS , result . getInt ( OFFSET_SKILLS + 11 ) ) ;
skills . put ( PrimarySkillType . FISHING , result . getInt ( OFFSET_SKILLS + 12 ) ) ;
skills . put ( PrimarySkillType . ALCHEMY , result . getInt ( OFFSET_SKILLS + 13 ) ) ;
skillsXp . put ( PrimarySkillType . TAMING , result . getFloat ( OFFSET_XP + 1 ) ) ;
skillsXp . put ( PrimarySkillType . MINING , result . getFloat ( OFFSET_XP + 2 ) ) ;
skillsXp . put ( PrimarySkillType . REPAIR , result . getFloat ( OFFSET_XP + 3 ) ) ;
skillsXp . put ( PrimarySkillType . WOODCUTTING , result . getFloat ( OFFSET_XP + 4 ) ) ;
skillsXp . put ( PrimarySkillType . UNARMED , result . getFloat ( OFFSET_XP + 5 ) ) ;
skillsXp . put ( PrimarySkillType . HERBALISM , result . getFloat ( OFFSET_XP + 6 ) ) ;
skillsXp . put ( PrimarySkillType . EXCAVATION , result . getFloat ( OFFSET_XP + 7 ) ) ;
skillsXp . put ( PrimarySkillType . ARCHERY , result . getFloat ( OFFSET_XP + 8 ) ) ;
skillsXp . put ( PrimarySkillType . SWORDS , result . getFloat ( OFFSET_XP + 9 ) ) ;
skillsXp . put ( PrimarySkillType . AXES , result . getFloat ( OFFSET_XP + 10 ) ) ;
skillsXp . put ( PrimarySkillType . ACROBATICS , result . getFloat ( OFFSET_XP + 11 ) ) ;
skillsXp . put ( PrimarySkillType . FISHING , result . getFloat ( OFFSET_XP + 12 ) ) ;
skillsXp . put ( PrimarySkillType . ALCHEMY , result . getFloat ( OFFSET_XP + 13 ) ) ;
2013-06-29 00:02:58 +02:00
// Taming - Unused - result.getInt(OFFSET_DATS + 1)
2019-01-13 04:56:54 +01:00
skillsDATS . put ( SuperAbilityType . SUPER_BREAKER , result . getInt ( OFFSET_DATS + 2 ) ) ;
2013-06-29 00:02:58 +02:00
// Repair - Unused - result.getInt(OFFSET_DATS + 3)
2019-01-13 04:56:54 +01:00
skillsDATS . put ( SuperAbilityType . TREE_FELLER , result . getInt ( OFFSET_DATS + 4 ) ) ;
skillsDATS . put ( SuperAbilityType . BERSERK , result . getInt ( OFFSET_DATS + 5 ) ) ;
skillsDATS . put ( SuperAbilityType . GREEN_TERRA , result . getInt ( OFFSET_DATS + 6 ) ) ;
skillsDATS . put ( SuperAbilityType . GIGA_DRILL_BREAKER , result . getInt ( OFFSET_DATS + 7 ) ) ;
2013-06-29 00:02:58 +02:00
// Archery - Unused - result.getInt(OFFSET_DATS + 8)
2019-01-13 04:56:54 +01:00
skillsDATS . put ( SuperAbilityType . SERRATED_STRIKES , result . getInt ( OFFSET_DATS + 9 ) ) ;
skillsDATS . put ( SuperAbilityType . SKULL_SPLITTER , result . getInt ( OFFSET_DATS + 10 ) ) ;
2013-06-29 00:02:58 +02:00
// Acrobatics - Unused - result.getInt(OFFSET_DATS + 11)
2019-01-13 04:56:54 +01:00
skillsDATS . put ( SuperAbilityType . BLAST_MINING , result . getInt ( OFFSET_DATS + 12 ) ) ;
2019-01-11 08:52:11 +01:00
uniqueData . put ( UniqueDataType . CHIMAERA_WING_DATS , result . getInt ( OFFSET_DATS + 13 ) ) ;
2013-06-29 00:02:58 +02:00
try {
2014-02-09 18:12:00 +01:00
mobHealthbarType = MobHealthbarType . valueOf ( result . getString ( OFFSET_OTHER + 1 ) ) ;
2013-06-29 00:02:58 +02:00
}
catch ( Exception e ) {
mobHealthbarType = Config . getInstance ( ) . getMobHealthbarDefault ( ) ;
}
2014-02-09 18:12:00 +01:00
try {
scoreboardTipsShown = result . getInt ( OFFSET_OTHER + 2 ) ;
}
catch ( Exception e ) {
scoreboardTipsShown = 0 ;
}
2014-08-01 20:17:15 +02:00
try {
uuid = UUID . fromString ( result . getString ( OFFSET_OTHER + 3 ) ) ;
}
catch ( Exception e ) {
uuid = null ;
}
2019-01-11 08:52:11 +01:00
return new PlayerProfile ( playerName , uuid , skills , skillsXp , skillsDATS , mobHealthbarType , scoreboardTipsShown , uniqueData ) ;
2013-06-29 00:02:58 +02:00
}
2013-06-04 18:14:43 +02:00
private void printErrors ( SQLException ex ) {
2014-08-20 01:11:07 +02:00
StackTraceElement element = ex . getStackTrace ( ) [ 0 ] ;
2014-08-12 17:39:43 +02:00
mcMMO . p . getLogger ( ) . severe ( " Location: " + element . getClassName ( ) + " " + element . getMethodName ( ) + " " + element . getLineNumber ( ) ) ;
2013-04-18 23:37:36 +02:00
mcMMO . p . getLogger ( ) . severe ( " SQLException: " + ex . getMessage ( ) ) ;
mcMMO . p . getLogger ( ) . severe ( " SQLState: " + ex . getSQLState ( ) ) ;
mcMMO . p . getLogger ( ) . severe ( " VendorError: " + ex . getErrorCode ( ) ) ;
}
2013-08-22 15:11:33 +02:00
public DatabaseType getDatabaseType ( ) {
return DatabaseType . SQL ;
}
2014-08-01 20:17:15 +02:00
2018-07-24 04:13:57 +02:00
private void checkNameUniqueness ( final Statement statement ) {
2015-06-20 18:57:01 +02:00
ResultSet resultSet = null ;
try {
2015-06-20 21:11:18 +02:00
resultSet = statement . executeQuery ( " SHOW INDEXES "
2015-06-20 18:57:01 +02:00
+ " FROM ` " + tablePrefix + " users` "
+ " WHERE Column_name='user' "
+ " AND NOT Non_unique " ) ;
if ( ! resultSet . next ( ) ) {
return ;
}
resultSet . close ( ) ;
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables to drop name uniqueness... " ) ;
2015-06-20 21:11:18 +02:00
statement . execute ( " ALTER TABLE ` " + tablePrefix + " users` "
2015-06-20 18:57:01 +02:00
+ " DROP INDEX `user`, "
+ " ADD INDEX `user` (`user`(20) ASC) " ) ;
} catch ( SQLException ex ) {
2019-01-15 10:11:33 +01:00
ex . printStackTrace ( ) ;
2015-06-20 18:57:01 +02:00
} finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
2015-06-20 18:57:01 +02:00
}
}
2014-08-01 20:17:15 +02:00
private void checkUpgradeAddAlchemy ( final Statement statement ) throws SQLException {
try {
statement . executeQuery ( " SELECT `alchemy` FROM ` " + tablePrefix + " skills` LIMIT 1 " ) ;
}
catch ( SQLException ex ) {
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for Alchemy... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " skills` ADD `alchemy` int(10) NOT NULL DEFAULT '0' " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " experience` ADD `alchemy` int(10) NOT NULL DEFAULT '0' " ) ;
}
}
private void checkUpgradeAddBlastMiningCooldown ( final Statement statement ) throws SQLException {
try {
statement . executeQuery ( " SELECT `blast_mining` FROM ` " + tablePrefix + " cooldowns` LIMIT 1 " ) ;
}
catch ( SQLException ex ) {
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for Blast Mining... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0' " ) ;
}
}
2019-01-11 08:52:11 +01:00
private void checkUpgradeAddUniqueChimaeraWing ( final Statement statement ) throws SQLException {
try {
statement . executeQuery ( " SELECT `chimaera_wing` FROM ` " + tablePrefix + " cooldowns` LIMIT 1 " ) ;
}
catch ( SQLException ex ) {
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for Chimaera Wing... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " cooldowns` ADD `chimaera_wing` int(32) NOT NULL DEFAULT '0' " ) ;
}
}
2014-08-01 20:17:15 +02:00
private void checkUpgradeAddFishing ( final Statement statement ) throws SQLException {
try {
statement . executeQuery ( " SELECT `fishing` FROM ` " + tablePrefix + " skills` LIMIT 1 " ) ;
}
catch ( SQLException ex ) {
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for Fishing... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " skills` ADD `fishing` int(10) NOT NULL DEFAULT '0' " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " experience` ADD `fishing` int(10) NOT NULL DEFAULT '0' " ) ;
}
}
private void checkUpgradeAddMobHealthbars ( final Statement statement ) throws SQLException {
try {
statement . executeQuery ( " SELECT `mobhealthbar` FROM ` " + tablePrefix + " huds` LIMIT 1 " ) ;
}
catch ( SQLException ex ) {
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for mob healthbars... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT ' " + Config . getInstance ( ) . getMobHealthbarDefault ( ) + " ' " ) ;
}
}
2014-02-09 18:12:00 +01:00
private void checkUpgradeAddScoreboardTips ( final Statement statement ) throws SQLException {
try {
statement . executeQuery ( " SELECT `scoreboardtips` FROM ` " + tablePrefix + " huds` LIMIT 1 " ) ;
}
catch ( SQLException ex ) {
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for scoreboard tips... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " huds` ADD `scoreboardtips` int(10) NOT NULL DEFAULT '0' ; " ) ;
}
}
2018-07-24 04:13:57 +02:00
private void checkUpgradeAddSQLIndexes ( final Statement statement ) {
2014-08-01 20:17:15 +02:00
ResultSet resultSet = null ;
try {
resultSet = statement . executeQuery ( " SHOW INDEX FROM ` " + tablePrefix + " skills` WHERE `Key_name` LIKE 'idx \\ _%' " ) ;
resultSet . last ( ) ;
2019-01-13 08:54:53 +01:00
if ( resultSet . getRow ( ) ! = PrimarySkillType . NON_CHILD_SKILLS . size ( ) ) {
2014-08-01 20:17:15 +02:00
mcMMO . p . getLogger ( ) . info ( " Indexing tables, this may take a while on larger databases " ) ;
2019-01-13 08:54:53 +01:00
for ( PrimarySkillType skill : PrimarySkillType . NON_CHILD_SKILLS ) {
2014-08-01 20:17:15 +02:00
String skill_name = skill . name ( ) . toLowerCase ( ) ;
try {
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " skills` ADD INDEX `idx_ " + skill_name + " ` (` " + skill_name + " `) USING BTREE " ) ;
}
catch ( SQLException ex ) {
// Ignore
}
}
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
2014-08-01 20:17:15 +02:00
}
}
private void checkUpgradeAddUUIDs ( final Statement statement ) {
ResultSet resultSet = null ;
try {
resultSet = statement . executeQuery ( " SELECT * FROM ` " + tablePrefix + " users` LIMIT 1 " ) ;
ResultSetMetaData rsmeta = resultSet . getMetaData ( ) ;
boolean column_exists = false ;
for ( int i = 1 ; i < = rsmeta . getColumnCount ( ) ; i + + ) {
if ( rsmeta . getColumnName ( i ) . equalsIgnoreCase ( " uuid " ) ) {
column_exists = true ;
break ;
}
}
if ( ! column_exists ) {
mcMMO . p . getLogger ( ) . info ( " Adding UUIDs to mcMMO MySQL user table... " ) ;
2014-08-01 19:35:36 +02:00
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " users` ADD `uuid` varchar(36) NULL DEFAULT NULL " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " users` ADD UNIQUE INDEX `uuid` (`uuid`) USING BTREE " ) ;
2014-08-01 20:17:15 +02:00
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
2014-08-01 20:17:15 +02:00
}
2014-08-04 17:49:09 +02:00
new GetUUIDUpdatesRequired ( ) . runTaskLaterAsynchronously ( mcMMO . p , 100 ) ; // wait until after first purge
2014-08-04 17:42:02 +02:00
}
2014-08-01 20:17:15 +02:00
2014-08-04 17:42:02 +02:00
private class GetUUIDUpdatesRequired extends BukkitRunnable {
public void run ( ) {
massUpdateLock . lock ( ) ;
List < String > names = new ArrayList < String > ( ) ;
Connection connection = null ;
Statement statement = null ;
ResultSet resultSet = null ;
try {
2014-08-01 20:17:15 +02:00
try {
2014-08-19 23:57:52 +02:00
connection = miscPool . getConnection ( ) ;
2014-08-04 17:42:02 +02:00
statement = connection . createStatement ( ) ;
resultSet = statement . executeQuery ( " SELECT `user` FROM ` " + tablePrefix + " users` WHERE `uuid` IS NULL " ) ;
while ( resultSet . next ( ) ) {
names . add ( resultSet . getString ( " user " ) ) ;
}
} catch ( SQLException ex ) {
printErrors ( ex ) ;
} finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
tryClose ( connection ) ;
2014-08-01 20:17:15 +02:00
}
2014-08-04 17:42:02 +02:00
if ( ! names . isEmpty ( ) ) {
2018-07-24 04:13:57 +02:00
new UUIDUpdateAsyncTask ( mcMMO . p , names ) . run ( ) ;
2014-08-01 20:17:15 +02:00
}
2014-08-04 17:42:02 +02:00
} finally {
massUpdateLock . unlock ( ) ;
2014-08-01 20:17:15 +02:00
}
}
}
private void checkUpgradeDropPartyNames ( final Statement statement ) {
ResultSet resultSet = null ;
try {
resultSet = statement . executeQuery ( " SELECT * FROM ` " + tablePrefix + " users` LIMIT 1 " ) ;
ResultSetMetaData rsmeta = resultSet . getMetaData ( ) ;
boolean column_exists = false ;
for ( int i = 1 ; i < = rsmeta . getColumnCount ( ) ; i + + ) {
if ( rsmeta . getColumnName ( i ) . equalsIgnoreCase ( " party " ) ) {
column_exists = true ;
break ;
}
}
if ( column_exists ) {
mcMMO . p . getLogger ( ) . info ( " Removing party name from users table... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " users` DROP COLUMN `party` " ) ;
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
2014-08-01 20:17:15 +02:00
}
}
2018-11-15 02:31:57 +01:00
private void checkUpgradeSkillTotal ( final Connection connection ) throws SQLException {
ResultSet resultSet = null ;
Statement statement = null ;
try {
connection . setAutoCommit ( false ) ;
statement = connection . createStatement ( ) ;
resultSet = statement . executeQuery ( " SELECT * FROM ` " + tablePrefix + " skills` LIMIT 1 " ) ;
ResultSetMetaData rsmeta = resultSet . getMetaData ( ) ;
boolean column_exists = false ;
for ( int i = 1 ; i < = rsmeta . getColumnCount ( ) ; i + + ) {
if ( rsmeta . getColumnName ( i ) . equalsIgnoreCase ( " total " ) ) {
column_exists = true ;
break ;
}
}
if ( ! column_exists ) {
mcMMO . p . getLogger ( ) . info ( " Adding skill total column to skills table... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " skills` ADD COLUMN `total` int NOT NULL DEFAULT '0' " ) ;
statement . executeUpdate ( " UPDATE ` " + tablePrefix + " skills` SET `total` = (taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy) " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " skills` ADD INDEX `idx_total` (`total`) USING BTREE " ) ;
connection . commit ( ) ;
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
connection . setAutoCommit ( true ) ;
tryClose ( resultSet ) ;
tryClose ( statement ) ;
}
}
2014-08-01 20:17:15 +02:00
private void checkUpgradeDropSpout ( final Statement statement ) {
ResultSet resultSet = null ;
try {
resultSet = statement . executeQuery ( " SELECT * FROM ` " + tablePrefix + " huds` LIMIT 1 " ) ;
ResultSetMetaData rsmeta = resultSet . getMetaData ( ) ;
boolean column_exists = false ;
for ( int i = 1 ; i < = rsmeta . getColumnCount ( ) ; i + + ) {
if ( rsmeta . getColumnName ( i ) . equalsIgnoreCase ( " hudtype " ) ) {
column_exists = true ;
break ;
}
}
if ( column_exists ) {
mcMMO . p . getLogger ( ) . info ( " Removing Spout HUD type from huds table... " ) ;
statement . executeUpdate ( " ALTER TABLE ` " + tablePrefix + " huds` DROP COLUMN `hudtype` " ) ;
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
2014-08-01 20:17:15 +02:00
}
}
2014-08-01 19:35:36 +02:00
2014-08-07 20:16:28 +02:00
private int getUserID ( final Connection connection , final String playerName , final UUID uuid ) {
2019-01-06 01:21:15 +01:00
if ( uuid = = null )
return getUserIDByName ( connection , playerName ) ;
if ( cachedUserIDs . containsKey ( uuid ) )
2014-08-01 19:35:36 +02:00
return cachedUserIDs . get ( uuid ) ;
ResultSet resultSet = null ;
PreparedStatement statement = null ;
try {
2014-08-08 06:09:00 +02:00
statement = connection . prepareStatement ( " SELECT id, user FROM " + tablePrefix + " users WHERE uuid = ? OR (uuid IS NULL AND user = ?) " ) ;
2019-01-06 01:21:15 +01:00
statement . setString ( 1 , uuid . toString ( ) ) ;
2014-08-07 20:16:28 +02:00
statement . setString ( 2 , playerName ) ;
2014-08-01 19:35:36 +02:00
resultSet = statement . executeQuery ( ) ;
if ( resultSet . next ( ) ) {
int id = resultSet . getInt ( " id " ) ;
2019-01-06 01:21:15 +01:00
cachedUserIDs . put ( uuid , id ) ;
return id ;
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
tryClose ( resultSet ) ;
tryClose ( statement ) ;
}
return - 1 ;
}
private int getUserIDByName ( final Connection connection , final String playerName ) {
ResultSet resultSet = null ;
PreparedStatement statement = null ;
try {
statement = connection . prepareStatement ( " SELECT id, user FROM " + tablePrefix + " users WHERE user = ? " ) ;
statement . setString ( 1 , playerName ) ;
resultSet = statement . executeQuery ( ) ;
if ( resultSet . next ( ) ) {
int id = resultSet . getInt ( " id " ) ;
2014-08-01 19:35:36 +02:00
return id ;
}
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
2015-07-18 16:48:40 +02:00
tryClose ( resultSet ) ;
tryClose ( statement ) ;
2014-08-01 19:35:36 +02:00
}
return - 1 ;
}
2015-07-18 16:48:40 +02:00
private void tryClose ( AutoCloseable closeable ) {
if ( closeable ! = null ) {
try {
closeable . close ( ) ;
}
catch ( Exception e ) {
// Ignore
}
}
}
2014-08-01 19:35:36 +02:00
@Override
public void onDisable ( ) {
2014-08-08 06:02:07 +02:00
mcMMO . p . debug ( " Releasing connection pool resource... " ) ;
2014-10-15 05:59:41 +02:00
miscPool . close ( ) ;
loadPool . close ( ) ;
savePool . close ( ) ;
2014-08-19 23:57:52 +02:00
}
public enum PoolIdentifier {
MISC ,
LOAD ,
2018-07-24 04:13:57 +02:00
SAVE
2014-08-01 19:35:36 +02:00
}
2016-04-23 06:24:05 +02:00
public void resetMobHealthSettings ( ) {
PreparedStatement statement = null ;
Connection connection = null ;
try {
connection = getConnection ( PoolIdentifier . MISC ) ;
statement = connection . prepareStatement ( " UPDATE " + tablePrefix + " huds SET mobhealthbar = ? " ) ;
statement . setString ( 1 , Config . getInstance ( ) . getMobHealthbarDefault ( ) . toString ( ) ) ;
statement . executeUpdate ( ) ;
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
finally {
tryClose ( statement ) ;
tryClose ( connection ) ;
}
}
2013-07-01 05:23:34 +02:00
}