refactor: clean source code
This commit is contained in:
73
Tools/Stat Conversion/pom.xml
Normal file
73
Tools/Stat Conversion/pom.xml
Normal file
@ -0,0 +1,73 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>StatConverter</groupId>
|
||||
<artifactId>StatConverter</artifactId>
|
||||
<version>1.0</version>
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src</directory>
|
||||
<excludes>
|
||||
<exclude>**/*.java</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.1</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<Main-Class>com.mineplex.statconverter.Main</Main-Class>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
<configuration>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>2.4.3</version>
|
||||
<type>maven-plugin</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-dbcp2</artifactId>
|
||||
<version>2.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.14</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,192 @@
|
||||
package com.mineplex.statconverter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.mineplex.statconverter.database.mysql.DBPool;
|
||||
|
||||
public class BucketFiller
|
||||
{
|
||||
private File _info;
|
||||
|
||||
private boolean _complete = false;
|
||||
|
||||
private List<Integer> _statIds;
|
||||
private int _nextStat;
|
||||
private int _nextStartLimit;
|
||||
|
||||
public BucketFiller()
|
||||
{
|
||||
int stat = 0;
|
||||
int startLimit = 0;
|
||||
try
|
||||
{
|
||||
if (new File(new File(".").getCanonicalPath() + File.separator + "completeBuckets.dat").exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_info = new File(new File(".").getCanonicalPath() + File.separator + "bucketInfo.dat");
|
||||
System.out.println(_info.getCanonicalPath());
|
||||
|
||||
_statIds = loadStatIds();
|
||||
if (_statIds.isEmpty() || _statIds == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_info.exists())
|
||||
{
|
||||
String startStr = Files.readFirstLine(_info, Charset.defaultCharset());
|
||||
if (startStr != null && !startStr.isEmpty() && startStr.contains(",") && !startStr.endsWith(",") && !startStr.startsWith(","))
|
||||
{
|
||||
String[] starts = startStr.split(Pattern.quote(","));
|
||||
stat = Integer.parseInt(starts[0]);
|
||||
startLimit = Integer.parseInt(starts[1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_info.createNewFile();
|
||||
stat = _statIds.get(0);
|
||||
Files.write((stat + ",0").getBytes(), _info);
|
||||
}
|
||||
|
||||
_nextStat = stat;
|
||||
_nextStartLimit = startLimit;
|
||||
|
||||
while (!_complete)
|
||||
{
|
||||
try
|
||||
{
|
||||
convertStat(_nextStat, _nextStartLimit);
|
||||
}
|
||||
catch (SQLException | IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Integer> loadStatIds()
|
||||
{
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
|
||||
try (Connection c = DBPool.getDataSource("ACCOUNT_PC").getConnection();
|
||||
PreparedStatement ps = c.prepareStatement("SELECT id FROM stats ORDER BY id DESC;");
|
||||
ResultSet rs = ps.executeQuery();
|
||||
)
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
ids.add(rs.getInt("id"));
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
private void convertStat(int stat, int start) throws SQLException, IOException
|
||||
{
|
||||
System.out.println("[INFO] Starting " + stat + ": " + start + " to " + (start + 9999));
|
||||
Map<Integer, Long> accounts = new HashMap<>();
|
||||
try (Connection c = DBPool.getDataSource("ACCOUNT_PC").getConnection())
|
||||
{
|
||||
try (Statement s = c.createStatement();
|
||||
ResultSet rs = s.executeQuery("SELECT accountId, value FROM accountStatsAllTime WHERE statId=" + stat + " LIMIT " + start + ",10000;")
|
||||
)
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
accounts.put(rs.getInt("accountId"), rs.getLong("value"));
|
||||
}
|
||||
}
|
||||
|
||||
if (!accounts.isEmpty())
|
||||
{
|
||||
for (Entry<Integer, Long> entry : accounts.entrySet())
|
||||
{
|
||||
Long value = entry.getValue();
|
||||
try (Statement s = c.createStatement())
|
||||
{
|
||||
s.execute("UPDATE accountStatsAllTimeBuckets SET playerCount=playerCount+1 WHERE minScore <= " + value + " AND maxScore >= " + value + " AND statId=" + stat + " LIMIT 1;");
|
||||
}
|
||||
}
|
||||
completeStatGroup(stat, start);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
completeStat(stat);
|
||||
}
|
||||
catch (IndexOutOfBoundsException ex)
|
||||
{
|
||||
complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void completeStatGroup(int stat, int start) throws IOException
|
||||
{
|
||||
_nextStartLimit = start + 10000;
|
||||
if (_info.delete())
|
||||
{
|
||||
_info.createNewFile();
|
||||
Files.write((stat + "," + start).getBytes(), _info);
|
||||
System.out.println("[INFO] Completed " + stat + ": " + start + " to " + (_nextStartLimit - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Unable to delete info file");
|
||||
}
|
||||
}
|
||||
|
||||
private void completeStat(int stat) throws IOException, IndexOutOfBoundsException
|
||||
{
|
||||
if (_info.delete())
|
||||
{
|
||||
_info.createNewFile();
|
||||
Files.write((stat + "," + 0).getBytes(), _info);
|
||||
System.out.println("[INFO] Conversion of stat " + stat + " complete");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("Unable to delete info file");
|
||||
}
|
||||
_nextStat = _statIds.get(_statIds.indexOf(stat) + 1);
|
||||
_nextStartLimit = 0;
|
||||
}
|
||||
|
||||
private void complete() throws IOException
|
||||
{
|
||||
_complete = true;
|
||||
System.out.println("[INFO] Conversion of buckets complete");
|
||||
new File(new File(".").getCanonicalPath() + File.separator + "completeBuckets.dat").createNewFile();
|
||||
}
|
||||
}
|
281
Tools/Stat Conversion/src/com/mineplex/statconverter/Main.java
Normal file
281
Tools/Stat Conversion/src/com/mineplex/statconverter/Main.java
Normal file
@ -0,0 +1,281 @@
|
||||
package com.mineplex.statconverter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.mineplex.statconverter.database.mysql.DBPool;
|
||||
import com.mysql.jdbc.exceptions.jdbc4.MySQLDataException;
|
||||
|
||||
public class Main
|
||||
{
|
||||
private static final String FILE_PATH_BASE;
|
||||
|
||||
static
|
||||
{
|
||||
String path;
|
||||
try
|
||||
{
|
||||
path = new File(".").getCanonicalPath() + File.separator;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
path = "";
|
||||
}
|
||||
|
||||
FILE_PATH_BASE = path;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (new File(FILE_PATH_BASE + "doBuckets.dat").exists())
|
||||
{
|
||||
new BucketFiller();
|
||||
}
|
||||
else
|
||||
{
|
||||
new Main();
|
||||
}
|
||||
}
|
||||
|
||||
private File _info;
|
||||
private boolean _complete = false;
|
||||
private int _totalCompleted;
|
||||
private long _startTime;
|
||||
|
||||
public Main()
|
||||
{
|
||||
int completed = 0;
|
||||
try
|
||||
{
|
||||
if (new File(FILE_PATH_BASE + "complete.dat").exists())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_info = new File(FILE_PATH_BASE + "converterInfo.dat");
|
||||
System.out.println(FILE_PATH_BASE + "converterInfo.dat");
|
||||
|
||||
if (_info.exists())
|
||||
{
|
||||
String completedStr = Files.readFirstLine(_info, Charset.defaultCharset());
|
||||
if (completedStr != null && !completedStr.isEmpty())
|
||||
{
|
||||
completed = Integer.parseInt(completedStr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_info.createNewFile();
|
||||
Files.write(String.valueOf(0).getBytes(), _info);
|
||||
}
|
||||
|
||||
_totalCompleted = completed;
|
||||
|
||||
while (!_complete)
|
||||
{
|
||||
convertGroup();
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void convertGroup()
|
||||
{
|
||||
_startTime = System.currentTimeMillis();
|
||||
System.out.println("[INFO] Starting next batch of 10000 (Number " + (_totalCompleted + 1) + ")");
|
||||
Map<Integer[], Long> converting = new HashMap<>(10000);
|
||||
try (Connection c = DBPool.getDataSource("ACCOUNT_PC").getConnection())
|
||||
{
|
||||
try (Statement s = c.createStatement();
|
||||
ResultSet rs = s.executeQuery("SELECT accountId, statId, value FROM accountStat LIMIT 10000;")
|
||||
)
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
final int accountId = rs.getInt("accountId");
|
||||
final int statId = rs.getInt("statId");
|
||||
long value = 0;
|
||||
try
|
||||
{
|
||||
value = rs.getLong("value");
|
||||
}
|
||||
catch (MySQLDataException ex)
|
||||
{
|
||||
long played = 0;
|
||||
try (ResultSet r = s.executeQuery("SELECT name FROM stats WHERE id=" + statId + ";"))
|
||||
{
|
||||
r.next();
|
||||
String[] parts = r.getString(1).split(Pattern.quote("."));
|
||||
String type = parts[0];
|
||||
String stat = parts[1];
|
||||
if (!stat.equals("ExpEarned"))
|
||||
{
|
||||
System.out.println("VALUE IS TOO BIG BUT STAT IS NOT EXPEARNED");
|
||||
System.exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
ResultSet playedSet;
|
||||
if (type.equals("Global"))
|
||||
{
|
||||
playedSet = s.executeQuery("SELECT SUM(value) FROM accountStat WHERE accountId=" + accountId + " AND statId IN (SELECT id FROM stats WHERE name LIKE '%.Wins' OR name LIKE '%.Losses');");
|
||||
}
|
||||
else
|
||||
{
|
||||
playedSet = s.executeQuery("SELECT SUM(value) FROM accountStat WHERE accountId=" + accountId + " AND statId IN (SELECT id FROM stats WHERE name IN ('" + type + ".Wins', '" + type + ".Losses'));");
|
||||
}
|
||||
if (playedSet.next())
|
||||
{
|
||||
try
|
||||
{
|
||||
played = playedSet.getLong(1);
|
||||
}
|
||||
catch (Exception anything) {}
|
||||
finally
|
||||
{
|
||||
playedSet.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long newValue = played * 625; //Average xp per game network-wide
|
||||
s.executeUpdate("UPDATE accountStat SET value=" + newValue + " WHERE accountId=" + accountId + " AND statId=" + statId + ";");
|
||||
value = newValue;
|
||||
}
|
||||
converting.put(new Integer[] {rs.getInt("accountId"), rs.getInt("statId")}, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
_complete = true;
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (!converting.isEmpty())
|
||||
{
|
||||
try (Connection c = DBPool.getDataSource("ACCOUNT_PC").getConnection();
|
||||
PreparedStatement select = c.prepareStatement("SELECT value FROM accountStatsAllTime WHERE accountId=? AND statId=?;");
|
||||
PreparedStatement update = c.prepareStatement("UPDATE accountStatsAllTime SET value=value+? WHERE accountId=? AND statId=?;");
|
||||
PreparedStatement insert = c.prepareStatement("INSERT INTO accountStatsAllTime (accountId, statId, value) VALUES (?, ?, ?);");
|
||||
PreparedStatement delete = c.prepareStatement("DELETE FROM accountStat WHERE accountId=? AND statId=?;");
|
||||
)
|
||||
{
|
||||
for (Entry<Integer[], Long> convertEntry : converting.entrySet())
|
||||
{
|
||||
int accountId = convertEntry.getKey()[0];
|
||||
int statId = convertEntry.getKey()[1];
|
||||
long value = convertEntry.getValue();
|
||||
select.setInt(1, accountId);
|
||||
select.setInt(2, statId);
|
||||
long fetched = -1;
|
||||
try (ResultSet rs = select.executeQuery())
|
||||
{
|
||||
if (rs.next())
|
||||
{
|
||||
fetched = rs.getLong("value");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
select.clearParameters();
|
||||
}
|
||||
long diff = value - Math.max(fetched, 0);
|
||||
if (fetched == -1)
|
||||
{
|
||||
insert.setInt(1, accountId);
|
||||
insert.setInt(2, statId);
|
||||
insert.setLong(3, value);
|
||||
insert.execute();
|
||||
insert.clearParameters();
|
||||
}
|
||||
else if (value > 0 && fetched >= 2 * value)
|
||||
{
|
||||
update.setLong(1, -1 * value);
|
||||
update.setInt(2, accountId);
|
||||
update.setInt(3, statId);
|
||||
update.execute();
|
||||
update.clearParameters();
|
||||
}
|
||||
else if (diff > 0)
|
||||
{
|
||||
update.setLong(1, diff);
|
||||
update.setInt(2, accountId);
|
||||
update.setInt(3, statId);
|
||||
update.execute();
|
||||
update.clearParameters();
|
||||
}
|
||||
|
||||
delete.setInt(1, accountId);
|
||||
delete.setInt(2, statId);
|
||||
delete.addBatch();
|
||||
}
|
||||
delete.executeBatch();
|
||||
}
|
||||
completeGroup();
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("[INFO] Conversion complete");
|
||||
try
|
||||
{
|
||||
new File(FILE_PATH_BASE + "complete.dat").createNewFile();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
_complete = true;
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
_complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void completeGroup()
|
||||
{
|
||||
long timeTaken = System.currentTimeMillis() - _startTime;
|
||||
_startTime = 0;
|
||||
if (_info.delete())
|
||||
{
|
||||
try
|
||||
{
|
||||
_totalCompleted++;
|
||||
_info.createNewFile();
|
||||
Files.write(String.valueOf(_totalCompleted).getBytes(), _info);
|
||||
System.out.println("[INFO] Completed group " + _totalCompleted + " of 10000 in " + timeTaken + " milliseconds");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
_complete = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_complete = true;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.mineplex.statconverter.database.mysql;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.sql.Connection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
|
||||
public final class DBPool
|
||||
{
|
||||
private static final Map<String, DataSource> _dataSources = new ConcurrentHashMap<>();
|
||||
|
||||
public static DataSource getDataSource(String databaseId)
|
||||
{
|
||||
if (_dataSources == null || _dataSources.isEmpty())
|
||||
{
|
||||
loadDataSources();
|
||||
}
|
||||
return _dataSources.get(databaseId);
|
||||
}
|
||||
|
||||
private static DataSource openDataSource(String url, String username, String password)
|
||||
{
|
||||
BasicDataSource source = new BasicDataSource();
|
||||
source.addConnectionProperty("autoReconnect", "true");
|
||||
source.addConnectionProperty("allowMultiQueries", "true");
|
||||
source.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
|
||||
source.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
source.setUrl(url);
|
||||
source.setUsername(username);
|
||||
source.setPassword(password);
|
||||
source.setMaxTotal(3);
|
||||
source.setMaxIdle(3);
|
||||
source.setTimeBetweenEvictionRunsMillis(180 * 1000);
|
||||
source.setSoftMinEvictableIdleTimeMillis(180 * 1000);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
private static void loadDataSources()
|
||||
{
|
||||
Map<String, DataSource> dataSources = new HashMap<>();
|
||||
try
|
||||
{
|
||||
File configFile = new File(new File(".").getCanonicalPath() + File.separator + "database-config.dat");
|
||||
|
||||
if (configFile.exists())
|
||||
{
|
||||
List<String> lines = Files.readAllLines(configFile.toPath(),
|
||||
Charset.defaultCharset());
|
||||
|
||||
for (String line : lines)
|
||||
{
|
||||
String[] args = line.split(" ");
|
||||
|
||||
if (args.length == 4)
|
||||
{
|
||||
String dbId = args[0];
|
||||
String dbHost = args[1];
|
||||
String userName = args[2];
|
||||
String password = args[3];
|
||||
|
||||
dataSources.put(dbId, openDataSource("jdbc:mysql://" + dbHost, userName, password));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("database-config.dat not found at "
|
||||
+ configFile.toPath().toString());
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
exception.printStackTrace();
|
||||
System.out.println("---Unable To Parse DBPOOL Configuration File---");
|
||||
}
|
||||
|
||||
_dataSources.replaceAll((database, source) -> dataSources.getOrDefault(database, source));
|
||||
dataSources.forEach((database, source) -> _dataSources.putIfAbsent(database, source));
|
||||
_dataSources.entrySet().removeIf(entry -> !dataSources.containsKey(entry.getKey()));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user