2015-07-30 19:24:01 +02:00
package com.plotsquared.bukkit.uuid ;
2015-07-24 16:06:58 +02:00
2015-07-30 16:25:16 +02:00
import java.io.BufferedReader ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.net.HttpURLConnection ;
import java.net.URL ;
import java.sql.Connection ;
import java.sql.PreparedStatement ;
import java.sql.ResultSet ;
import java.sql.SQLException ;
import java.util.ArrayList ;
import java.util.HashMap ;
import java.util.Iterator ;
import java.util.List ;
import java.util.UUID ;
2015-07-27 15:10:14 +02:00
import com.google.common.collect.HashBiMap ;
2015-07-27 09:26:50 +02:00
import com.intellectualcrafters.json.JSONObject ;
2015-07-24 16:06:58 +02:00
import com.intellectualcrafters.plot.PS ;
import com.intellectualcrafters.plot.config.C ;
import com.intellectualcrafters.plot.config.Settings ;
import com.intellectualcrafters.plot.database.DBFunc ;
2015-07-27 09:26:50 +02:00
import com.intellectualcrafters.plot.database.SQLite ;
import com.intellectualcrafters.plot.object.RunnableVal ;
2015-07-24 16:06:58 +02:00
import com.intellectualcrafters.plot.object.StringWrapper ;
import com.intellectualcrafters.plot.util.TaskManager ;
2015-07-27 09:26:50 +02:00
import com.intellectualcrafters.plot.util.UUIDHandler ;
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation ;
2015-07-24 16:06:58 +02:00
import com.intellectualcrafters.plot.uuid.UUIDWrapper ;
2015-07-27 09:26:50 +02:00
public class SQLUUIDHandler extends UUIDHandlerImplementation {
public SQLUUIDHandler ( UUIDWrapper wrapper ) {
super ( wrapper ) ;
2015-07-24 16:06:58 +02:00
_sqLite = new SQLite ( " ./plugins/PlotSquared/usercache.db " ) ;
try {
_sqLite . openConnection ( ) ;
2015-07-27 09:26:50 +02:00
} catch ( final Exception e ) {
2015-07-24 16:06:58 +02:00
e . printStackTrace ( ) ;
}
2015-07-27 09:26:50 +02:00
2015-07-24 16:06:58 +02:00
try {
2015-07-27 15:10:14 +02:00
PreparedStatement stmt = getConnection ( ) . prepareStatement ( " CREATE TABLE IF NOT EXISTS `usercache` (uuid VARCHAR(32) NOT NULL, username VARCHAR(32) NOT NULL, PRIMARY KEY (uuid, username)) " ) ;
2015-07-24 16:06:58 +02:00
stmt . execute ( ) ;
stmt . close ( ) ;
} catch ( SQLException e ) {
e . printStackTrace ( ) ;
}
2015-07-27 15:10:14 +02:00
startCaching ( null ) ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 09:26:50 +02:00
private class SQLUUIDHandlerException extends RuntimeException {
SQLUUIDHandlerException ( String s , Throwable c ) {
super ( " SQLUUIDHandler caused an exception: " + s , c ) ;
}
@SuppressWarnings ( " unused " )
SQLUUIDHandlerException ( String s ) {
super ( " SQLUUIDHandler caused an exception: " + s ) ;
2015-07-24 16:06:58 +02:00
}
}
2015-07-27 09:26:50 +02:00
private final SQLite _sqLite ;
private Connection getConnection ( ) {
synchronized ( _sqLite ) {
return _sqLite . getConnection ( ) ;
}
2015-07-24 16:06:58 +02:00
}
2015-07-27 09:26:50 +02:00
2015-07-24 16:06:58 +02:00
@Override
2015-07-27 15:10:14 +02:00
public boolean startCaching ( final Runnable whenDone ) {
if ( ! super . startCaching ( whenDone ) ) {
2015-07-27 09:26:50 +02:00
return false ;
}
2015-07-24 16:06:58 +02:00
TaskManager . runTaskAsync ( new Runnable ( ) {
@Override
public void run ( ) {
try {
2015-07-27 15:10:14 +02:00
final HashBiMap < StringWrapper , UUID > toAdd = HashBiMap . create ( new HashMap < StringWrapper , UUID > ( ) ) ;
2015-07-24 16:06:58 +02:00
PreparedStatement statement = getConnection ( ) . prepareStatement ( " SELECT `uuid`, `username` FROM `usercache` " ) ;
ResultSet resultSet = statement . executeQuery ( ) ;
StringWrapper username ;
UUID uuid ;
while ( resultSet . next ( ) ) {
username = new StringWrapper ( resultSet . getString ( " username " ) ) ;
uuid = UUID . fromString ( resultSet . getString ( " uuid " ) ) ;
2015-07-27 15:10:14 +02:00
toAdd . put ( new StringWrapper ( username . value ) , uuid ) ;
2015-07-24 16:06:58 +02:00
}
statement . close ( ) ;
2015-07-27 15:10:14 +02:00
add ( toAdd ) ;
add ( new StringWrapper ( " * " ) , DBFunc . everyone ) ;
// This should be called as long as there are some unknown plots
final List < UUID > toFetch = new ArrayList < > ( ) ;
for ( UUID u : UUIDHandler . getAllUUIDS ( ) ) {
if ( ! uuidExists ( u ) ) {
toFetch . add ( u ) ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 15:10:14 +02:00
}
if ( toFetch . isEmpty ( ) ) {
if ( whenDone ! = null ) whenDone . run ( ) ;
return ;
}
FileUUIDHandler fileHandler = new FileUUIDHandler ( SQLUUIDHandler . this . uuidWrapper ) ;
fileHandler . startCaching ( new Runnable ( ) {
@Override
public void run ( ) {
// If the file based UUID handler didn't cache it, then we can't cache offline mode
// Also, trying to cache based on files again, is useless as that's what the file based uuid cacher does
if ( Settings . OFFLINE_MODE ) {
if ( whenDone ! = null ) whenDone . run ( ) ;
2015-07-24 16:06:58 +02:00
return ;
}
2015-07-27 15:10:14 +02:00
if ( ! Settings . OFFLINE_MODE ) {
2015-07-30 16:25:16 +02:00
PS . debug ( C . PREFIX . s ( ) + " &cWill fetch &6 " + toFetch . size ( ) + " &c from mojang! " ) ;
2015-07-27 15:10:14 +02:00
int i = 0 ;
Iterator < UUID > iterator = toFetch . iterator ( ) ;
while ( iterator . hasNext ( ) ) {
StringBuilder url = new StringBuilder ( " http://api.intellectualsites.com/uuid/?user= " ) ;
List < UUID > currentIteration = new ArrayList < > ( ) ;
while ( i + + < = 15 & & iterator . hasNext ( ) ) {
UUID _uuid = iterator . next ( ) ;
url . append ( _uuid . toString ( ) ) ;
if ( iterator . hasNext ( ) ) {
url . append ( " , " ) ;
}
currentIteration . add ( _uuid ) ;
2015-07-24 16:06:58 +02:00
}
2015-07-30 16:25:16 +02:00
PS . debug ( C . PREFIX . s ( ) + " &cWill attempt to fetch &6 " + currentIteration . size ( ) + " &c uuids from: &6 " + url . toString ( ) ) ;
2015-07-27 15:10:14 +02:00
try {
HttpURLConnection connection = ( HttpURLConnection ) new URL ( url . toString ( ) ) . openConnection ( ) ;
connection . setRequestProperty ( " User-Agent " , " Mozilla/5.0 " ) ;
BufferedReader reader = new BufferedReader ( new InputStreamReader ( connection . getInputStream ( ) ) ) ;
String line ;
StringBuilder rawJSON = new StringBuilder ( ) ;
while ( ( line = reader . readLine ( ) ) ! = null ) {
rawJSON . append ( line ) ;
}
reader . close ( ) ;
JSONObject object = new JSONObject ( rawJSON . toString ( ) ) ;
for ( UUID _u : currentIteration ) {
Object o = object . getJSONObject ( _u . toString ( ) . replace ( " - " , " " ) ) . get ( " username " ) ;
if ( o = = null | | ! ( o instanceof String ) ) {
continue ;
}
add ( new StringWrapper ( o . toString ( ) ) , _u ) ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 15:10:14 +02:00
} catch ( final Exception e ) {
e . printStackTrace ( ) ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 15:10:14 +02:00
i = 0 ;
2015-07-24 16:06:58 +02:00
}
}
2015-07-27 15:10:14 +02:00
if ( whenDone ! = null ) whenDone . run ( ) ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 15:10:14 +02:00
} ) ;
2015-07-24 16:06:58 +02:00
} catch ( SQLException e ) {
throw new SQLUUIDHandlerException ( " Couldn't select :s " , e ) ;
}
}
} ) ;
2015-07-27 09:26:50 +02:00
return true ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 09:26:50 +02:00
2015-07-24 16:06:58 +02:00
@Override
2015-07-27 09:26:50 +02:00
public void fetchUUID ( final String name , final RunnableVal < UUID > ifFetch ) {
2015-07-30 16:25:16 +02:00
PS . debug ( C . PREFIX . s ( ) + " UUID for ' " + name + " ' was null. We'll cache this from the mojang servers! " ) ;
2015-07-24 16:06:58 +02:00
TaskManager . runTaskAsync ( new Runnable ( ) {
@Override
public void run ( ) {
2015-07-27 09:26:50 +02:00
String url = " http://api.intellectualsites.com/uuid/?user= " + name ;
2015-07-24 16:06:58 +02:00
try {
2015-07-27 09:26:50 +02:00
HttpURLConnection connection = ( HttpURLConnection ) new URL ( url ) . openConnection ( ) ;
connection . setRequestProperty ( " User-Agent " , " Mozilla/5.0 " ) ;
BufferedReader reader = new BufferedReader ( new InputStreamReader ( connection . getInputStream ( ) ) ) ;
String line ;
StringBuilder rawJSON = new StringBuilder ( ) ;
while ( ( line = reader . readLine ( ) ) ! = null ) {
rawJSON . append ( line ) ;
}
reader . close ( ) ;
JSONObject object = new JSONObject ( rawJSON . toString ( ) ) ;
ifFetch . value = UUID . fromString ( object . getJSONObject ( name ) . getString ( " dashed " ) ) ;
add ( new StringWrapper ( name ) , ifFetch . value ) ;
} catch ( IOException e ) {
2015-07-24 16:06:58 +02:00
e . printStackTrace ( ) ;
}
2015-07-27 09:26:50 +02:00
TaskManager . runTask ( ifFetch ) ;
2015-07-24 16:06:58 +02:00
}
} ) ;
}
2015-07-27 09:26:50 +02:00
2015-07-24 16:06:58 +02:00
@Override
2015-07-27 09:26:50 +02:00
public void handleShutdown ( ) {
super . handleShutdown ( ) ;
try {
getConnection ( ) . close ( ) ;
} catch ( SQLException e ) {
throw new SQLUUIDHandlerException ( " Couldn't close database connection " , e ) ;
2015-07-24 16:06:58 +02:00
}
}
2015-07-27 09:26:50 +02:00
2015-07-24 16:06:58 +02:00
@Override
2015-07-27 09:26:50 +02:00
public boolean add ( final StringWrapper name , final UUID uuid ) {
// Ignoring duplicates
2015-07-27 15:10:14 +02:00
if ( super . add ( name , uuid ) ) {
2015-07-24 16:06:58 +02:00
TaskManager . runTaskAsync ( new Runnable ( ) {
@Override
public void run ( ) {
try {
2015-07-27 09:26:50 +02:00
PreparedStatement statement = getConnection ( ) . prepareStatement ( " INSERT INTO usercache (`uuid`, `username`) VALUES(?, ?) " ) ;
statement . setString ( 1 , uuid . toString ( ) ) ;
statement . setString ( 2 , name . toString ( ) ) ;
statement . execute ( ) ;
2015-07-30 16:25:16 +02:00
PS . debug ( C . PREFIX . s ( ) + " &cAdded '&6 " + uuid + " &c' - '&6 " + name + " &c' " ) ;
2015-07-27 09:26:50 +02:00
} catch ( SQLException e ) {
2015-07-24 16:06:58 +02:00
e . printStackTrace ( ) ;
}
}
} ) ;
2015-07-27 15:10:14 +02:00
return true ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 15:10:14 +02:00
return false ;
2015-07-24 16:06:58 +02:00
}
2015-07-27 09:26:50 +02:00
/ * *
* This isn ' t used as any UUID that is unknown is bulk cached ( in lots of 16 )
* @param uuid
* @return
* /
@Deprecated
public String getName__unused__ ( final UUID uuid ) {
2015-07-30 16:25:16 +02:00
PS . debug ( C . PREFIX . s ( ) + " Name for ' " + uuid + " ' was null. We'll cache this from the mojang servers! " ) ;
2015-07-24 16:06:58 +02:00
TaskManager . runTaskAsync ( new Runnable ( ) {
@Override
public void run ( ) {
2015-07-27 09:26:50 +02:00
String url = " http://api.intellectualsites.com/uuid/?user= " + uuid ;
2015-07-24 16:06:58 +02:00
try {
HttpURLConnection connection = ( HttpURLConnection ) new URL ( url ) . openConnection ( ) ;
connection . setRequestProperty ( " User-Agent " , " Mozilla/5.0 " ) ;
BufferedReader reader = new BufferedReader ( new InputStreamReader ( connection . getInputStream ( ) ) ) ;
String line ;
StringBuilder rawJSON = new StringBuilder ( ) ;
while ( ( line = reader . readLine ( ) ) ! = null ) {
rawJSON . append ( line ) ;
}
reader . close ( ) ;
JSONObject object = new JSONObject ( rawJSON . toString ( ) ) ;
2015-07-27 09:26:50 +02:00
String username = object . getJSONObject ( uuid . toString ( ) . replace ( " - " , " " ) ) . getString ( " username " ) ;
add ( new StringWrapper ( username ) , uuid ) ;
2015-07-24 16:06:58 +02:00
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
}
} ) ;
return null ;
}
2015-07-27 15:10:14 +02:00
@Override
public void rename ( final UUID uuid , final StringWrapper name ) {
super . rename ( uuid , name ) ;
TaskManager . runTaskAsync ( new Runnable ( ) {
@Override
public void run ( ) {
try {
PreparedStatement statement = getConnection ( ) . prepareStatement ( " UPDATE usercache SET `username`=? WHERE `uuid`=? " ) ;
statement . setString ( 1 , name . value ) ;
statement . setString ( 2 , uuid . toString ( ) ) ;
statement . execute ( ) ;
2015-07-30 16:25:16 +02:00
PS . debug ( C . PREFIX . s ( ) + " Name change for ' " + uuid + " ' to ' " + name . value + " ' " ) ;
2015-07-27 15:10:14 +02:00
} catch ( SQLException e ) {
e . printStackTrace ( ) ;
}
}
} ) ;
}
2015-07-24 16:06:58 +02:00
}