2012-04-27 11:47:11 +02:00
package com.gmail.nossr50.util ;
import java.sql.Connection ;
import java.sql.DriverManager ;
2012-06-05 16:13:10 +02:00
import java.sql.PreparedStatement ;
2012-04-27 11:47:11 +02:00
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.util.ArrayList ;
2012-06-05 16:13:10 +02:00
import java.util.HashMap ;
2013-01-16 01:03:13 +01:00
import java.util.Map ;
2012-04-27 11:47:11 +02:00
import java.util.Properties ;
2012-06-05 16:13:10 +02:00
2013-01-14 06:47:47 +01:00
import org.bukkit.Bukkit ;
import org.bukkit.entity.Player ;
2012-06-07 00:02:22 +02:00
import com.gmail.nossr50.mcMMO ;
2012-04-27 11:47:11 +02:00
import com.gmail.nossr50.config.Config ;
import com.gmail.nossr50.datatypes.DatabaseUpdate ;
2013-01-14 06:47:47 +01:00
import com.gmail.nossr50.datatypes.McMMOPlayer ;
2013-01-16 01:03:13 +01:00
import com.gmail.nossr50.datatypes.SkillType ;
2013-01-14 06:47:47 +01:00
import com.gmail.nossr50.datatypes.SpoutHud ;
2012-04-27 11:47:11 +02:00
import com.gmail.nossr50.runnables.SQLReconnect ;
2013-01-14 06:47:47 +01:00
import com.gmail.nossr50.spout.SpoutStuff ;
2012-04-27 11:47:11 +02:00
public class Database {
2012-07-10 18:04:18 +02:00
private static Config configInstance = Config . getInstance ( ) ;
2012-12-28 11:40:15 +01:00
private static String connectionString ;
2012-07-10 18:04:18 +02:00
private static String tablePrefix = configInstance . getMySQLTablePrefix ( ) ;
private static Connection connection = null ;
2012-06-07 00:02:22 +02:00
private static mcMMO plugin = null ;
2012-10-22 14:45:16 +02:00
// Scale waiting time by this much per failed attempt
2013-01-11 03:41:35 +01:00
private static final double SCALING_FACTOR = 40 ;
2012-12-24 22:56:25 +01:00
2012-10-22 14:45:16 +02:00
// Minimum wait in nanoseconds (default 500ms)
2012-12-28 11:40:15 +01:00
private static final long MIN_WAIT = 500L * 1000000L ;
2012-10-22 14:45:16 +02:00
// Maximum time to wait between reconnects (default 5 minutes)
2012-12-28 11:40:15 +01:00
private static final long MAX_WAIT = 5L * 60L * 1000L * 1000000L ;
2012-10-22 14:45:16 +02:00
// How long to wait when checking if connection is valid (default 3 seconds)
private static final int VALID_TIMEOUT = 3 ;
// When next to try connecting to Database in nanoseconds
private static long nextReconnectTimestamp = 0L ;
2012-12-24 22:56:25 +01:00
2012-10-22 14:45:16 +02:00
// How many connection attemtps have failed
private static int reconnectAttempt = 0 ;
2012-04-27 11:47:11 +02:00
2012-06-07 00:02:22 +02:00
public Database ( mcMMO instance ) {
2012-04-27 11:47:11 +02:00
plugin = instance ;
2012-10-22 14:45:16 +02:00
checkConnected ( ) ; //Connect to MySQL
2012-04-27 11:47:11 +02:00
}
/ * *
* Attempt to connect to the mySQL database .
* /
public static void connect ( ) {
2013-01-16 01:03:13 +01:00
connectionString = " jdbc:mysql:// " + configInstance . getMySQLServerName ( ) + " : " + configInstance . getMySQLServerPort ( ) + " / " + configInstance . getMySQLDatabaseName ( ) ;
try {
mcMMO . p . getLogger ( ) . info ( " Attempting connection to MySQL... " ) ;
// Force driver to load if not yet loaded
Class . forName ( " com.mysql.jdbc.Driver " ) ;
Properties connectionProperties = new Properties ( ) ;
connectionProperties . put ( " user " , configInstance . getMySQLUserName ( ) ) ;
connectionProperties . put ( " password " , configInstance . getMySQLUserPassword ( ) ) ;
connectionProperties . put ( " autoReconnect " , " false " ) ;
connectionProperties . put ( " maxReconnects " , " 0 " ) ;
connection = DriverManager . getConnection ( connectionString , connectionProperties ) ;
mcMMO . p . getLogger ( ) . info ( " Connection to MySQL was a success! " ) ;
} catch ( SQLException ex ) {
connection = null ;
if ( reconnectAttempt = = 0 | | reconnectAttempt > = 11 ) mcMMO . p . getLogger ( ) . info ( " Connection to MySQL failed! " ) ;
} catch ( ClassNotFoundException ex ) {
connection = null ;
if ( reconnectAttempt = = 0 | | reconnectAttempt > = 11 ) mcMMO . p . getLogger ( ) . info ( " MySQL database driver not found! " ) ;
}
2012-04-27 11:47:11 +02:00
}
/ * *
* Attempt to create the database structure .
* /
public void createStructure ( ) {
2013-01-11 21:26:42 +01:00
write ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " users` ( "
+ " `id` int(10) unsigned NOT NULL AUTO_INCREMENT, "
2012-04-27 11:47:11 +02:00
+ " `user` varchar(40) NOT NULL, "
+ " `lastlogin` int(32) unsigned NOT NULL, "
+ " PRIMARY KEY (`id`), "
+ " UNIQUE KEY `user` (`user`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1; " ) ;
2013-01-11 21:26:42 +01:00
write ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " huds` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
+ " `hudtype` varchar(50) NOT NULL DEFAULT 'STANDARD', "
2013-01-12 07:43:40 +01:00
+ " PRIMARY KEY (`user_id`), "
2013-01-12 07:23:16 +01:00
+ " FOREIGN KEY (`user_id`) REFERENCES ` " + tablePrefix + " users` (`id`) "
2013-01-11 21:26:42 +01:00
+ " ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1; " ) ;
write ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " cooldowns` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
2012-04-27 11:47:11 +02:00
+ " `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', "
2013-01-12 07:43:40 +01:00
+ " PRIMARY KEY (`user_id`), "
2013-01-12 07:23:16 +01:00
+ " FOREIGN KEY (`user_id`) REFERENCES ` " + tablePrefix + " users` (`id`) "
2013-01-11 21:26:42 +01:00
+ " ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1; " ) ;
write ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " skills` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
2012-04-27 11:47:11 +02:00
+ " `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', "
2013-01-12 07:43:40 +01:00
+ " PRIMARY KEY (`user_id`), "
2013-01-12 07:23:16 +01:00
+ " FOREIGN KEY (`user_id`) REFERENCES ` " + tablePrefix + " users` (`id`) "
2013-01-11 21:26:42 +01:00
+ " ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1; " ) ;
write ( " CREATE TABLE IF NOT EXISTS ` " + tablePrefix + " experience` ( "
+ " `user_id` int(10) unsigned NOT NULL, "
2012-04-27 11:47:11 +02:00
+ " `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', "
2013-01-12 07:43:40 +01:00
+ " PRIMARY KEY (`user_id`), "
2013-01-12 07:23:16 +01:00
+ " FOREIGN KEY (`user_id`) REFERENCES ` " + tablePrefix + " users` (`id`) "
2013-01-11 21:26:42 +01:00
+ " ON DELETE CASCADE) ENGINE=MyISAM DEFAULT CHARSET=latin1; " ) ;
2012-04-27 11:47:11 +02:00
checkDatabaseStructure ( DatabaseUpdate . FISHING ) ;
checkDatabaseStructure ( DatabaseUpdate . BLAST_MINING ) ;
2013-01-12 06:34:52 +01:00
checkDatabaseStructure ( DatabaseUpdate . CASCADE_DELETE ) ;
2012-04-27 11:47:11 +02:00
}
/ * *
* Check database structure for missing values .
*
2013-01-12 07:23:16 +01:00
* @param update Type of data to check updates for
2012-04-27 11:47:11 +02:00
* /
public void checkDatabaseStructure ( DatabaseUpdate update ) {
String sql = null ;
2012-10-22 15:03:31 +02:00
ResultSet resultSet = null ;
2012-07-10 18:04:18 +02:00
HashMap < Integer , ArrayList < String > > rows = new HashMap < Integer , ArrayList < String > > ( ) ;
2012-04-27 11:47:11 +02:00
switch ( update ) {
case BLAST_MINING :
2012-07-10 18:04:18 +02:00
sql = " SELECT * FROM ` " + tablePrefix + " cooldowns` ORDER BY ` " + tablePrefix + " cooldowns`.`blast_mining` ASC LIMIT 0 , 30 " ;
2012-04-27 11:47:11 +02:00
break ;
2012-07-10 18:04:18 +02:00
2013-01-12 07:23:16 +01:00
case CASCADE_DELETE :
write ( " ALTER TABLE ` " + tablePrefix + " huds` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE; " ) ;
write ( " ALTER TABLE ` " + tablePrefix + " experience` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE; " ) ;
write ( " ALTER TABLE ` " + tablePrefix + " cooldowns` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE; " ) ;
write ( " ALTER TABLE ` " + tablePrefix + " skills` ADD FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE; " ) ;
2012-04-27 11:47:11 +02:00
case FISHING :
2012-07-10 18:04:18 +02:00
sql = " SELECT * FROM ` " + tablePrefix + " experience` ORDER BY ` " + tablePrefix + " experience`.`fishing` ASC LIMIT 0 , 30 " ;
2012-04-27 11:47:11 +02:00
break ;
2012-07-10 18:04:18 +02:00
2012-04-27 11:47:11 +02:00
default :
break ;
}
2012-10-22 15:03:31 +02:00
PreparedStatement statement = null ;
2012-04-27 11:47:11 +02:00
try {
2013-01-10 05:03:17 +01:00
if ( ! checkConnected ( ) ) return ;
2012-10-22 15:03:31 +02:00
statement = connection . prepareStatement ( sql ) ;
2012-07-10 18:04:18 +02:00
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) ) {
ArrayList < String > column = new ArrayList < String > ( ) ;
for ( int i = 1 ; i < = resultSet . getMetaData ( ) . getColumnCount ( ) ; i + + ) {
column . add ( resultSet . getString ( i ) ) ;
2012-04-27 11:47:11 +02:00
}
2012-07-10 18:04:18 +02:00
rows . put ( resultSet . getRow ( ) , column ) ;
2012-04-27 11:47:11 +02:00
}
}
catch ( SQLException ex ) {
2012-07-10 18:04:18 +02:00
switch ( update ) {
case BLAST_MINING :
2013-01-16 01:03:13 +01:00
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for Blast Mining... " ) ;
2012-04-27 11:47:11 +02:00
write ( " ALTER TABLE ` " + tablePrefix + " cooldowns` ADD `blast_mining` int(32) NOT NULL DEFAULT '0' ; " ) ;
2012-07-10 18:04:18 +02:00
break ;
case FISHING :
2013-01-16 01:03:13 +01:00
mcMMO . p . getLogger ( ) . info ( " Updating mcMMO MySQL tables for Fishing... " ) ;
2012-04-27 11:47:11 +02:00
write ( " ALTER TABLE ` " + tablePrefix + " skills` ADD `fishing` int(10) NOT NULL DEFAULT '0' ; " ) ;
write ( " ALTER TABLE ` " + tablePrefix + " experience` ADD `fishing` int(10) NOT NULL DEFAULT '0' ; " ) ;
2012-07-10 18:04:18 +02:00
break ;
default :
break ;
2012-04-27 11:47:11 +02:00
}
2012-10-22 15:03:31 +02:00
} finally {
2012-12-24 22:56:25 +01:00
if ( resultSet ! = null ) {
2013-01-12 06:34:52 +01:00
try {
2012-12-24 22:56:25 +01:00
resultSet . close ( ) ;
} catch ( SQLException e ) {
// Ignore the error, we're leaving
}
}
if ( statement ! = null ) {
try {
statement . close ( ) ;
} catch ( SQLException e ) {
// Ignore the error, we're leaving
}
}
2012-04-27 11:47:11 +02:00
}
}
/ * *
* Attempt to write the SQL query .
*
* @param sql Query to write .
* @return true if the query was successfully written , false otherwise .
* /
public boolean write ( String sql ) {
2012-10-22 14:45:16 +02:00
if ( checkConnected ( ) ) {
2012-12-24 22:56:25 +01:00
PreparedStatement statement = null ;
2012-04-27 11:47:11 +02:00
try {
2012-10-22 15:03:31 +02:00
statement = connection . prepareStatement ( sql ) ;
2012-07-10 18:04:18 +02:00
statement . executeUpdate ( ) ;
2012-04-27 11:47:11 +02:00
return true ;
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
return false ;
2012-10-22 15:03:31 +02:00
} finally {
2012-12-24 22:56:25 +01:00
if ( statement ! = null ) {
2012-10-22 15:03:31 +02:00
try {
2012-12-24 22:56:25 +01:00
statement . close ( ) ;
} catch ( SQLException e ) {
printErrors ( e ) ;
return false ;
}
}
2012-04-27 11:47:11 +02:00
}
}
2012-07-10 18:04:18 +02:00
2012-04-27 11:47:11 +02:00
return false ;
}
/ * *
* Get the Integer . Only return first row / first field .
*
* @param sql SQL query to execute
* @return the value in the first row / first field
* /
2012-07-10 18:04:18 +02:00
public int getInt ( String sql ) {
ResultSet resultSet ;
int result = 0 ;
2012-04-27 11:47:11 +02:00
2012-10-22 14:45:16 +02:00
if ( checkConnected ( ) ) {
2012-04-27 11:47:11 +02:00
try {
2012-07-10 18:04:18 +02:00
PreparedStatement statement = connection . prepareStatement ( sql ) ;
resultSet = statement . executeQuery ( ) ;
if ( resultSet . next ( ) ) {
result = resultSet . getInt ( 1 ) ;
2012-06-28 05:35:56 +02:00
}
else {
result = 0 ;
2012-04-27 11:47:11 +02:00
}
2012-07-10 18:04:18 +02:00
statement . close ( ) ;
2012-04-27 11:47:11 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
}
2012-07-10 18:04:18 +02:00
2012-04-27 11:47:11 +02:00
return result ;
}
2012-06-05 15:57:10 +02:00
2012-04-27 11:47:11 +02:00
/ * *
2012-10-22 14:45:16 +02:00
* Check connection status and re - establish if dead or stale .
*
2012-12-24 22:56:25 +01:00
* If the very first immediate attempt fails , further attempts
* will be made in progressively larger intervals up to MAX_WAIT
* intervals .
2012-10-22 14:45:16 +02:00
*
2012-12-24 22:56:25 +01:00
* This allows for MySQL to time out idle connections as needed by
* server operator , without affecting McMMO , while still providing
* protection against a database outage taking down Bukkit ' s tick
2012-10-22 14:45:16 +02:00
* processing loop due to attemping a database connection each
* time McMMO needs the database .
2012-06-05 15:57:10 +02:00
*
2012-04-27 11:47:11 +02:00
* @return the boolean value for whether or not we are connected
* /
2012-10-22 14:45:16 +02:00
public static boolean checkConnected ( ) {
2012-12-24 22:56:25 +01:00
boolean isClosed = true ;
boolean isValid = false ;
boolean exists = ( connection ! = null ) ;
// If we're waiting for server to recover then leave early
if ( nextReconnectTimestamp > 0 & & nextReconnectTimestamp > System . nanoTime ( ) ) {
return false ;
}
if ( exists ) {
2012-10-22 14:45:16 +02:00
try {
2012-12-24 22:56:25 +01:00
isClosed = connection . isClosed ( ) ;
} catch ( SQLException e ) {
isClosed = true ;
e . printStackTrace ( ) ;
printErrors ( e ) ;
}
2012-10-22 14:45:16 +02:00
if ( ! isClosed ) {
try {
2012-12-24 22:56:25 +01:00
isValid = connection . isValid ( VALID_TIMEOUT ) ;
} catch ( SQLException e ) {
// Don't print stack trace because it's valid to lose idle connections
// to the server and have to restart them.
isValid = false ;
}
}
}
// Leave if all ok
if ( exists & & ! isClosed & & isValid ) {
// Housekeeping
nextReconnectTimestamp = 0 ;
reconnectAttempt = 0 ;
return true ;
}
// Cleanup after ourselves for GC and MySQL's sake
if ( exists & & ! isClosed ) {
try {
connection . close ( ) ;
} catch ( SQLException ex ) {
// This is a housekeeping exercise, ignore errors
2012-10-22 14:45:16 +02:00
}
2012-12-24 22:56:25 +01:00
}
// Try to connect again
connect ( ) ;
// Leave if connection is good
try {
if ( connection ! = null & & ! connection . isClosed ( ) ) {
// Schedule a database save if we really had an outage
if ( reconnectAttempt > 1 ) {
plugin . getServer ( ) . getScheduler ( ) . scheduleSyncDelayedTask ( plugin , new SQLReconnect ( plugin ) , 5 ) ;
}
nextReconnectTimestamp = 0 ;
reconnectAttempt = 0 ;
return true ;
}
} catch ( SQLException e ) {
// Failed to check isClosed, so presume connection is bad and attempt later
e . printStackTrace ( ) ;
printErrors ( e ) ;
}
reconnectAttempt + + ;
nextReconnectTimestamp = ( long ) ( System . nanoTime ( ) + Math . min ( MAX_WAIT , ( reconnectAttempt * SCALING_FACTOR * MIN_WAIT ) ) ) ;
return false ;
2012-04-27 11:47:11 +02:00
}
/ * *
* Read SQL query .
*
* @param sql SQL query to read
* @return the rows in this SQL query
* /
public HashMap < Integer , ArrayList < String > > read ( String sql ) {
2012-07-10 18:04:18 +02:00
ResultSet resultSet ;
HashMap < Integer , ArrayList < String > > rows = new HashMap < Integer , ArrayList < String > > ( ) ;
2012-04-27 11:47:11 +02:00
2012-10-22 14:45:16 +02:00
if ( checkConnected ( ) ) {
2012-04-27 11:47:11 +02:00
try {
2012-07-10 18:04:18 +02:00
PreparedStatement statement = connection . prepareStatement ( sql ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) ) {
ArrayList < String > column = new ArrayList < String > ( ) ;
for ( int i = 1 ; i < = resultSet . getMetaData ( ) . getColumnCount ( ) ; i + + ) {
column . add ( resultSet . getString ( i ) ) ;
2012-04-27 11:47:11 +02:00
}
2012-07-10 18:04:18 +02:00
rows . put ( resultSet . getRow ( ) , column ) ;
2012-04-27 11:47:11 +02:00
}
2012-07-10 18:04:18 +02:00
statement . close ( ) ;
2012-04-27 11:47:11 +02:00
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
}
2012-07-10 18:04:18 +02:00
return rows ;
2012-04-27 11:47:11 +02:00
}
2013-01-16 01:03:13 +01:00
public Map < String , Integer > readSQLRank ( String playerName ) {
ResultSet resultSet ;
Map < String , Integer > skills = new HashMap < String , Integer > ( ) ;
if ( checkConnected ( ) ) {
try {
String sql = " SELECT "
2013-01-16 03:20:33 +01:00
+ " (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'ALL' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.fishing desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'FISHING' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.taming desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'TAMING' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.woodcutting desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'WOODCUTTING' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.repair desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'REPAIR' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.unarmed desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'UNARMED' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.herbalism desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'HERBALISM' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.excavation desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'EXCAVATION' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.archery desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'ARCHERY' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.swords desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'SWORDS' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.axes desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'AXES' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.acrobatics desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'ACROBATICS' "
+ " , (SELECT rank FROM (SELECT @rownum:=@rownum+1 rank, p.user AS user FROM (SELECT @rownum:=0) AS rank, ((SELECT u.user AS user FROM " + tablePrefix + " users u, " + tablePrefix + " skills s WHERE u.id = s.user_id ORDER BY s.mining desc ) AS p) AS d) WHERE user = ' " + playerName + " ') AS 'MINING' " ;
2013-01-16 01:03:13 +01:00
PreparedStatement statement = connection . prepareStatement ( sql ) ;
resultSet = statement . executeQuery ( ) ;
while ( resultSet . next ( ) ) {
for ( SkillType skillType : SkillType . values ( ) ) {
skills . put ( skillType . name ( ) , resultSet . getInt ( skillType . name ( ) ) ) ;
}
}
statement . close ( ) ;
}
catch ( SQLException ex ) {
printErrors ( ex ) ;
}
}
return skills ;
}
2012-04-27 11:47:11 +02:00
2013-01-14 06:47:47 +01:00
public void purgePowerlessSQL ( ) {
plugin . getLogger ( ) . info ( " Purging powerless users... " ) ;
HashMap < Integer , ArrayList < String > > usernames = read ( " SELECT u.user FROM " + tablePrefix + " skills AS s, " + tablePrefix + " users AS u WHERE s.user_id = u.id AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0 " ) ;
write ( " DELETE FROM " + tablePrefix + " users WHERE " + tablePrefix + " users.id IN (SELECT * FROM (SELECT u.id FROM " + tablePrefix + " skills AS s, " + tablePrefix + " users AS u WHERE s.user_id = u.id AND (s.taming+s.mining+s.woodcutting+s.repair+s.unarmed+s.herbalism+s.excavation+s.archery+s.swords+s.axes+s.acrobatics+s.fishing) = 0) AS p) " ) ;
int purgedUsers = 0 ;
for ( int i = 1 ; i < = usernames . size ( ) ; i + + ) {
String playerName = usernames . get ( i ) . get ( 0 ) ;
if ( playerName = = null | | Bukkit . getOfflinePlayer ( playerName ) . isOnline ( ) ) {
continue ;
}
profileCleanup ( playerName ) ;
purgedUsers + + ;
}
plugin . getLogger ( ) . info ( " Purged " + purgedUsers + " users from the database. " ) ;
}
public void purgeOldSQL ( ) {
plugin . getLogger ( ) . info ( " Purging old users... " ) ;
long currentTime = System . currentTimeMillis ( ) ;
long purgeTime = 2630000000L * Config . getInstance ( ) . getOldUsersCutoff ( ) ;
HashMap < Integer , ArrayList < String > > usernames = read ( " SELECT user FROM " + tablePrefix + " users WHERE (( " + currentTime + " - lastlogin*1000) > " + purgeTime + " ) " ) ;
write ( " DELETE FROM " + tablePrefix + " users WHERE " + tablePrefix + " users.id IN (SELECT * FROM (SELECT id FROM " + tablePrefix + " users WHERE (( " + currentTime + " - lastlogin*1000) > " + purgeTime + " )) AS p) " ) ;
int purgedUsers = 0 ;
for ( int i = 1 ; i < = usernames . size ( ) ; i + + ) {
String playerName = usernames . get ( i ) . get ( 0 ) ;
if ( playerName = = null ) {
continue ;
}
profileCleanup ( playerName ) ;
purgedUsers + + ;
}
plugin . getLogger ( ) . info ( " Purged " + purgedUsers + " users from the database. " ) ;
}
2012-04-27 11:47:11 +02:00
private static void printErrors ( SQLException ex ) {
System . out . println ( " SQLException: " + ex . getMessage ( ) ) ;
System . out . println ( " SQLState: " + ex . getSQLState ( ) ) ;
System . out . println ( " VendorError: " + ex . getErrorCode ( ) ) ;
}
2013-01-14 06:47:47 +01:00
2013-01-15 16:51:06 +01:00
public static void profileCleanup ( String playerName ) {
2013-01-14 06:47:47 +01:00
McMMOPlayer mcmmoPlayer = Users . getPlayer ( playerName ) ;
if ( mcmmoPlayer ! = null ) {
Player player = mcmmoPlayer . getPlayer ( ) ;
SpoutHud spoutHud = mcmmoPlayer . getProfile ( ) . getSpoutHud ( ) ;
if ( spoutHud ! = null ) {
spoutHud . removeWidgets ( ) ;
}
Users . remove ( playerName ) ;
if ( player . isOnline ( ) ) {
Users . addUser ( player ) ;
if ( mcMMO . spoutEnabled ) {
SpoutStuff . reloadSpoutPlayer ( player ) ;
}
}
}
}
2013-01-16 01:03:13 +01:00
}