Bugfix, Database optimization, Locations, Partial 2.2.0 features [2.2.0-DEV]

- Bugfix for #2 (Catch for NoSuchFieldError, null checks)
- Database now uses Batch processing with Commanduse, IPs, Nicknames &
Locations. Also used when saving whole cache.
- Uncommented Location gathering and swapped the location saving to use
batch processing. TODO: Worlds table
- Added placeholders for top lists & recent players to analysis &
planlite.html

TODO:
- Worlds Table
- Links to players
- New HashMaps in Analysis for recent players
- InspectCache clear multiper
- InspectCache clear task check. (Time value for each task)
This commit is contained in:
Rsl1122 2017-01-26 11:32:42 +02:00
parent f1e3fe7a7e
commit 96240195ef
16 changed files with 409 additions and 371 deletions

4
.gitignore vendored
View File

@ -7,4 +7,6 @@
/Plan Advanced/build/
/Plan Advanced/dist/
/Plan Advanced/nbproject/private/
/Plan/target/
/Plan/target/
/Plan/nbproject/
/Debugger/nbproject/private/

View File

@ -46,8 +46,8 @@ is divided into following sections:
<property file="${user.properties.file}"/>
<!-- The two properties below are usually overridden -->
<!-- by the active platform. Just a fallback. -->
<property name="default.javac.source" value="1.4"/>
<property name="default.javac.target" value="1.4"/>
<property name="default.javac.source" value="1.6"/>
<property name="default.javac.target" value="1.6"/>
</target>
<target depends="-pre-init,-init-private,-init-user" name="-init-project">
<property file="nbproject/configs/${config}.properties"/>
@ -76,7 +76,7 @@ is divided into following sections:
<and>
<isset property="javac.profile"/>
<length length="0" string="${javac.profile}" when="greater"/>
<matches pattern="1\.[89](\..*)?" string="${javac.source}"/>
<matches pattern="((1\.[89])|9)(\..*)?" string="${javac.source}"/>
</and>
</condition>
<condition property="do.archive">
@ -156,6 +156,7 @@ is divided into following sections:
<property name="application.args" value=""/>
<property name="source.encoding" value="${file.encoding}"/>
<property name="runtime.encoding" value="${source.encoding}"/>
<property name="manifest.encoding" value="${source.encoding}"/>
<condition property="javadoc.encoding.used" value="${javadoc.encoding}">
<and>
<isset property="javadoc.encoding"/>
@ -840,7 +841,7 @@ is divided into following sections:
</chainedmapper>
</pathconvert>
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
<copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" manifestencoding="UTF-8" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
<fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
<manifest>
<attribute name="Class-Path" value="${jar.classpath}"/>
@ -852,7 +853,7 @@ is divided into following sections:
</target>
<target name="-init-presetdef-jar">
<presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
<jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
<jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifestencoding="UTF-8">
<j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
</jar>
</presetdef>
@ -975,15 +976,15 @@ is divided into following sections:
</target>
<target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
<tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
<copy file="${manifest.file}" tofile="${tmp.manifest.file}"/>
<copy encoding="${manifest.encoding}" file="${manifest.file}" outputencoding="UTF-8" tofile="${tmp.manifest.file}"/>
</target>
<target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
<manifest file="${tmp.manifest.file}" mode="update">
<manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
<attribute name="Main-Class" value="${main.class}"/>
</manifest>
</target>
<target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
<manifest file="${tmp.manifest.file}" mode="update">
<manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
<attribute name="Profile" value="${javac.profile}"/>
</manifest>
</target>
@ -991,7 +992,7 @@ is divided into following sections:
<basename file="${application.splash}" property="splashscreen.basename"/>
<mkdir dir="${build.classes.dir}/META-INF"/>
<copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
<manifest file="${tmp.manifest.file}" mode="update">
<manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
<attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
</manifest>
</target>
@ -1186,7 +1187,7 @@ is divided into following sections:
<target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
<startprofiler/>
<antcal target="run-test-with-main"/>
<antcall target="run-test-with-main"/>
</target>
<target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
<fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>

View File

@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=8064a381@1.79.1.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=f0bf6c4b
nbproject/build-impl.xml.script.CRC32=b8db7136
nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48
nbproject/build-impl.xml.script.CRC32=ca4555e3
nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48

View File

@ -24,6 +24,12 @@
<version>1.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.javaheatmap</groupId>
<artifactId>jheatchart</artifactId>
<version>0.6</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<defaultGoal>clean package install</defaultGoal>

View File

@ -8,6 +8,7 @@ import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
* @author Rsl1122
*/
public enum Phrase {
CONFIG_HEADER("Plan Config | More info at https://www.spigotmc.org/wiki/plan-configuration/"),
DATABASE_TYPE_DOES_NOT_EXIST("That database type doesn't exist."),
DATABASE_FAILURE_DISABLE("Database initialization has failed, disabling Plan."),
PLANLITE_REG_HOOK("Registered additional hook, passed on to PlanLite: "),

View File

@ -17,19 +17,19 @@ import java.util.HashSet;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitRunnable;
/* TODO 2.1.0
Placeholder API
Immutable InspectCache ?
Recent players
Optimize db with batch processing (commanduse, ips, nicks)
Recent players 25%
Optimize db with batch processing (commanduse, ips, nicks)
Manage command
Database cleaning
PlanLite Top 20 richest
PlanLite Top 20 most votes
Top 20 most active
PlanLite Top 20 richest 25%
PlanLite Top 20 most votes 25%
Top 20 most active 25%
Clear setting multiper (InspectCache)
Clear check for existing clear task. (InspectCache)
*/
@ -63,31 +63,20 @@ public class Plan extends JavaPlugin {
databases.add(new MySQLDB(this));
databases.add(new SQLiteDB(this));
// for (Database database : databases) {
// String name = database.getConfigName();
//
// ConfigurationSection section = getConfig().getConfigurationSection(name);
//
// if (section == null) {
// section = getConfig().createSection(name);
// }
//
// database.getConfigDefaults(section);
//
// if (section.getKeys(false).isEmpty()) {
// getConfig().set(name, null);
// }
// }
getConfig().options().copyDefaults(true);
getConfig().options().header("Plan Config | More info at https://www.spigotmc.org/wiki/plan-configuration/");
getConfig().options().header(Phrase.CONFIG_HEADER + "");
saveConfig();
log("Database init..");
initDatabase();
log("Database initiated.");
if (initDatabase()) {
log("Database initiated.");
} else {
logError(Phrase.DATABASE_FAILURE_DISABLE.toString());
getServer().getPluginManager().disablePlugin(this);
return;
}
hookPlanLite();
this.handler = new DataCacheHandler(this);
@ -183,12 +172,12 @@ public class Plan extends JavaPlugin {
}
private void registerListeners() {
getServer().getPluginManager().registerEvents(new PlanChatListener(this), this);
getServer().getPluginManager().registerEvents(new PlanPlayerListener(this), this);
getServer().getPluginManager().registerEvents(new PlanGamemodeChangeListener(this), this);
getServer().getPluginManager().registerEvents(new PlanCommandPreprocessListener(this), this);
// Locations Removed from Build 2.0.0 for performance reasons.
// getServer().getPluginManager().registerEvents(new PlanPlayerMoveListener(this), this);
final PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new PlanChatListener(this), this);
pluginManager.registerEvents(new PlanPlayerListener(this), this);
pluginManager.registerEvents(new PlanGamemodeChangeListener(this), this);
pluginManager.registerEvents(new PlanCommandPreprocessListener(this), this);
pluginManager.registerEvents(new PlanPlayerMoveListener(this), this);
}
private boolean initDatabase() {

View File

@ -36,10 +36,10 @@ public class UserData {
private boolean isOp;
private boolean isBanned;
private DemographicsData demData;
private boolean planLiteFound;
private PlanLitePlayerData planLiteData;
private String name;
private boolean isOnline;
@ -60,7 +60,10 @@ public class UserData {
gmTimes.put(GameMode.SURVIVAL, zero);
gmTimes.put(GameMode.CREATIVE, zero);
gmTimes.put(GameMode.ADVENTURE, zero);
gmTimes.put(GameMode.SPECTATOR, zero);
try {
gmTimes.put(GameMode.SPECTATOR, zero);
} catch (NoSuchFieldError e) {
}
lastGamemode = player.getGameMode();
this.demData = demData;
isBanned = player.isBanned();
@ -84,7 +87,10 @@ public class UserData {
gmTimes.put(GameMode.SURVIVAL, zero);
gmTimes.put(GameMode.CREATIVE, zero);
gmTimes.put(GameMode.ADVENTURE, zero);
gmTimes.put(GameMode.SPECTATOR, zero);
try {
gmTimes.put(GameMode.SPECTATOR, zero);
} catch (NoSuchFieldError e) {
}
this.demData = demData;
isBanned = player.isBanned();
name = player.getName();
@ -102,18 +108,15 @@ public class UserData {
}
public void addLocation(Location loc) {
// locations.add(loc);
locations.add(loc);
location = loc;
}
@Deprecated
public void addLocations(Collection<Location> addLocs) {
/*
locations.addAll(addLocs);
if (!locations.isEmpty()) {
location = locations.get(locations.size() - 1);
}
*/
}
public void addNickname(String nick) {
@ -135,7 +138,10 @@ public class UserData {
gmTimes.put(GameMode.SURVIVAL, survivalTime);
gmTimes.put(GameMode.CREATIVE, creativeTime);
gmTimes.put(GameMode.ADVENTURE, adventureTime);
gmTimes.put(GameMode.SPECTATOR, spectatorTime);
try {
gmTimes.put(GameMode.SPECTATOR, spectatorTime);
} catch (NoSuchFieldError e) {
}
}
public void updateBanned(Player p) {
@ -151,7 +157,6 @@ public class UserData {
}
// Getters -------------------------------------------------------------
public boolean isPlanLiteFound() {
return planLiteFound;
}
@ -167,17 +172,15 @@ public class UserData {
public void setPlanLiteData(PlanLitePlayerData planLiteData) {
this.planLiteData = planLiteData;
}
public UUID getUuid() {
return uuid;
}
@Deprecated
public Location getLocation() {
return location;
}
@Deprecated
public List<Location> getLocations() {
return locations;
}
@ -314,6 +317,5 @@ public class UserData {
public boolean isOnline() {
return isOnline;
}
}

View File

@ -4,8 +4,10 @@ import com.djrapitops.plan.Plan;
import com.djrapitops.plan.database.Database;
import com.djrapitops.plan.data.*;
import com.djrapitops.plan.data.handlers.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
@ -147,9 +149,9 @@ public class DataCacheHandler {
* Saves all data in the cache to Database with AsyncTasks
*/
public void saveCachedUserData() {
dataCache.keySet().stream().forEach((uuid) -> {
saveCachedData(uuid);
});
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
db.saveMultipleUserData(data);
timesSaved++;
}
@ -157,11 +159,14 @@ public class DataCacheHandler {
* Saves all data in the cache to Database and closes the database down.
*/
public void saveCacheOnDisable() {
dataCache.keySet().stream().forEach((uuid) -> {
if (dataCache.get(uuid) != null) {
db.saveUserData(uuid, dataCache.get(uuid));
}
});
// dataCache.keySet().stream().forEach((uuid) -> {
// if (dataCache.get(uuid) != null) {
// db.saveUserData(uuid, dataCache.get(uuid));
// }
// });
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
db.saveMultipleUserData(data);
db.saveServerData(serverData);
db.close();
}

View File

@ -49,6 +49,12 @@ public abstract class Database {
*/
public abstract void saveUserData(UUID uuid, UserData data);
/**
* Saves multiple UserData to the Database using batch processing.
* @param data List of Data
*/
public abstract void saveMultipleUserData(List<UserData> data);
/**
* Check if the player is found in the database.
*

View File

@ -155,10 +155,10 @@ public abstract class SQLDB extends Database {
return false;
}
ResultSet set = connection.prepareStatement(supportsModification ? ("SHOW TABLES LIKE '" + userName + "'") : "SELECT name FROM sqlite_master WHERE type='table' AND name='" + userName + "'").executeQuery();
// ResultSet set = connection.prepareStatement(supportsModification ? ("SHOW TABLES LIKE '" + userName + "'") : "SELECT name FROM sqlite_master WHERE type='table' AND name='" + userName + "'").executeQuery();
// boolean newDatabase = set.next();
set.close();
// set.close();
query("CREATE TABLE IF NOT EXISTS " + userName + " ("
+ userColumnID + " integer PRIMARY KEY, "
@ -173,7 +173,7 @@ public abstract class SQLDB extends Database {
+ userColumnLastPlayed + " bigint NOT NULL"
+ ")"
);
/* Locations Removed from Build 2.0.0 for performance reasons.
query("CREATE TABLE IF NOT EXISTS " + locationName + " ("
+ locationColumnID + " integer PRIMARY KEY, "
+ locationColumnUserID + " integer NOT NULL, "
@ -183,7 +183,7 @@ public abstract class SQLDB extends Database {
+ "FOREIGN KEY(" + locationColumnUserID + ") REFERENCES " + userName + "(" + userColumnID + ")"
+ ")"
);
*/
query("CREATE TABLE IF NOT EXISTS " + gamemodetimesName + " ("
+ gamemodetimesColumnUserID + " integer NOT NULL, "
+ gamemodetimesColumnSurvivalTime + " bigint NOT NULL, "
@ -308,109 +308,6 @@ public abstract class SQLDB extends Database {
return userId;
}
@Override
public UserData getUserData(UUID uuid) {
checkConnection();
// Check if user is in the database
if (!wasSeenBefore(uuid)) {
return null;
}
List<World> worldList = Bukkit.getServer().getWorlds();
World defaultWorld = worldList.get(0);
HashMap<String, World> worlds = new HashMap<>();
for (World w : worldList) {
worlds.put(w.getName(), w);
}
// Get the data
UserData data = new UserData(getOfflinePlayer(uuid), new DemographicsData(), this);
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + userName + " WHERE UPPER(" + userColumnUUID + ") LIKE UPPER(?)");
statement.setString(1, uuid.toString());
ResultSet set = statement.executeQuery();
while (set.next()) {
data.getDemData().setAge(set.getInt(userColumnDemAge));
data.getDemData().setGender(Gender.parse(set.getString(userColumnDemGender)));
data.getDemData().setGeoLocation(set.getString(userColumnDemGeoLocation));
data.setLastGamemode(GameMode.valueOf(set.getString(userColumnLastGM)));
data.setLastGmSwapTime(set.getLong(userColumnLastGMSwapTime));
data.setPlayTime(set.getLong(userColumnPlayTime));
data.setLoginTimes(set.getInt(userColumnLoginTimes));
data.setLastPlayed(set.getLong(userColumnLastPlayed));
}
set.close();
statement.close();
String userId = "" + getUserId(uuid.toString());
/* Locations Removed from Build 2.0.0 for performance reasons.
statement = connection.prepareStatement("SELECT * FROM " + locationName + " WHERE UPPER(" + locationColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
List<Location> locations = new ArrayList<>();
while (set.next()) {
locations.add(new Location(worlds.get(set.getString(locationColumnWorld)), set.getInt(locationColumnCoordinatesX), 0, set.getInt(locationColumnCoordinatesZ)));
}
set.close();
statement.close();
data.addLocations(locations);
if (locations.isEmpty()) {
data.setLocation(new Location(defaultWorld, 0, 0, 0));
} else {
data.setLocation(locations.get(locations.size() - 1));
}
*/
data.setLocation(new Location(defaultWorld, 0, 0, 0));
statement = connection.prepareStatement("SELECT * FROM " + nicknamesName + " WHERE UPPER(" + nicknamesColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
List<String> nicknames = new ArrayList<>();
while (set.next()) {
nicknames.add(set.getString(nicknamesColumnNick));
}
set.close();
statement.close();
data.addNicknames(nicknames);
statement = connection.prepareStatement("SELECT * FROM " + ipsName + " WHERE UPPER(" + ipsColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
List<InetAddress> ips = new ArrayList<>();
while (set.next()) {
try {
ips.add(InetAddress.getByName(set.getString(ipsColumnIP)));
} catch (SQLException | UnknownHostException e) {
}
}
set.close();
statement.close();
data.addIpAddresses(ips);
statement = connection.prepareStatement("SELECT * FROM " + gamemodetimesName + " WHERE UPPER(" + gamemodetimesColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
HashMap<GameMode, Long> times = new HashMap<>();
while (set.next()) {
times.put(GameMode.SURVIVAL, set.getLong(gamemodetimesColumnSurvivalTime));
times.put(GameMode.CREATIVE, set.getLong(gamemodetimesColumnCreativeTime));
times.put(GameMode.ADVENTURE, set.getLong(gamemodetimesColumnAdventureTime));
times.put(GameMode.SPECTATOR, set.getLong(gamemodetimesColumnSpectatorTime));
}
set.close();
statement.close();
data.setGmTimes(times);
} catch (SQLException e) {
data = null;
e.printStackTrace();
}
return data;
}
@Override
public HashMap<Long, ServerData> getServerDataHashMap() {
HashMap<String, Integer> commandUse = getCommandUse();
@ -487,17 +384,21 @@ public abstract class SQLDB extends Database {
"DELETE FROM " + commanduseName);
statement.execute();
statement.close();
for (String key : data.keySet()) {
statement = connection.prepareStatement("INSERT INTO " + commanduseName + " ("
+ commanduseColumnCommand + ", "
+ commanduseColumnTimesUsed
+ ") VALUES (?, ?)");
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + commanduseName + " ("
+ commanduseColumnCommand + ", "
+ commanduseColumnTimesUsed
+ ") VALUES (?, ?)");
for (String key : data.keySet()) {
statement.setString(1, key);
statement.setInt(2, data.get(key));
statement.execute();
statement.close();
statement.addBatch();
}
statement.executeBatch();
connection.commit();
statement.close();
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
@ -536,12 +437,12 @@ public abstract class SQLDB extends Database {
statement.setString(1, uuid);
statement.execute();
statement.close();
/* Locations Removed from Build 2.0.0 for performance reasons.
statement = connection.prepareStatement("DELETE FROM " + locationName + " WHERE UPPER(" + locationColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, "" + userId);
statement.execute();
statement.close();
*/
statement = connection.prepareStatement("DELETE FROM " + nicknamesName + " WHERE UPPER(" + nicknamesColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, "" + userId);
statement.execute();
@ -559,6 +460,171 @@ public abstract class SQLDB extends Database {
}
}
@Override
public UserData getUserData(UUID uuid) {
checkConnection();
// Check if user is in the database
if (!wasSeenBefore(uuid)) {
plugin.logError(uuid + " was not found from the database!");
return null;
}
List<World> worldList = Bukkit.getServer().getWorlds();
World defaultWorld = worldList.get(0);
HashMap<String, World> worlds = new HashMap<>();
for (World w : worldList) {
worlds.put(w.getName(), w);
}
// Get the data
UserData data = new UserData(getOfflinePlayer(uuid), new DemographicsData(), this);
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + userName + " WHERE UPPER(" + userColumnUUID + ") LIKE UPPER(?)");
statement.setString(1, uuid.toString());
ResultSet set = statement.executeQuery();
while (set.next()) {
data.getDemData().setAge(set.getInt(userColumnDemAge));
data.getDemData().setGender(Gender.parse(set.getString(userColumnDemGender)));
data.getDemData().setGeoLocation(set.getString(userColumnDemGeoLocation));
data.setLastGamemode(GameMode.valueOf(set.getString(userColumnLastGM)));
data.setLastGmSwapTime(set.getLong(userColumnLastGMSwapTime));
data.setPlayTime(set.getLong(userColumnPlayTime));
data.setLoginTimes(set.getInt(userColumnLoginTimes));
data.setLastPlayed(set.getLong(userColumnLastPlayed));
}
set.close();
statement.close();
String userId = "" + getUserId(uuid.toString());
statement = connection.prepareStatement("SELECT * FROM " + locationName + " WHERE UPPER(" + locationColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
List<Location> locations = new ArrayList<>();
while (set.next()) {
locations.add(new Location(worlds.get(set.getString(locationColumnWorld)), set.getInt(locationColumnCoordinatesX), 0, set.getInt(locationColumnCoordinatesZ)));
}
set.close();
statement.close();
data.addLocations(locations);
if (locations.isEmpty()) {
data.setLocation(new Location(defaultWorld, 0, 0, 0));
} else {
data.setLocation(locations.get(locations.size() - 1));
}
data.setLocation(new Location(defaultWorld, 0, 0, 0));
statement = connection.prepareStatement("SELECT * FROM " + nicknamesName + " WHERE UPPER(" + nicknamesColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
List<String> nicknames = new ArrayList<>();
while (set.next()) {
nicknames.add(set.getString(nicknamesColumnNick));
}
set.close();
statement.close();
data.addNicknames(nicknames);
statement = connection.prepareStatement("SELECT * FROM " + ipsName + " WHERE UPPER(" + ipsColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
List<InetAddress> ips = new ArrayList<>();
while (set.next()) {
try {
ips.add(InetAddress.getByName(set.getString(ipsColumnIP)));
} catch (SQLException | UnknownHostException e) {
}
}
set.close();
statement.close();
data.addIpAddresses(ips);
statement = connection.prepareStatement("SELECT * FROM " + gamemodetimesName + " WHERE UPPER(" + gamemodetimesColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, userId);
set = statement.executeQuery();
HashMap<GameMode, Long> times = new HashMap<>();
while (set.next()) {
times.put(GameMode.SURVIVAL, set.getLong(gamemodetimesColumnSurvivalTime));
times.put(GameMode.CREATIVE, set.getLong(gamemodetimesColumnCreativeTime));
times.put(GameMode.ADVENTURE, set.getLong(gamemodetimesColumnAdventureTime));
try {
times.put(GameMode.SPECTATOR, set.getLong(gamemodetimesColumnSpectatorTime));
} catch (NoSuchFieldError e) {
}
}
set.close();
statement.close();
data.setGmTimes(times);
} catch (SQLException e) {
data = null;
e.printStackTrace();
}
return data;
}
@Override
public void saveMultipleUserData(List<UserData> data) {
List<UserData> saveLast = new ArrayList<>();
String uSQL = "UPDATE " + userName + " SET "
+ userColumnDemAge + "=?, "
+ userColumnDemGender + "=?, "
+ userColumnDemGeoLocation + "=?, "
+ userColumnLastGM + "=?, "
+ userColumnLastGMSwapTime + "=?, "
+ userColumnPlayTime + "=?, "
+ userColumnLoginTimes + "=?, "
+ userColumnLastPlayed + "=? "
+ "WHERE UPPER(" + userColumnUUID + ") LIKE UPPER(?)";
try {
connection.setAutoCommit(false);
PreparedStatement uStatement = connection.prepareStatement(uSQL);
for (UserData uData : data) {
int userId = getUserId(uData.getUuid().toString());
if (userId == -1) {
saveLast.add(uData);
continue;
}
uStatement.setInt(1, uData.getDemData().getAge());
uStatement.setString(2, uData.getDemData().getGender().toString().toLowerCase());
uStatement.setString(3, uData.getDemData().getGeoLocation());
GameMode gm = uData.getLastGamemode();
if (gm != null) {
uStatement.setString(4, uData.getLastGamemode().name());
} else {
uStatement.setString(4, GameMode.SURVIVAL.name());
}
uStatement.setLong(5, uData.getLastGmSwapTime());
uStatement.setLong(6, uData.getPlayTime());
uStatement.setInt(7, uData.getLoginTimes());
uStatement.setLong(8, uData.getLastPlayed());
uStatement.setString(9, uData.getUuid().toString());
uStatement.addBatch();
}
uStatement.executeBatch();
connection.commit();
uStatement.close();
connection.setAutoCommit(true);
data.removeAll(saveLast);
for (UserData uData : data) {
int userId = getUserId(uData.getUuid().toString());
saveLocationList(userId, uData.getLocations());
saveNickList(userId, uData.getNicknames());
saveIPList(userId, uData.getIps());
saveGMTimes(userId, uData.getGmTimes());
}
for (UserData userData : saveLast) {
saveUserData(userData.getUuid(), userData);
}
} catch (SQLException | NullPointerException e) {
e.printStackTrace();
}
}
@Override
public void saveUserData(UUID uuid, UserData data) {
checkConnection();
@ -627,7 +693,7 @@ public abstract class SQLDB extends Database {
statement.close();
userId = getUserId(uuid.toString());
}
// saveLocationList(userId, data.getLocations());
saveLocationList(userId, data.getLocations());
saveNickList(userId, data.getNicknames());
saveIPList(userId, data.getIps());
saveGMTimes(userId, data.getGmTimes());
@ -638,37 +704,34 @@ public abstract class SQLDB extends Database {
data.setAccessing(false);
}
@Deprecated // Locations Removed from Build 2.0.0 for performance reasons.
public void saveLocationList(int userId, List<Location> locations) {
/*
try {
PreparedStatement statement = connection.prepareStatement(
PreparedStatement deleteStatement = connection.prepareStatement(
"DELETE FROM " + locationName + " WHERE UPPER(" + locationColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, "" + userId);
statement.execute();
statement.close();
deleteStatement.setString(1, "" + userId);
deleteStatement.execute();
deleteStatement.close();
connection.setAutoCommit(false);
PreparedStatement saveStatement = connection.prepareStatement("INSERT INTO " + locationName + " ("
+ locationColumnUserID + ", "
+ locationColumnCoordinatesX + ", "
+ locationColumnCoordinatesZ + ", "
+ locationColumnWorld
+ ") VALUES (?, ?, ?, ?)");
for (Location location : locations) {
PreparedStatement saveStatement = connection.prepareStatement("INSERT INTO " + locationName + " ("
+ locationColumnUserID + ", "
+ locationColumnCoordinatesX + ", "
+ locationColumnCoordinatesZ + ", "
+ locationColumnWorld
+ ") VALUES (?, ?, ?, ?)");
saveStatement.setInt(1, userId);
saveStatement.setInt(2, (int) location.getBlockX());
saveStatement.setInt(3, (int) location.getBlockZ());
saveStatement.setString(4, location.getWorld().getName());
saveStatement.execute();
saveStatement.close();
saveStatement.addBatch();
}
saveStatement.executeBatch();
connection.commit();
saveStatement.close();
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
}
*/
}
public void saveNickList(int userId, HashSet<String> names) {
@ -678,17 +741,20 @@ public abstract class SQLDB extends Database {
statement.setString(1, "" + userId);
statement.execute();
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + nicknamesName + " ("
+ nicknamesColumnUserID + ", "
+ nicknamesColumnNick
+ ") VALUES (?, ?)");
for (String name : names) {
statement = connection.prepareStatement("INSERT INTO " + nicknamesName + " ("
+ nicknamesColumnUserID + ", "
+ nicknamesColumnNick
+ ") VALUES (?, ?)");
statement.setInt(1, userId);
statement.setString(2, name);
statement.execute();
statement.close();
statement.addBatch();
}
statement.executeBatch();
connection.commit();
statement.close();
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
@ -703,17 +769,20 @@ public abstract class SQLDB extends Database {
statement.execute();
statement.close();
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + ipsName + " ("
+ ipsColumnUserID + ", "
+ ipsColumnIP
+ ") VALUES (?, ?)");
for (InetAddress ip : ips) {
statement = connection.prepareStatement("INSERT INTO " + ipsName + " ("
+ ipsColumnUserID + ", "
+ ipsColumnIP
+ ") VALUES (?, ?)");
statement.setInt(1, userId);
statement.setString(2, ip.getHostAddress());
statement.execute();
statement.close();
statement.addBatch();
}
statement.executeBatch();
connection.commit();
statement.close();
connection.setAutoCommit(true);
} catch (SQLException e) {
e.printStackTrace();
@ -740,7 +809,16 @@ public abstract class SQLDB extends Database {
statement.setLong(2, gamemodeTimes.get(GameMode.SURVIVAL));
statement.setLong(3, gamemodeTimes.get(GameMode.CREATIVE));
statement.setLong(4, gamemodeTimes.get(GameMode.ADVENTURE));
statement.setLong(5, gamemodeTimes.get(GameMode.SPECTATOR));
try {
Long gm = gamemodeTimes.get(GameMode.SPECTATOR);
if (gm != null) {
statement.setLong(5, gm);
} else {
statement.setLong(5, 0);
}
} catch (NoSuchFieldError e) {
statement.setLong(5, 0);
}
statement.execute();
statement.close();
@ -901,151 +979,4 @@ public abstract class SQLDB extends Database {
return connection;
}
public String getUserName() {
return userName;
}
public String getLocationName() {
return locationName;
}
public String getServerdataName() {
return serverdataName;
}
public String getCommanduseName() {
return commanduseName;
}
public String getGamemodetimesName() {
return gamemodetimesName;
}
public String getNicknamesName() {
return nicknamesName;
}
public String getIpsName() {
return ipsName;
}
public String getUserColumnUUID() {
return userColumnUUID;
}
public String getUserColumnID() {
return userColumnID;
}
public String getUserColumnPlayTime() {
return userColumnPlayTime;
}
public String getUserColumnDemGeoLocation() {
return userColumnDemGeoLocation;
}
public String getUserColumnDemAge() {
return userColumnDemAge;
}
public String getUserColumnDemGender() {
return userColumnDemGender;
}
public String getUserColumnLastGM() {
return userColumnLastGM;
}
public String getUserColumnLastGMSwapTime() {
return userColumnLastGMSwapTime;
}
public String getUserColumnLoginTimes() {
return userColumnLoginTimes;
}
public String getUserColumnLastPlayed() {
return userColumnLastPlayed;
}
public String getLocationColumnUserID() {
return locationColumnUserID;
}
public String getLocationColumnID() {
return locationColumnID;
}
public String getLocationColumnCoordinatesX() {
return locationColumnCoordinatesX;
}
public String getLocationColumnCoordinatesZ() {
return locationColumnCoordinatesZ;
}
public String getLocationColumnWorld() {
return locationColumnWorld;
}
public String getServerdataColumnDate() {
return serverdataColumnDate;
}
public String getServerdataColumnPlayersOnline() {
return serverdataColumnPlayersOnline;
}
public String getServerdataColumnNewPlayers() {
return serverdataColumnNewPlayers;
}
public String getCommanduseColumnCommand() {
return commanduseColumnCommand;
}
public String getCommanduseColumnTimesUsed() {
return commanduseColumnTimesUsed;
}
public String getGamemodetimesColumnUserID() {
return gamemodetimesColumnUserID;
}
public String getGamemodetimesColumnSurvivalTime() {
return gamemodetimesColumnSurvivalTime;
}
public String getGamemodetimesColumnCreativeTime() {
return gamemodetimesColumnCreativeTime;
}
public String getGamemodetimesColumnAdventureTime() {
return gamemodetimesColumnAdventureTime;
}
public String getGamemodetimesColumnSpectatorTime() {
return gamemodetimesColumnSpectatorTime;
}
public String getNicknamesColumnUserID() {
return nicknamesColumnUserID;
}
public String getNicknamesColumnNick() {
return nicknamesColumnNick;
}
public String getIpsColumnUserID() {
return ipsColumnUserID;
}
public String getIpsColumnIP() {
return ipsColumnIP;
}
public String getVersionName() {
return versionName;
}
}

View File

@ -24,8 +24,17 @@ public class GMTimesPieChartCreator {
* @return Url of charts4j image link.
*/
public static String createChart(HashMap<GameMode, Long> gmTimes) {
Long gm3;
try {
gm3 = gmTimes.get(GameMode.SPECTATOR);
if (gm3 == null) {
gm3 = (long) 0;
}
} catch (NoSuchFieldError e) {
gm3 = (long) 0;
}
long total = gmTimes.get(GameMode.SURVIVAL) + gmTimes.get(GameMode.CREATIVE)
+ gmTimes.get(GameMode.ADVENTURE) + gmTimes.get(GameMode.SPECTATOR);
+ gmTimes.get(GameMode.ADVENTURE) + gm3;
return createChart(gmTimes, total);
}
@ -42,7 +51,15 @@ public class GMTimesPieChartCreator {
long gmZero = gmTimes.get(GameMode.SURVIVAL);
long gmOne = gmTimes.get(GameMode.CREATIVE);
long gmTwo = gmTimes.get(GameMode.ADVENTURE);
long gmThree = gmTimes.get(GameMode.SPECTATOR);
Long gmThree;
try {
gmThree = gmTimes.get(GameMode.SPECTATOR);
if (gmThree == null) {
gmThree = (long) 0;
}
} catch (NoSuchFieldError e) {
gmThree = (long) 0;
}
int zero = (int) ((gmZero * 1.0 / total) * 100);
int one = (int) ((gmOne * 1.0 / total) * 100);
int two = (int) ((gmTwo * 1.0 / total) * 100);

View File

@ -0,0 +1,52 @@
package main.java.com.djrapitops.plan.ui.graphs;
import com.djrapitops.plan.Plan;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.tc33.jheatchart.HeatChart;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class HeatMapCreator {
public static String createLocationHeatmap(List<Location> locations) {
double[][] data = new double[1000][1000];
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 1000; j++) {
data[i][j] = 0;
}
}
for (Location loc : locations) {
int x = loc.getBlockX()+500;
int z = loc.getBlockZ()+500;
if (x < 0 || x > 1000) {
continue;
}
if (z < 0 || z > 1000) {
continue;
}
data[x][z] = data[x][z] + 1;
}
HeatChart map = new HeatChart(data);
map.setTitle("Location heatmap.");
map.setXAxisLabel("X");
map.setYAxisLabel("Z");
try {
String folder = getPlugin(Plan.class).getDataFolder().getAbsolutePath()+File.separator+"Heatmaps";
map.saveToFile(new File(folder + File.separator+"java-heat-chart.png"));
} catch (IOException ex) {
Logger.getLogger(HeatMapCreator.class.getName()).log(Level.SEVERE, null, ex);
}
return "";
}
}

View File

@ -14,6 +14,7 @@ import java.util.List;
import java.util.UUID;
import main.java.com.djrapitops.plan.data.PlanLiteAnalyzedData;
import main.java.com.djrapitops.plan.data.PlanLitePlayerData;
import main.java.com.djrapitops.plan.ui.graphs.HeatMapCreator;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import org.bukkit.scheduler.BukkitRunnable;
@ -113,7 +114,7 @@ public class Analysis {
int ops = 0;
List<Integer> ages = new ArrayList<>();
boolean planLiteEnabled;
PlanLiteHook planLiteHook = plugin.getPlanLiteHook();
if (planLiteHook != null) {
@ -149,7 +150,13 @@ public class Analysis {
gmZero += gmTimes.get(GameMode.SURVIVAL);
gmOne += gmTimes.get(GameMode.CREATIVE);
gmTwo += gmTimes.get(GameMode.ADVENTURE);
gmThree += gmTimes.get(GameMode.SPECTATOR);
try {
Long gm = gmTimes.get(GameMode.SPECTATOR);
if (gm != null) {
gmThree += gm;
}
} catch (NoSuchFieldError e) {
}
totalPlaytime += uData.getPlayTime();
totalLoginTimes += uData.getLoginTimes();
int age = uData.getDemData().getAge();
@ -213,7 +220,10 @@ public class Analysis {
totalGmTimes.put(GameMode.SURVIVAL, gmZero);
totalGmTimes.put(GameMode.CREATIVE, gmOne);
totalGmTimes.put(GameMode.ADVENTURE, gmTwo);
totalGmTimes.put(GameMode.SPECTATOR, gmThree);
try {
totalGmTimes.put(GameMode.SPECTATOR, gmThree);
} catch (NoSuchFieldError e) {
}
String serverGMChartHtml = AnalysisUtils.createGMPieChart(totalGmTimes, gmTotal);
data.setGmTimesChartImgHtml(serverGMChartHtml);
data.setGm0Perc((gmZero * 1.0 / gmTotal));

View File

@ -73,7 +73,16 @@ public class AnalysisUtils {
long gmZero = gmTimes.get(GameMode.SURVIVAL);
long gmOne = gmTimes.get(GameMode.CREATIVE);
long gmTwo = gmTimes.get(GameMode.ADVENTURE);
long gmThree = gmTimes.get(GameMode.SPECTATOR);
long gmThree;
try {
Long gm3 = gmTimes.get(GameMode.SPECTATOR);
if (gm3 == null) {
gm3 = (long) 0;
}
gmThree = gm3;
} catch (NoSuchFieldError e) {
gmThree = 0;
}
long total = gmZero + gmOne + gmTwo + gmThree;
replaceMap.put("%gm0%", FormatUtils.formatTimeAmount("" + gmZero));
replaceMap.put("%gm1%", FormatUtils.formatTimeAmount("" + gmOne));

View File

@ -28,6 +28,9 @@
%playerchartweek%
<h4>Player Activity - Last 30 days</h4>
%playerchartmonth%
<p>Recent logins: %recentlogins%</p>
<br/><h4>Top 20 Most Active</h4>
%top20mostactive%
</td>
<td style="margin-left: 3px; margin-right: auto;
border-style: groove; border-width: 3px; border-radius: 12px; padding: 2px 4px 2px 3px;

View File

@ -4,6 +4,10 @@
<h4>Information from PlanLite</h4>
%totalmoneyline%
%totalvotesline%
<br/><h4>Richest Players</h4>
%top10richest%
<br/><h4>Top Voters</h4>
%top10votes%
</td>
<td style="margin-left: 3px; margin-right: auto;border-style: groove; border-width: 3px;
border-radius: 12px; padding: 2px 4px 2px 3px; box-shadow: 5px 5px 4px 0px #888888;">