[2.7.2] Bugfixes & Optimization

Fix for #31 #30 #29 #28
Possible fix for #26
This commit is contained in:
Rsl1122 2017-02-27 14:08:19 +02:00
parent a820da3261
commit 75e1cf3e85
20 changed files with 464 additions and 256 deletions

View File

@ -32,6 +32,10 @@ public enum Phrase {
DB_FAILURE_DISABLE("Database initialization has failed, disabling Plan."),
NOTIFY_EMPTY_IP(ChatColor.YELLOW + "" + PREFIX + "IP in server.properties is empty & AlternativeServerIP is not used, incorrect links will be given!"),
//
CACHE_SAVETASK_DISABLED("Attempted to schedule data for save after task was shut down."),
CACHE_GETTASK_DISABLED("Attempted to schedule data grab after task was shut down."),
CACHE_CLEARTASK_DISABLED("Attempted to schedule data for clear after task was shut down."),
//
VERSION_NEW_AVAILABLE("New Version (" + REPLACE0 + ") is availible at https://www.spigotmc.org/resources/plan-player-analytics.32536/"),
VERSION_LATEST("You're running the latest version"),
VERSION_CHECK_ERROR("Failed to compare versions."),

View File

@ -51,7 +51,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
/* TODO 2.6.0
/* TODO
Placeholder API
Play session length
- Playtime month

View File

@ -85,7 +85,7 @@ public class ManageRemoveCommand extends SubCommand {
public void run() {
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
try {
plugin.getHandler().clearFromCache(uuid);
plugin.getHandler().scheludeForClear(uuid);
if (plugin.getDB().removeAccount(uuid.toString())) {
sender.sendMessage(Phrase.MANAGE_REMOVE_SUCCESS.parse(playerName, plugin.getDB().getConfigName()));
} else {

View File

@ -0,0 +1,95 @@
package main.java.com.djrapitops.plan.data.cache;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import main.java.com.djrapitops.plan.Plan;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class DataCacheClearQueue {
private BlockingQueue<UUID> q;
private ClearSetup s;
public DataCacheClearQueue(Plan plugin, DataCacheHandler handler) {
q = new ArrayBlockingQueue(1000);
s = new ClearSetup();
s.go(q, handler);
}
public void scheduleForClear(UUID uuid) {
q.add(uuid);
}
public void scheduleForClear(Collection<UUID> uuids) {
q.addAll(uuids);
}
public void stop() {
s.stop();
}
}
class ClearConsumer implements Runnable {
private final BlockingQueue<UUID> queue;
private final DataCacheHandler handler;
private boolean run;
ClearConsumer(BlockingQueue q, DataCacheHandler handler) {
queue = q;
this.handler = handler;
run = true;
}
@Override
public void run() {
try {
while (run) {
consume(queue.take());
}
} catch (InterruptedException ex) {
}
}
void consume(UUID uuid) {
try {
if (handler.isDataAccessed(uuid)) {
queue.add(uuid);
} else if (!getOfflinePlayer(uuid).isOnline()) {
handler.clearFromCache(uuid);
}
// if online remove from clear list
} catch (Exception ex) {
getPlugin(Plan.class).toLog(this.getClass().getName(), ex);
}
}
void stop() {
run = false;
}
}
class ClearSetup {
private ClearConsumer one;
private ClearConsumer two;
void go(BlockingQueue<UUID> q, DataCacheHandler handler) {
one = new ClearConsumer(q, handler);
two = new ClearConsumer(q, handler);
new Thread(one).start();
new Thread(two).start();
}
void stop() {
one.stop();
two.stop();
}
}

View File

@ -0,0 +1,104 @@
package main.java.com.djrapitops.plan.data.cache;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.database.Database;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class DataCacheGetQueue {
private BlockingQueue<HashMap<UUID, List<DBCallableProcessor>>> q;
private GetSetup s;
public DataCacheGetQueue(Plan plugin) {
q = new ArrayBlockingQueue(1000);
s = new GetSetup();
s.go(q, plugin.getDB());
}
public void scheduleForGet(UUID uuid, DBCallableProcessor... processors) {
HashMap<UUID, List<DBCallableProcessor>> map = new HashMap<>();
if (map.get(uuid) == null) {
map.put(uuid, new ArrayList<>());
}
map.get(uuid).addAll(Arrays.asList(processors));
q.add(map);
}
public void stop() {
s.stop();
}
}
class GetConsumer implements Runnable {
private final BlockingQueue<HashMap<UUID, List<DBCallableProcessor>>> queue;
private final Database db;
private boolean run;
GetConsumer(BlockingQueue q, Database db) {
queue = q;
this.db = db;
run = true;
}
@Override
public void run() {
try {
while (run) {
consume(queue.take());
}
} catch (InterruptedException ex) {
}
}
void consume(HashMap<UUID, List<DBCallableProcessor>> processors) {
try {
for (UUID uuid : processors.keySet()) {
List<DBCallableProcessor> processorsList = processors.get(uuid);
if (processorsList != null) {
try {
db.giveUserDataToProcessors(uuid, processorsList);
} catch (SQLException e) {
getPlugin(Plan.class).toLog(this.getClass().getName(), e);
}
}
}
} catch (Exception ex) {
getPlugin(Plan.class).toLog(this.getClass().getName(), ex);
}
}
void stop() {
run = false;
}
}
class GetSetup {
private GetConsumer one;
private GetConsumer two;
void go(BlockingQueue<HashMap<UUID, List<DBCallableProcessor>>> q, Database db) {
one = new GetConsumer(q, db);
two = new GetConsumer(q, db);
new Thread(one).start();
new Thread(two).start();
}
void stop() {
one.stop();
two.stop();
}
}

View File

@ -1,11 +1,10 @@
package main.java.com.djrapitops.plan.data.cache;
import main.java.com.djrapitops.plan.utilities.NewPlayerCreator;
import java.sql.SQLException;
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 main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
@ -25,21 +24,31 @@ import org.bukkit.scheduler.BukkitTask;
*/
public class DataCacheHandler {
// Cache
private final HashMap<UUID, UserData> dataCache;
private HashMap<String, Integer> commandUse;
// Plan
private final Plan plugin;
private final Database db;
// Handlers
private final ActivityHandler activityHandler;
private final GamemodeTimesHandler gamemodeTimesHandler;
private final LocationHandler locationHandler;
private final DemographicsHandler demographicsHandler;
private final BasicInfoHandler basicInfoHandler;
private final RuleBreakingHandler ruleBreakingHandler;
private HashMap<String, Integer> commandUse;
private CommandUseHandler commandUseHandler;
private final KillHandler killHandler;
private final SessionHandler sessionHandler;
private final Database db;
private final NewPlayerCreator newPlayerCreator;
// Queues
private final DataCacheSaveQueue saveTask;
private final DataCacheClearQueue clearTask;
private final DataCacheGetQueue getTask;
// Variables
private int timesSaved;
private int maxPlayers;
@ -62,10 +71,13 @@ public class DataCacheHandler {
basicInfoHandler = new BasicInfoHandler(plugin, this);
ruleBreakingHandler = new RuleBreakingHandler(plugin, this);
newPlayerCreator = new NewPlayerCreator(plugin, this);
killHandler = new KillHandler(plugin);
sessionHandler = new SessionHandler(plugin);
getTask = new DataCacheGetQueue(plugin);
clearTask = new DataCacheClearQueue(plugin, this);
saveTask = new DataCacheSaveQueue(plugin);
timesSaved = 0;
maxPlayers = plugin.getServer().getMaxPlayers();
try {
@ -114,32 +126,25 @@ public class DataCacheHandler {
* of DataCacheHandler
*/
public void getUserDataForProcessing(DBCallableProcessor processor, UUID uuid, boolean cache) {
BukkitTask asyncCacheTask = (new BukkitRunnable() {
@Override
public void run() {
UserData uData = dataCache.get(uuid);
if (uData == null) {
DBCallableProcessor cacher = new DBCallableProcessor() {
@Override
public void process(UserData data) {
if (cache) {
dataCache.put(uuid, data);
plugin.log(Phrase.CACHE_ADD.parse(uuid.toString()));
}
}
};
try {
db.giveUserDataToProcessors(uuid, cacher, processor);
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
this.cancel();
UserData uData = dataCache.get(uuid);
if (uData == null) {
if (cache) {
DBCallableProcessor cacher = new DBCallableProcessor() {
@Override
public void process(UserData data) {
dataCache.put(uuid, data);
plugin.log(Phrase.CACHE_ADD.parse(uuid.toString()));
}
} else {
processor.process(uData);
}
this.cancel();
};
getTask.scheduleForGet(uuid, cacher, processor);
} else {
getTask.scheduleForGet(uuid, processor);
}
}).runTaskAsynchronously(plugin);
} else {
processor.process(uData);
}
}
/**
@ -155,31 +160,27 @@ public class DataCacheHandler {
}
/**
* Saves all data in the cache to Database with AsyncTasks
* Saves all data in the cache to Database. Should only be called from Async
* thread
*/
public void saveCachedUserData() {
clearNulls();
BukkitTask asyncFullCacheSaveTask = (new BukkitRunnable() {
@Override
public void run() {
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
try {
db.saveMultipleUserData(data);
} catch (SQLException ex) {
plugin.toLog(this.getClass().getName(), ex);
}
timesSaved++;
this.cancel();
}
}).runTaskAsynchronously(plugin);
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
try {
db.saveMultipleUserData(data);
} catch (SQLException ex) {
plugin.toLog(this.getClass().getName(), ex);
}
}
/**
* Saves all data in the cache to Database and closes the database down.
* Closes save clear and get tasks.
*/
public void saveCacheOnDisable() {
clearNulls();
saveTask.stop();
getTask.stop();
clearTask.stop();
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
data.parallelStream().forEach((userData) -> {
@ -200,38 +201,26 @@ public class DataCacheHandler {
* @param uuid Player's UUID
*/
public void saveCachedData(UUID uuid) {
clearNulls();
BukkitTask asyncCachedUserSaveTask = (new BukkitRunnable() {
@Override
public void run() {
if (dataCache.get(uuid) != null) {
try {
db.saveUserData(uuid, dataCache.get(uuid));
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
this.cancel();
}
}).runTaskAsynchronously(plugin);
UserData data = dataCache.get(uuid);
if (data != null) {
saveTask.scheduleForSave(data);
}
}
/**
* Saves the cached ServerData with AsyncTask
* Scheludes the cached CommandUsage to be saved.
*
* Data is saved on a new line with a long value matching current Date
*/
public void saveCommandUse() {
try {
db.saveCommandUse(commandUse);
} catch (SQLException e) {
} catch (SQLException | NullPointerException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
// Should only be called from Async thread
private void saveHandlerDataToCache() {
public void saveHandlerDataToCache() {
Bukkit.getServer().getOnlinePlayers().parallelStream().forEach((p) -> {
saveHandlerDataToCache(p);
});
@ -253,10 +242,7 @@ public class DataCacheHandler {
* Clears all UserData from the HashMap
*/
public void clearCache() {
Iterator<Map.Entry<UUID, UserData>> clearIterator = dataCache.entrySet().iterator();
while (clearIterator.hasNext()) {
clearFromCache(clearIterator.next());
}
clearTask.scheduleForClear(dataCache.keySet());
}
/**
@ -265,54 +251,20 @@ public class DataCacheHandler {
* @param uuid Player's UUID
*/
public void clearFromCache(UUID uuid) {
UserData userData = dataCache.get(uuid);
if (userData != null) {
if (userData.isAccessed()) {
(new BukkitRunnable() {
@Override
public void run() {
if (!userData.isAccessed()) {
dataCache.remove(uuid);
plugin.log("Cleared " + uuid.toString() + " from Cache. (Delay task)");
this.cancel();
}
}
}).runTaskTimer(plugin, 30 * 20, 30 * 20);
} else {
dataCache.remove(uuid);
plugin.log(Phrase.CACHE_REMOVE+"");
}
}
dataCache.remove(uuid);
plugin.log(Phrase.CACHE_REMOVE.parse(uuid.toString()));
}
/**
* Setting entry value to null, clearing it from memory.
*
* This method is used to avoid ConcurrentModificationException when
* clearing the cache.
*
* @param entry An entry from the cache HashMap that is being iterated over.
*/
public void clearFromCache(Map.Entry<UUID, UserData> entry) {
if (entry != null) {
if (entry.getValue() != null) {
if (entry.getValue().isAccessed()) {
(new BukkitRunnable() {
@Override
public void run() {
if (!entry.getValue().isAccessed()) {
entry.setValue(null);
plugin.log("Cleared " + entry.getKey().toString() + " from Cache. (Delay task)");
this.cancel();
}
}
}).runTaskTimer(plugin, 30 * 20, 30 * 20);
} else {
entry.setValue(null);
plugin.log("Cleared " + entry.getKey().toString() + " from Cache.");
}
}
public void scheludeForClear(UUID uuid) {
clearTask.scheduleForClear(uuid);
}
public boolean isDataAccessed(UUID uuid) {
UserData userData = dataCache.get(uuid);
if (userData != null) {
return userData.isAccessed();
}
return false;
}
/**
@ -321,11 +273,11 @@ public class DataCacheHandler {
* @param player Player the new UserData is created for
*/
public void newPlayer(Player player) {
newPlayerCreator.createNewPlayer(player);
saveTask.scheduleNewPlayer(NewPlayerCreator.createNewPlayer(player));
}
public void newPlayer(OfflinePlayer player) {
newPlayerCreator.createNewPlayer(player);
saveTask.scheduleNewPlayer(NewPlayerCreator.createNewPlayer(player));
}
/**
@ -426,14 +378,14 @@ public class DataCacheHandler {
activityHandler.handleReload(data);
basicInfoHandler.handleReload(player.getDisplayName(), player.getAddress().getAddress(), data);
gamemodeTimesHandler.handleReload(player.getGameMode(), data);
saveCachedUserData();
}
};
getUserDataForProcessing(cacheUpdater, player.getUniqueId());
}
this.cancel();
}
}).runTaskAsynchronously(plugin);
saveCachedUserData();
}).runTaskAsynchronously(plugin);
}
/**
@ -444,13 +396,4 @@ public class DataCacheHandler {
public int getMaxPlayers() {
return maxPlayers;
}
private void clearNulls() {
Iterator<UUID> clearIterator = dataCache.keySet().iterator();
while (clearIterator.hasNext()) {
if (dataCache.get(clearIterator.next()) == null) {
clearIterator.remove();
}
}
}
}

View File

@ -0,0 +1,95 @@
package main.java.com.djrapitops.plan.data.cache;
import java.sql.SQLException;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.database.Database;
import static org.bukkit.plugin.java.JavaPlugin.getPlugin;
/**
*
* @author Rsl1122
*/
public class DataCacheSaveQueue {
private BlockingQueue<UserData> q;
private SaveSetup s;
public DataCacheSaveQueue(Plan plugin) {
q = new ArrayBlockingQueue(1000);
s = new SaveSetup();
s.go(q, plugin.getDB());
}
public void scheduleForSave(UserData data) {
q.add(data);
}
public void scheduleForSave(Collection<UserData> data) {
q.addAll(data);
}
public void scheduleNewPlayer(UserData data) {
q.add(data);
}
public void stop() {
s.stop();
}
}
class SaveConsumer implements Runnable {
private final BlockingQueue<UserData> queue;
private final Database db;
private boolean run;
SaveConsumer(BlockingQueue q, Database db) {
queue = q;
this.db = db;
run = true;
}
@Override
public void run() {
try {
while (run) {
consume(queue.take());
}
} catch (InterruptedException ex) {
}
}
void consume(UserData data) {
try {
db.saveUserData(data.getUuid(), data);
} catch (SQLException ex) {
getPlugin(Plan.class).toLog(this.getClass().getName(), ex);
}
}
void stop() {
run = false;
}
}
class SaveSetup {
private SaveConsumer one;
private SaveConsumer two;
void go(BlockingQueue<UserData> q, Database db) {
one = new SaveConsumer(q, db);
two = new SaveConsumer(q, db);
new Thread(one).start();
new Thread(two).start();
}
void stop() {
one.stop();
two.stop();
}
}

View File

@ -47,9 +47,6 @@ public class InspectCacheHandler {
}
public void cache(UUID uuid, int minutes) {
if (!handler.getDB().wasSeenBefore(uuid)) {
return;
}
DBCallableProcessor cacher = new DBCallableProcessor() {
@Override
public void process(UserData data) {

View File

@ -1,70 +0,0 @@
package main.java.com.djrapitops.plan.data.handlers;
import java.sql.SQLException;
import java.util.Date;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.DemographicsData;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.database.Database;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
/**
*
* @author Rsl1122
*/
public class NewPlayerCreator {
private Plan plugin;
private Database db;
private DataCacheHandler handler;
/**
* Class Constructor.
*
* Gets the Database from the plugin.
*
* @param plugin Current instance of Plan
* @param h Current instance of DataCacheHandler
*/
public NewPlayerCreator(Plan plugin, DataCacheHandler h) {
this.plugin = plugin;
db = plugin.getDB();
handler = h;
}
/**
* Creates a new instance of UserData with default values and saves it to
* DB.
*
* @param player Player the UserData is created for.
*/
public void createNewPlayer(Player player) {
createNewPlayer((OfflinePlayer) player, player.getGameMode());
}
public void createNewPlayer(OfflinePlayer player) {
createNewPlayer(player, GameMode.SURVIVAL);
}
public void createNewPlayer(OfflinePlayer player, GameMode gm) {
UserData data = new UserData(player, new DemographicsData());
data.setLastGamemode(gm);
data.setLastPlayed(new Date().getTime());
long zero = Long.parseLong("0");
data.setPlayTime(zero);
data.setTimesKicked(0);
data.setLoginTimes(0);
data.setLastGmSwapTime(zero);
data.setDeaths(0);
data.setMobKills(0);
try {
db.saveUserData(player.getUniqueId(), data);
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
}

View File

@ -4,7 +4,6 @@ package main.java.com.djrapitops.plan.data.handlers;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData;
@ -40,8 +39,6 @@ public class SessionHandler {
currentSession.endSession(now);
data.addSession(currentSession);
activeSessions.remove(uuid);
} else {
System.out.println(Phrase.ERROR_SESSIONDATA_INITIALIZATION.parse(data.getName()));
}
}
}

View File

@ -132,7 +132,7 @@ public class PlanPlayerListener implements Listener {
data.addLocations(locationH.getLocationsForSaving(uuid));
handler.saveCachedData(uuid);
locationH.clearLocations(uuid);
handler.clearFromCache(uuid);
handler.scheludeForClear(uuid);
}
};
handler.getUserDataForProcessing(kickProcessor, uuid);

View File

@ -21,7 +21,12 @@ public abstract class Database {
public boolean init(){
return false;
}
public abstract void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors) throws SQLException;
public void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors) throws SQLException {
List<DBCallableProcessor> coll = new ArrayList<>();
coll.addAll(Arrays.asList(processors));
giveUserDataToProcessors(uuid, coll);
}
public abstract void giveUserDataToProcessors(UUID uuid, Collection<DBCallableProcessor> processors) throws SQLException;
public abstract void saveUserData(UUID uuid, UserData data) throws SQLException;
public abstract void saveMultipleUserData(List<UserData> data) throws SQLException;
public abstract boolean wasSeenBefore(UUID uuid);
@ -38,7 +43,7 @@ public abstract class Database {
public abstract void close() throws SQLException;
public abstract boolean removeAccount(String uuid) throws SQLException;
public abstract boolean removeAllData() throws SQLException;
public abstract void saveCommandUse(HashMap<String, Integer> data) throws SQLException;
public abstract void saveCommandUse(HashMap<String, Integer> data) throws SQLException, NullPointerException;
public abstract Set<UUID> getSavedUUIDs() throws SQLException;
public abstract HashMap<String, Integer> getCommandUse() throws SQLException;
public abstract int getUserId(String uuid) throws SQLException;

View File

@ -7,7 +7,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -18,7 +18,6 @@ import main.java.com.djrapitops.plan.api.Gender;
import main.java.com.djrapitops.plan.data.*;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
@ -240,7 +239,7 @@ public abstract class SQLDB extends Database {
query("CREATE TABLE IF NOT EXISTS " + nicknamesName + " ("
+ nicknamesColumnUserID + " integer NOT NULL, "
+ nicknamesColumnNick + " varchar(30) NOT NULL, "
+ nicknamesColumnNick + " varchar(75) NOT NULL, "
+ nicknamesColumnCurrent + " boolean NOT NULL DEFAULT 0, "
+ "FOREIGN KEY(" + nicknamesColumnUserID + ") REFERENCES " + userName + "(" + userColumnID + ")"
+ ")"
@ -320,28 +319,21 @@ public abstract class SQLDB extends Database {
}
@Override
public int getVersion() {
public int getVersion() throws SQLException {
int version = 0;
try {
checkConnection();
ResultSet set = connection.prepareStatement("SELECT * FROM " + versionName).executeQuery();
ResultSet set = connection.prepareStatement("SELECT * FROM " + versionName).executeQuery();
if (set.next()) {
version = set.getInt("version");
}
set.close();
return version;
} catch (Exception e) {
plugin.toLog(this.getClass().getName(), e);
return version;
if (set.next()) {
version = set.getInt("version");
}
set.close();
return version;
}
@Override
public void setVersion(int version) throws SQLException {
checkConnection();
public void setVersion(int version) throws SQLException {
connection.prepareStatement("DELETE FROM " + versionName).executeUpdate();
connection.prepareStatement("INSERT INTO " + versionName + " (version) VALUES (" + version + ")").executeUpdate();
@ -405,7 +397,7 @@ public abstract class SQLDB extends Database {
}
@Override
public void saveCommandUse(HashMap<String, Integer> data) throws SQLException {
public void saveCommandUse(HashMap<String, Integer> data) throws SQLException, NullPointerException {
if (data.isEmpty()) {
return;
}
@ -499,11 +491,11 @@ public abstract class SQLDB extends Database {
}
@Override
public void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors) throws SQLException {
public void giveUserDataToProcessors(UUID uuid, Collection<DBCallableProcessor> processors) throws SQLException {
try {
checkConnection();
} catch (Exception e) {
plugin.toLog("Preparing for Exception report - Processors: " + Arrays.toString(processors));
plugin.toLog("Preparing for Exception report - Processors: " + processors.toString());
plugin.toLog(this.getClass().getName(), e);
return;
}
@ -511,12 +503,6 @@ public abstract class SQLDB extends Database {
if (!wasSeenBefore(uuid)) {
return;
}
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());
@ -767,6 +753,7 @@ public abstract class SQLDB extends Database {
saveUserData(userData.getUuid(), userData);
} catch (SQLException e) {
exceptions.add(e);
} catch (NullPointerException e) {
}
}
if (!exceptions.isEmpty()) {

View File

@ -5,11 +5,8 @@ import main.java.com.djrapitops.plan.data.KillData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*

View File

@ -58,7 +58,7 @@ public class Response {
if (forbidden) {
String errorMessage = "HTTP/1.1 403 Forbidden\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 100\r\n"
+ "Content-Length: 98\r\n"
+ "\r\n"
+ "<h1>403 Forbidden - Access Denied</h1><p>Make sure you're accessing the link given by a command</p>";
output.write(errorMessage.getBytes());

View File

@ -21,7 +21,6 @@ import org.bukkit.GameMode;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*
@ -70,7 +69,7 @@ public class Analysis {
@Override
public void run() {
uuids.stream().forEach((uuid) -> {
inspectCache.cache(uuid, 8);
inspectCache.cache(uuid, 15);
});
log(Phrase.ANALYSIS_FETCH_DATA + "");
while (rawData.size() != uuids.size()) {
@ -79,8 +78,10 @@ public class Analysis {
.forEach((uuid) -> {
if (inspectCache.isCached(uuid)) {
UserData userData = inspectCache.getFromCache(uuid);
rawData.add(userData);
added.add(uuid);
if (userData != null) {
rawData.add(userData);
added.add(uuid);
}
}
});
}
@ -216,19 +217,19 @@ public class Analysis {
private void createPlayerActivityGraphs(AnalysisData data, List<SessionData> sData, List<Long> registered) {
long now = new Date().toInstant().getEpochSecond() * (long) 1000;
long scaleDay = 86400 * 1000;
long scaleWeek = 604800 * 1000;
long scaleMonth = (long) 2592000 * (long) 1000;
long scaleMonth = (long) 2592000 * (long) 1000;
data.setNewPlayersDay(AnalysisUtils.getNewPlayers(registered, scaleDay, now));
data.setNewPlayersWeek(AnalysisUtils.getNewPlayers(registered, scaleWeek, now));
data.setNewPlayersMonth(AnalysisUtils.getNewPlayers(registered, scaleMonth, now));
String[] dayArray = PlayerActivityGraphCreator.generateDataArray(sData, scaleDay);
String[] weekArray = PlayerActivityGraphCreator.generateDataArray(sData, scaleWeek);
String[] monthArray = PlayerActivityGraphCreator.generateDataArray(sData, scaleMonth);
data.setPlayersDataArray(new String[]{dayArray[0], dayArray[1], weekArray[0], weekArray[1], monthArray[0], monthArray[1]});
}
}).runTaskAsynchronously(plugin);

View File

@ -1,20 +1,16 @@
package main.java.com.djrapitops.plan.utilities;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.ui.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.ui.tables.SortableCommandUseTableCreator;
import main.java.com.djrapitops.plan.ui.tables.SortablePlayersTableCreator;
import main.java.com.djrapitops.plan.utilities.comparators.MapComparator;
import org.bukkit.GameMode;
/**
*

View File

@ -0,0 +1,57 @@
package main.java.com.djrapitops.plan.utilities;
import java.util.Date;
import main.java.com.djrapitops.plan.data.DemographicsData;
import main.java.com.djrapitops.plan.data.UserData;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
/**
*
* @author Rsl1122
*/
public class NewPlayerCreator {
/**
* Creates a new instance of UserData with default values.
*
* @param player Player the UserData is created for.
* @return a new UserData object
*/
public static UserData createNewPlayer(Player player) {
return createNewPlayer((OfflinePlayer) player, player.getGameMode());
}
/**
* Creates a new instance of UserData with default values.
*
* @param player OfflinePlayer the UserData is created for.
* @return a new UserData object
*/
public static UserData createNewPlayer(OfflinePlayer player) {
return createNewPlayer(player, GameMode.SURVIVAL);
}
/**
* Creates a new instance of UserData with default values.
*
* @param player Player the UserData is created for.
* @param gm Gamemode set as the starting Gamemode
* @return a new UserData object
*/
public static UserData createNewPlayer(OfflinePlayer player, GameMode gm) {
UserData data = new UserData(player, new DemographicsData());
data.setLastGamemode(gm);
data.setLastPlayed(new Date().getTime());
long zero = Long.parseLong("0");
data.setPlayTime(zero);
data.setTimesKicked(0);
data.setLoginTimes(0);
data.setLastGmSwapTime(zero);
data.setDeaths(0);
data.setMobKills(0);
return data;
}
}

View File

@ -158,7 +158,7 @@ public class PlaceholderUtils {
replaceMap.put("%version%", plugin.getDescription().getVersion());
replaceMap.put("%planlite%", "");
String[] playersDataArray = PlayerActivityGraphCreator.generateDataArray(data.getSessions(), (long) 604800 * 1000);
replaceMap.put("%dataweek%", playersDataArray[0].replace("20]", "2]"));
replaceMap.put("%dataweek%", playersDataArray[0].replace(plugin.getHandler().getMaxPlayers()+"]", "2]"));
replaceMap.put("%labelsweek%", playersDataArray[1]);
replaceMap.put("%playersgraphcolor%", Settings.HCOLOR_ACT_ONL + "");
replaceMap.put("%playersgraphfill%", Settings.HCOLOR_ACT_ONL_FILL + "");

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: main.java.com.djrapitops.plan.Plan
version: 2.7.1
version: 2.7.2
softdepend:
- OnTime