diff --git a/Plan/.idea/libraries/Maven__com_destroystokyo_paper_paper_1_12_R0_1_SNAPSHOT.xml b/Plan/.idea/libraries/Maven__com_destroystokyo_paper_paper_1_12_R0_1_SNAPSHOT.xml new file mode 100644 index 000000000..ec40ac224 --- /dev/null +++ b/Plan/.idea/libraries/Maven__com_destroystokyo_paper_paper_1_12_R0_1_SNAPSHOT.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plan/.idea/libraries/Maven__com_destroystokyo_paper_paper_spigot_1_12.xml b/Plan/.idea/libraries/Maven__com_destroystokyo_paper_paper_spigot_1_12.xml new file mode 100644 index 000000000..52ad59c0d --- /dev/null +++ b/Plan/.idea/libraries/Maven__com_destroystokyo_paper_paper_spigot_1_12.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_0.xml b/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_0.xml new file mode 100644 index 000000000..e90b3b519 --- /dev/null +++ b/Plan/.idea/libraries/Maven__com_djrapitops_abstract_plugin_framework_2_0_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plan/.idea/uiDesigner.xml b/Plan/.idea/uiDesigner.xml new file mode 100644 index 000000000..e96534fb2 --- /dev/null +++ b/Plan/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/analysis/KillPart.java b/Plan/src/main/java/com/djrapitops/plan/data/analysis/KillPart.java index 1f8e16768..84932918e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/analysis/KillPart.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/analysis/KillPart.java @@ -3,6 +3,7 @@ package main.java.com.djrapitops.plan.data.analysis; import com.djrapitops.plugin.utilities.Verify; import main.java.com.djrapitops.plan.data.KillData; import main.java.com.djrapitops.plan.utilities.MiscUtils; +import main.java.com.djrapitops.plan.utilities.analysis.MathUtils; import java.util.HashMap; import java.util.List; @@ -16,14 +17,14 @@ import java.util.UUID; *

* Placeholder values can be retrieved using the get method. *

- * Contains following place-holders: deaths, mobkills, playerkilss + * Contains following place-holders: deaths, mobkills, playerkills, avgdeaths, avgmobkills, avgplayerkills * * @author Rsl1122 * @since 3.5.2 */ public class KillPart extends RawData { - private final PlayerCountPart playerCount; // TODO Averages + private final PlayerCountPart playerCount; private final Map> playerKills; private long mobKills; private long deaths; @@ -39,7 +40,12 @@ public class KillPart extends RawData { public void analyse() { addValue("deaths", deaths); addValue("mobkills", mobKills); - addValue("playerkills", getAllPlayerKills().size()); + int playerKillAmount = getAllPlayerKills().size(); + addValue("playerkills", playerKillAmount); + int playerCount = this.playerCount.getPlayerCount(); + addValue("avgdeaths", MathUtils.averageLong(deaths, playerCount)); + addValue("avgmobkills", MathUtils.averageLong(mobKills, playerCount)); + addValue("avgplayerkills", MathUtils.averageLong(playerKillAmount, playerCount)); } public void addKills(UUID uuid, List kills) throws IllegalArgumentException { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java b/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java index 08d68772c..b793f1e51 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheHandler.java @@ -220,8 +220,6 @@ public class DataCacheHandler extends SessionCache { /** * Saves all UserData in the cache to Database. *

- * ATTENTION: TODO - Doesn't save the Locations in the locationCache. - *

* Should only be called from Async thread */ public void saveCachedUserData() { diff --git a/Plan/src/main/java/com/djrapitops/plan/database/Database.java b/Plan/src/main/java/com/djrapitops/plan/database/Database.java index b1eb42a05..4c187e7e5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/Database.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/Database.java @@ -78,8 +78,27 @@ public abstract class Database { */ protected VersionTable versionTable; + /** + * Table representing plan_security in the database. + * + * @since 3.5.2 + */ protected SecurityTable securityTable; + /** + * Table representing plan_worlds in the database. + * + * @since 3.6.0 + */ + protected WorldTable worldTable; + + /** + * Table representing plan_world_times in the database. + * + * @since 3.6.0 + */ + protected WorldTimesTable worldTimesTable; + /** * Super constructor. * @@ -343,7 +362,30 @@ public abstract class Database { return tpsTable; } + /** + * Used to get the security table. + * + * @return Table representing plan_security + */ public SecurityTable getSecurityTable() { return securityTable; } + + /** + * Used to get the worlds table. + * + * @return Table representing plan_worlds + */ + public WorldTable getWorldTable() { + return worldTable; + } + + /** + * Used to get the world times table. + * + * @return Table representing plan_world_times + */ + public WorldTimesTable getWorldTimesTable() { + return worldTimesTable; + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java index 18750f9cf..b4c711467 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/databases/SQLDB.java @@ -48,6 +48,8 @@ public abstract class SQLDB extends Database { versionTable = new VersionTable(this, usingMySQL); tpsTable = new TPSTable(this, usingMySQL); securityTable = new SecurityTable(this, usingMySQL); + worldTable = new WorldTable(this, usingMySQL); + worldTimesTable = new WorldTimesTable(this, usingMySQL); startConnectionPingTask(); } @@ -118,7 +120,7 @@ public abstract class SQLDB extends Database { } if (newDatabase) { Log.info("New Database created."); - setVersion(6); + setVersion(7); } Benchmark.start("Database: Create tables"); for (Table table : getAllTables()) { @@ -132,8 +134,8 @@ public abstract class SQLDB extends Database { return false; } Benchmark.stop("Database: Create tables"); - if (!newDatabase && getVersion() < 6) { - setVersion(6); + if (!newDatabase && getVersion() < 7) { + setVersion(7); } } return true; @@ -177,14 +179,22 @@ public abstract class SQLDB extends Database { * @return */ public Table[] getAllTables() { - return new Table[]{usersTable, gmTimesTable, ipsTable, nicknamesTable, sessionsTable, killsTable, commandUseTable, tpsTable}; + return new Table[]{ + usersTable, gmTimesTable, ipsTable, + nicknamesTable, sessionsTable, killsTable, + commandUseTable, tpsTable, worldTable, + worldTimesTable}; } /** * @return */ public Table[] getAllTablesInRemoveOrder() { - return new Table[]{locationsTable, gmTimesTable, ipsTable, nicknamesTable, sessionsTable, killsTable, usersTable, commandUseTable, tpsTable}; + return new Table[]{ + locationsTable, gmTimesTable, ipsTable, + nicknamesTable, sessionsTable, killsTable, + worldTimesTable, worldTable, usersTable, + commandUseTable, tpsTable}; } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java index 388c35f50..0bc030461 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/TPSTable.java @@ -26,6 +26,9 @@ public class TPSTable extends Table { private final String columnTPS; private final String columnPlayers; private final String columnCPUUsage; + private final String columnRAMUsage; + private final String columnEntities; + private final String columnChunksLoaded; /** * @param db @@ -37,7 +40,9 @@ public class TPSTable extends Table { columnTPS = "tps"; columnPlayers = "players_online"; columnCPUUsage = "cpu_usage"; - //TODO add new columns + columnRAMUsage = "ram_usage"; + columnEntities = "entities"; + columnChunksLoaded = "chunks_loaded"; } @Override @@ -47,14 +52,18 @@ public class TPSTable extends Table { + columnDate + " bigint NOT NULL, " + columnTPS + " double NOT NULL, " + columnPlayers + " integer NOT NULL, " - + columnCPUUsage + " double NOT NULL" + + columnCPUUsage + " double NOT NULL, " + + columnEntities + " integer NOT NULL, " + + columnChunksLoaded + " integer NOT NULL" + ")" - //TODO add new columns ); int version = getVersion(); if (version < 6) { alterTablesV6(); } + if (version < 7) { + alterTablesV7(); + } return true; } catch (SQLException ex) { Log.toLog(this.getClass().getName(), ex); @@ -70,11 +79,26 @@ public class TPSTable extends Table { execute("ALTER TABLE " + tableName + " ADD COLUMN " + columnCPUUsage + " double NOT NULL DEFAULT 0"); } } catch (SQLException e) { - } } - //TODO alterTablesV7 + private void alterTablesV7() { + String[] sql; + if (usingMySQL) { + sql = new String[]{ + "ALTER TABLE " + tableName + " ADD " + columnRAMUsage + " bigint NOT NULL DEFAULT 0", + "ALTER TABLE " + tableName + " ADD " + columnEntities + " integer NOT NULL DEFAULT 0", + "ALTER TABLE " + tableName + " ADD " + columnChunksLoaded + " integer NOT NULL DEFAULT 0" + }; + } else { + sql = new String[]{ + "ALTER TABLE " + tableName + " ADD COLUMN " + columnRAMUsage + " bigint NOT NULL DEFAULT 0", + "ALTER TABLE " + tableName + " ADD COLUMN " + columnEntities + " integer NOT NULL DEFAULT 0", + "ALTER TABLE " + tableName + " ADD COLUMN " + columnChunksLoaded + " integer NOT NULL DEFAULT 0" + }; + } + executeUnsafe(sql); + } /** * @return @throws SQLException @@ -92,8 +116,10 @@ public class TPSTable extends Table { double tps = set.getDouble(columnTPS); int players = set.getInt(columnPlayers); double cpuUsage = set.getDouble(columnCPUUsage); - //TODO add new data - data.add(new TPS(date, tps, players, cpuUsage, 0, 0, 0)); + long ramUsage = set.getLong(columnRAMUsage); + int entities = set.getInt(columnEntities); + int chunksLoaded = set.getInt(columnChunksLoaded); + data.add(new TPS(date, tps, players, cpuUsage, ramUsage, entities, chunksLoaded)); } return data; } finally { @@ -121,8 +147,11 @@ public class TPSTable extends Table { + columnDate + ", " + columnTPS + ", " + columnPlayers + ", " - + columnCPUUsage - + ") VALUES (?, ?, ?, ?)"); + + columnCPUUsage + ", " + + columnRAMUsage + ", " + + columnEntities + ", " + + columnChunksLoaded + + ") VALUES (?, ?, ?, ?, ?, ?, ?)"); boolean commitRequired = false; int i = 0; @@ -131,6 +160,9 @@ public class TPSTable extends Table { statement.setDouble(2, tps.getTps()); statement.setInt(3, tps.getPlayers()); statement.setDouble(4, tps.getCPUUsage()); + statement.setLong(5, tps.getUsedMemory()); + statement.setDouble(6, tps.getEntityCount()); + statement.setDouble(7, tps.getChunksLoaded()); statement.addBatch(); commitRequired = true; i++; diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java index 49e5b8821..7c53bcfd1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java @@ -1,5 +1,6 @@ package main.java.com.djrapitops.plan.database.tables; +import com.djrapitops.plugin.utilities.Verify; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.database.Container; import main.java.com.djrapitops.plan.database.DBUtils; @@ -67,13 +68,28 @@ public abstract class Table { } /** - * @param sql + * @param statement * @return * @throws SQLException */ - protected boolean execute(String sql) throws SQLException { + protected boolean execute(String statement) throws SQLException { Connection connection = getConnection(); - return connection.createStatement().execute(sql); + return connection.createStatement().execute(statement); + } + + /** + * Used to execute queries while possible SQLExceptions are suppressed. + * + * @param statements SQL statements to execute + */ + protected void executeUnsafe(String... statements) { + Verify.nullCheck(statements); + for (String statement : statements) { + try { + execute(statement); + } catch (SQLException e) { + } + } } /** diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java index a1200de1f..0382f75c6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/UsersTable.java @@ -123,9 +123,9 @@ public class UsersTable extends Table { } private void alterTablesV4() { - String[] queries; + String[] statements; if (usingMySQL) { - queries = new String[]{ + statements = new String[]{ "ALTER TABLE " + tableName + " ADD " + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " ADD " + columnOP + " boolean NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " ADD " + columnBanned + " boolean NOT NULL DEFAULT 0", @@ -133,7 +133,7 @@ public class UsersTable extends Table { "ALTER TABLE " + tableName + " ADD " + columnRegistered + " bigint NOT NULL DEFAULT 0" }; } else { - queries = new String[]{ + statements = new String[]{ "ALTER TABLE " + tableName + " ADD COLUMN " + columnContainsBukkitData + " boolean NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " ADD COLUMN " + columnOP + " boolean NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " ADD COLUMN " + columnBanned + " boolean NOT NULL DEFAULT 0", @@ -141,34 +141,24 @@ public class UsersTable extends Table { "ALTER TABLE " + tableName + " ADD COLUMN " + columnRegistered + " bigint NOT NULL DEFAULT 0" }; } - for (String query : queries) { - try { - execute(query); - } catch (Exception e) { - } - } + executeUnsafe(statements); } private void alterTablesV3() { - String[] queries; + String[] statements; if (usingMySQL) { - queries = new String[]{ + statements = new String[]{ "ALTER TABLE " + tableName + " ADD " + columnDeaths + " integer NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " ADD " + columnMobKills + " integer NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " DROP INDEX " + columnPlayerKills }; } else { - queries = new String[]{ + statements = new String[]{ "ALTER TABLE " + tableName + " ADD COLUMN " + columnDeaths + " integer NOT NULL DEFAULT 0", "ALTER TABLE " + tableName + " ADD COLUMN " + columnMobKills + " integer NOT NULL DEFAULT 0" }; } - for (String query : queries) { - try { - execute(query); - } catch (Exception e) { - } - } + executeUnsafe(statements); } /** @@ -870,12 +860,4 @@ public class UsersTable extends Table { close(statement); } } - - /** - * @param uuids - * @return - */ - public Map getLoginTimes(Collection uuids) { - throw new UnsupportedOperationException("Not supported yet."); // TODO - } } diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java new file mode 100644 index 000000000..a0e658815 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTable.java @@ -0,0 +1,116 @@ +package main.java.com.djrapitops.plan.database.tables; + +import com.djrapitops.plugin.utilities.Verify; +import main.java.com.djrapitops.plan.Log; +import main.java.com.djrapitops.plan.database.databases.SQLDB; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * Table class representing database table plan_worlds. + *

+ * Used for storing id references to world names. + * + * @author Rsl1122 + * @since 3.6.0 / Database version 7 + */ +public class WorldTable extends Table { + + private final String columnWorldId; + private final String columnWorldName; + + /** + * Constructor. + * + * @param db Database this table is a part of. + * @param usingMySQL Database is a MySQL database. + */ + public WorldTable(SQLDB db, boolean usingMySQL) { + super("plan_worlds", db, usingMySQL); + columnWorldId = "world_id"; + columnWorldName = "world_name"; + } + + @Override + public boolean createTable() { + try { + execute("CREATE TABLE IF NOT EXISTS " + tableName + " (" + + columnWorldId + " integer " + ((usingMySQL) ? "NOT NULL AUTO_INCREMENT" : "PRIMARY KEY") + ", " + + columnWorldName + " varchar(100) NOT NULL" + + (usingMySQL ? ", PRIMARY KEY (" + columnWorldId + ")" : "") + + ")" + ); + return true; + } catch (SQLException ex) { + Log.toLog(this.getClass().getName(), ex); + return false; + } + } + + /** + * Used to get the available world names. + * + * @return List of all world names in the database. + * @throws SQLException Database error occurs. + */ + public List getWorlds() throws SQLException { + PreparedStatement statement = null; + ResultSet set = null; + try { + statement = prepareStatement("SELECT * FROM " + tableName); + set = statement.executeQuery(); + List worldNames = new ArrayList<>(); + while (set.next()) { + String worldName = set.getString(columnWorldName); + worldNames.add(worldName); + } + return worldNames; + } finally { + close(set, statement); + } + } + + /** + * Used to save a list of world names. + *

+ * Already saved names will not be saved. + * + * @param worlds List of world names. + * @throws SQLException Database error occurs. + */ + public void saveWorlds(List worlds) throws SQLException { + Verify.nullCheck(worlds); + + List saved = getWorlds(); + worlds.removeAll(saved); + if (Verify.isEmpty(worlds)) { + return; + } + + PreparedStatement statement = null; + try { + statement = prepareStatement("INSERT INTO " + tableName + " (" + + columnWorldName + + ") VALUES (?)"); + boolean commitRequired = false; + for (String world : worlds) { + statement.setString(1, world); + statement.addBatch(); + commitRequired = true; + } + if (commitRequired) { + statement.executeBatch(); + } + } finally { + close(statement); + } + } + + public String getColumnID() { + return columnWorldId; + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java new file mode 100644 index 000000000..9f35a2263 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/WorldTimesTable.java @@ -0,0 +1,54 @@ +package main.java.com.djrapitops.plan.database.tables; + +import main.java.com.djrapitops.plan.Log; +import main.java.com.djrapitops.plan.database.databases.SQLDB; + +import java.sql.SQLException; + +/** + * Table class representing database table plan_world_times. + * + * @author Rsl1122 + * @since 3.6.0 / Database version 7 + */ +public class WorldTimesTable extends Table { + + private final WorldTable worldTable; + + private final String columnWorldId; + private final String columnUserId; + private final String columnPlaytime; + + /** + * Constructor. + * + * @param db Database this table is a part of. + * @param usingMySQL Database is a MySQL database. + */ + public WorldTimesTable(SQLDB db, boolean usingMySQL) { + super("plan_world_times", db, usingMySQL); + worldTable = db.getWorldTable(); + columnWorldId = "world_id"; + columnUserId = "user_id"; + columnPlaytime = "playtime"; + } + + @Override + public boolean createTable() { + UsersTable usersTable = db.getUsersTable(); + try { + execute("CREATE TABLE IF NOT EXISTS " + tableName + " (" + + columnUserId + " integer NOT NULL, " + + columnWorldId + " integer NOT NULL, " + + columnPlaytime + " bigint NOT NULL, " + + "FOREIGN KEY(" + columnUserId + ") REFERENCES " + usersTable.getTableName() + "(" + usersTable.getColumnID() + "), " + + "FOREIGN KEY(" + columnWorldId + ") REFERENCES " + worldTable.getTableName() + "(" + worldTable.getColumnID() + ")" + + ")" + ); + return true; + } catch (SQLException ex) { + Log.toLog(this.getClass().getName(), ex); + return false; + } + } +} diff --git a/PlanPluginBridge/.idea/shelf/Fix__198.xml b/PlanPluginBridge/.idea/shelf/Fix__198.xml new file mode 100644 index 000000000..cccccdbda --- /dev/null +++ b/PlanPluginBridge/.idea/shelf/Fix__198.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file