2013-02-05 18:56:31 +01:00
package com.gmail.nossr50.database ;
2012-04-27 11:47:11 +02:00
import java.io.BufferedReader ;
import java.io.FileReader ;
2013-02-05 21:29:57 +01:00
import java.io.FileWriter ;
import java.io.IOException ;
2012-04-27 11:47:11 +02:00
import java.util.ArrayList ;
2013-01-01 04:40:33 +01:00
import java.util.Collections ;
import java.util.Comparator ;
2013-01-15 23:49:20 +01:00
import java.util.HashMap ;
2013-01-01 04:40:33 +01:00
import java.util.List ;
2012-04-27 11:47:11 +02:00
2013-02-05 21:29:57 +01:00
import org.bukkit.Bukkit ;
2012-06-07 00:02:22 +02:00
import com.gmail.nossr50.mcMMO ;
2013-02-05 21:29:57 +01:00
import com.gmail.nossr50.config.Config ;
import com.gmail.nossr50.datatypes.McMMOPlayer ;
2013-01-30 17:53:51 +01:00
import com.gmail.nossr50.skills.utilities.SkillType ;
2013-02-05 18:56:31 +01:00
import com.gmail.nossr50.util.Misc ;
2013-02-05 21:29:57 +01:00
import com.gmail.nossr50.util.Users ;
2012-04-27 11:47:11 +02:00
2013-01-26 23:01:55 +01:00
public final class Leaderboard {
2013-01-15 23:49:20 +01:00
private static HashMap < SkillType , List < PlayerStat > > playerStatHash = new HashMap < SkillType , List < PlayerStat > > ( ) ;
2013-02-04 16:33:34 +01:00
private static List < PlayerStat > powerLevels = new ArrayList < PlayerStat > ( ) ;
2013-01-16 21:02:41 +01:00
private static long lastUpdate = 0 ;
2013-01-21 23:22:54 +01:00
2013-01-26 23:01:55 +01:00
private Leaderboard ( ) { }
2012-04-27 11:47:11 +02:00
/ * *
2013-01-15 23:49:20 +01:00
* Update the leader boards .
2012-04-27 11:47:11 +02:00
* /
2013-01-15 23:49:20 +01:00
public static void updateLeaderboards ( ) {
2013-01-21 23:15:53 +01:00
if ( System . currentTimeMillis ( ) < lastUpdate + 600000 ) {
return ; //Only update FFS leaderboards every 10 minutes.. this puts a lot of strain on the server (depending on the size of the database) and should not be done frequently
}
2013-01-21 23:22:54 +01:00
2013-01-21 23:15:53 +01:00
lastUpdate = System . currentTimeMillis ( ) ; //Log when the last update was run
2013-01-21 23:22:54 +01:00
2013-01-15 23:49:20 +01:00
//Initialize lists
2013-02-04 16:33:34 +01:00
List < PlayerStat > mining , woodcutting , herbalism , excavation , acrobatics , repair , swords , axes , archery , unarmed , taming , fishing ;
2013-01-15 23:49:20 +01:00
mining = new ArrayList < PlayerStat > ( ) ;
woodcutting = new ArrayList < PlayerStat > ( ) ;
herbalism = new ArrayList < PlayerStat > ( ) ;
excavation = new ArrayList < PlayerStat > ( ) ;
acrobatics = new ArrayList < PlayerStat > ( ) ;
repair = new ArrayList < PlayerStat > ( ) ;
swords = new ArrayList < PlayerStat > ( ) ;
axes = new ArrayList < PlayerStat > ( ) ;
archery = new ArrayList < PlayerStat > ( ) ;
unarmed = new ArrayList < PlayerStat > ( ) ;
taming = new ArrayList < PlayerStat > ( ) ;
fishing = new ArrayList < PlayerStat > ( ) ;
//Read from the FlatFile database and fill our arrays with information
2012-04-27 11:47:11 +02:00
try {
2013-01-26 23:01:55 +01:00
FileReader file = new FileReader ( mcMMO . getUsersFilePath ( ) ) ;
2012-04-27 11:47:11 +02:00
BufferedReader in = new BufferedReader ( file ) ;
String line = " " ;
ArrayList < String > players = new ArrayList < String > ( ) ;
while ( ( line = in . readLine ( ) ) ! = null ) {
String [ ] character = line . split ( " : " ) ;
2013-01-14 22:09:11 +01:00
2012-04-27 11:47:11 +02:00
String p = character [ 0 ] ;
int powerLevel = 0 ;
2013-01-15 23:49:20 +01:00
//Prevent the same player from being added multiple times (I'd like to note that this shouldn't happen...)
2012-04-27 11:47:11 +02:00
if ( players . contains ( p ) ) {
continue ;
}
2013-01-10 04:43:21 +01:00
players . add ( p ) ;
2012-04-27 11:47:11 +02:00
if ( character . length > 1 & & Misc . isInt ( character [ 1 ] ) ) {
2013-01-15 23:49:20 +01:00
mining . add ( new PlayerStat ( p , Integer . valueOf ( character [ 1 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 1 ] ) ;
}
if ( character . length > 5 & & Misc . isInt ( character [ 5 ] ) ) {
2013-01-15 23:49:20 +01:00
woodcutting . add ( new PlayerStat ( p , Integer . valueOf ( character [ 5 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 5 ] ) ;
}
if ( character . length > 7 & & Misc . isInt ( character [ 7 ] ) ) {
2013-01-15 23:49:20 +01:00
repair . add ( new PlayerStat ( p , Integer . valueOf ( character [ 7 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 7 ] ) ;
}
if ( character . length > 8 & & Misc . isInt ( character [ 8 ] ) ) {
2013-01-15 23:49:20 +01:00
unarmed . add ( new PlayerStat ( p , Integer . valueOf ( character [ 8 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 8 ] ) ;
}
if ( character . length > 9 & & Misc . isInt ( character [ 9 ] ) ) {
2013-01-15 23:49:20 +01:00
herbalism . add ( new PlayerStat ( p , Integer . valueOf ( character [ 9 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 9 ] ) ;
}
if ( character . length > 10 & & Misc . isInt ( character [ 10 ] ) ) {
2013-01-15 23:49:20 +01:00
excavation . add ( new PlayerStat ( p , Integer . valueOf ( character [ 10 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 10 ] ) ;
}
if ( character . length > 11 & & Misc . isInt ( character [ 11 ] ) ) {
2013-01-15 23:49:20 +01:00
archery . add ( new PlayerStat ( p , Integer . valueOf ( character [ 11 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 11 ] ) ;
}
if ( character . length > 12 & & Misc . isInt ( character [ 12 ] ) ) {
2013-01-15 23:49:20 +01:00
swords . add ( new PlayerStat ( p , Integer . valueOf ( character [ 12 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 12 ] ) ;
}
if ( character . length > 13 & & Misc . isInt ( character [ 13 ] ) ) {
2013-01-15 23:49:20 +01:00
axes . add ( new PlayerStat ( p , Integer . valueOf ( character [ 13 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 13 ] ) ;
}
if ( character . length > 14 & & Misc . isInt ( character [ 14 ] ) ) {
2013-01-15 23:49:20 +01:00
acrobatics . add ( new PlayerStat ( p , Integer . valueOf ( character [ 14 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 14 ] ) ;
}
if ( character . length > 24 & & Misc . isInt ( character [ 24 ] ) ) {
2013-01-15 23:49:20 +01:00
taming . add ( new PlayerStat ( p , Integer . valueOf ( character [ 24 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 24 ] ) ;
}
if ( character . length > 34 & & Misc . isInt ( character [ 34 ] ) ) {
2013-01-15 23:49:20 +01:00
fishing . add ( new PlayerStat ( p , Integer . valueOf ( character [ 34 ] ) ) ) ;
2012-04-27 11:47:11 +02:00
powerLevel + = Integer . valueOf ( character [ 34 ] ) ;
}
2013-02-04 16:33:34 +01:00
powerLevels . add ( new PlayerStat ( p , powerLevel ) ) ;
2012-04-27 11:47:11 +02:00
}
in . close ( ) ;
}
catch ( Exception e ) {
2013-01-26 23:01:55 +01:00
mcMMO . p . getLogger ( ) . severe ( ( " Exception while reading " + mcMMO . getUsersFilePath ( ) + " (Are you sure you formatted it correctly?) " + e . toString ( ) ) ) ;
2012-04-27 11:47:11 +02:00
}
2013-01-01 04:40:33 +01:00
SkillComparator c = new SkillComparator ( ) ;
2013-01-15 23:49:20 +01:00
Collections . sort ( mining , c ) ;
Collections . sort ( woodcutting , c ) ;
Collections . sort ( repair , c ) ;
Collections . sort ( unarmed , c ) ;
Collections . sort ( herbalism , c ) ;
Collections . sort ( excavation , c ) ;
Collections . sort ( archery , c ) ;
Collections . sort ( swords , c ) ;
Collections . sort ( axes , c ) ;
Collections . sort ( acrobatics , c ) ;
Collections . sort ( taming , c ) ;
Collections . sort ( fishing , c ) ;
2013-02-04 16:33:34 +01:00
Collections . sort ( powerLevels , c ) ;
2013-01-21 23:22:54 +01:00
2013-01-15 23:49:20 +01:00
playerStatHash . put ( SkillType . MINING , mining ) ;
playerStatHash . put ( SkillType . WOODCUTTING , woodcutting ) ;
playerStatHash . put ( SkillType . REPAIR , repair ) ;
playerStatHash . put ( SkillType . UNARMED , unarmed ) ;
playerStatHash . put ( SkillType . HERBALISM , herbalism ) ;
playerStatHash . put ( SkillType . EXCAVATION , excavation ) ;
playerStatHash . put ( SkillType . ARCHERY , archery ) ;
playerStatHash . put ( SkillType . SWORDS , swords ) ;
playerStatHash . put ( SkillType . AXES , axes ) ;
playerStatHash . put ( SkillType . ACROBATICS , acrobatics ) ;
playerStatHash . put ( SkillType . TAMING , taming ) ;
playerStatHash . put ( SkillType . FISHING , fishing ) ;
2012-04-27 11:47:11 +02:00
}
/ * *
* Retrieve leaderboard info .
*
2013-01-31 01:42:40 +01:00
* @param skillType Skill to retrieve info on .
* @param pageNumber Which page in the leaderboards to retrieve
2012-04-27 11:47:11 +02:00
* @return the requested leaderboard information
* /
2013-02-04 16:33:34 +01:00
public static String [ ] retrieveInfo ( String skillType , int pageNumber ) {
2013-01-21 23:15:53 +01:00
String [ ] info = new String [ 10 ] ;
2013-02-04 16:33:34 +01:00
List < PlayerStat > statsList ;
2013-01-15 23:49:20 +01:00
2013-02-04 16:33:34 +01:00
if ( skillType . equalsIgnoreCase ( " all " ) ) {
statsList = powerLevels ;
}
else {
statsList = playerStatHash . get ( SkillType . getSkill ( skillType ) ) ;
}
int destination ;
// How many lines to skip through
if ( pageNumber = = 1 ) {
destination = 0 ;
}
else {
destination = ( pageNumber * 10 ) - 9 ;
}
2013-01-21 23:22:54 +01:00
2013-02-04 16:33:34 +01:00
int currentPos = 0 ;
2013-01-21 23:22:54 +01:00
2013-02-04 16:33:34 +01:00
for ( PlayerStat ps : statsList ) {
if ( currentPos = = 10 ) {
break ;
2012-04-27 11:47:11 +02:00
}
2013-02-04 16:33:34 +01:00
if ( destination > 1 ) {
destination - - ;
continue ;
2012-04-27 11:47:11 +02:00
}
2013-01-21 23:22:54 +01:00
2013-02-04 16:33:34 +01:00
info [ currentPos ] = ps . name + " : " + ps . statVal ;
currentPos + + ;
}
2013-01-21 23:22:54 +01:00
2013-02-04 16:33:34 +01:00
return info ;
}
public static int [ ] getPlayerRank ( String playerName ) {
int currentPos = 1 ;
if ( powerLevels ! = null ) {
for ( PlayerStat stat : powerLevels ) {
if ( stat . name . equalsIgnoreCase ( playerName ) ) {
return new int [ ] { currentPos , stat . statVal } ;
2013-01-21 23:15:53 +01:00
}
2013-01-21 23:22:54 +01:00
2013-01-21 23:15:53 +01:00
currentPos + + ;
2013-02-04 16:33:34 +01:00
continue ;
2013-01-21 23:15:53 +01:00
}
2013-02-04 16:33:34 +01:00
return new int [ ] { 0 , 0 } ;
2012-04-27 11:47:11 +02:00
}
2013-01-21 23:22:54 +01:00
2013-02-04 16:33:34 +01:00
return new int [ ] { 0 , 0 } ;
2012-04-27 11:47:11 +02:00
}
2013-01-21 23:22:54 +01:00
2013-01-16 20:58:14 +01:00
public static int [ ] getPlayerRank ( String playerName , SkillType skillType ) {
2013-01-21 23:15:53 +01:00
int currentPos = 1 ;
2013-01-15 23:49:20 +01:00
List < PlayerStat > statsList = playerStatHash . get ( skillType ) ;
2013-01-21 23:22:54 +01:00
2013-01-21 23:15:53 +01:00
if ( statsList ! = null ) {
for ( PlayerStat stat : statsList ) {
if ( stat . name . equalsIgnoreCase ( playerName ) ) {
return new int [ ] { currentPos , stat . statVal } ;
}
2013-01-21 23:22:54 +01:00
2013-01-21 23:15:53 +01:00
currentPos + + ;
continue ;
}
2013-01-22 01:07:17 +01:00
return new int [ ] { 0 , 0 } ;
2012-04-27 11:47:11 +02:00
}
2013-01-21 23:15:53 +01:00
2013-01-22 01:07:17 +01:00
return new int [ ] { 0 , 0 } ;
2012-04-27 11:47:11 +02:00
}
2013-01-21 23:22:54 +01:00
2013-01-01 04:40:33 +01:00
private static class SkillComparator implements Comparator < PlayerStat > {
@Override
public int compare ( PlayerStat o1 , PlayerStat o2 ) {
return ( o2 . statVal - o1 . statVal ) ;
}
}
2013-02-05 21:29:57 +01:00
public static boolean removeFlatFileUser ( String playerName ) {
boolean worked = false ;
BufferedReader in = null ;
FileWriter out = null ;
String usersFilePath = mcMMO . getUsersFilePath ( ) ;
try {
FileReader file = new FileReader ( usersFilePath ) ;
in = new BufferedReader ( file ) ;
StringBuilder writer = new StringBuilder ( ) ;
String line = " " ;
while ( ( line = in . readLine ( ) ) ! = null ) {
/* Write out the same file but when we get to the player we want to remove, we skip his line. */
if ( ! line . split ( " : " ) [ 0 ] . equalsIgnoreCase ( playerName ) ) {
writer . append ( line ) . append ( " \ r \ n " ) ;
}
else {
System . out . println ( " User found, removing... " ) ;
worked = true ;
continue ; //Skip the player
}
}
out = new FileWriter ( usersFilePath ) ; //Write out the new file
out . write ( writer . toString ( ) ) ;
}
catch ( Exception e ) {
mcMMO . p . getLogger ( ) . severe ( " Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?) " + e . toString ( ) ) ;
}
finally {
if ( in ! = null ) {
try {
in . close ( ) ;
}
catch ( IOException ex ) {
ex . printStackTrace ( ) ;
}
}
if ( out ! = null ) {
try {
out . close ( ) ;
}
catch ( IOException ex ) {
ex . printStackTrace ( ) ;
}
}
}
return worked ;
}
public static void purgePowerlessFlatfile ( ) {
mcMMO . p . getLogger ( ) . info ( " Purging powerless users... " ) ;
int purgedUsers = 0 ;
for ( McMMOPlayer player : Users . getPlayers ( ) . values ( ) ) {
String playerName = player . getPlayer ( ) . getName ( ) ;
if ( playerName = = null | | Bukkit . getOfflinePlayer ( playerName ) . isOnline ( ) ) {
continue ;
}
if ( getPlayerRank ( playerName ) [ 1 ] = = 0 & & removeFlatFileUser ( playerName ) ) {
purgedUsers + + ;
}
}
mcMMO . p . getLogger ( ) . info ( " Purged " + purgedUsers + " users from the database. " ) ;
}
public static void purgeOldFlatfile ( ) {
mcMMO . p . getLogger ( ) . info ( " Purging old users... " ) ;
int purgedUsers = removeOldFlatfileUsers ( ) ;
mcMMO . p . getLogger ( ) . info ( " Purged " + purgedUsers + " users from the database. " ) ;
}
private static int removeOldFlatfileUsers ( ) {
int removedPlayers = 0 ;
long currentTime = System . currentTimeMillis ( ) ;
long purgeTime = 2630000000L * Config . getInstance ( ) . getOldUsersCutoff ( ) ;
BufferedReader in = null ;
FileWriter out = null ;
String usersFilePath = mcMMO . getUsersFilePath ( ) ;
try {
FileReader file = new FileReader ( usersFilePath ) ;
in = new BufferedReader ( file ) ;
StringBuilder writer = new StringBuilder ( ) ;
String line = " " ;
while ( ( line = in . readLine ( ) ) ! = null ) {
/* Write out the same file but when we get to the player we want to remove, we skip his line. */
if ( currentTime - ( Misc . getLong ( line . split ( " : " ) [ 37 ] ) * 1000 ) < = purgeTime ) {
writer . append ( line ) . append ( " \ r \ n " ) ;
}
else {
System . out . println ( " User found, removing... " ) ;
removedPlayers + + ;
continue ; //Skip the player
}
}
out = new FileWriter ( usersFilePath ) ; //Write out the new file
out . write ( writer . toString ( ) ) ;
}
catch ( Exception e ) {
mcMMO . p . getLogger ( ) . severe ( " Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?) " + e . toString ( ) ) ;
}
finally {
if ( in ! = null ) {
try {
in . close ( ) ;
}
catch ( IOException ex ) {
ex . printStackTrace ( ) ;
}
}
if ( out ! = null ) {
try {
out . close ( ) ;
}
catch ( IOException ex ) {
ex . printStackTrace ( ) ;
}
}
}
return removedPlayers ;
}
2012-04-27 11:47:11 +02:00
}