mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-01 00:10:12 +01:00
[2.7.2] Bugfixes & Optimization
Fix for #31 #30 #29 #28 Possible fix for #26
This commit is contained in:
parent
a820da3261
commit
75e1cf3e85
@ -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."),
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
95
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheClearQueue.java
vendored
Normal file
95
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheClearQueue.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
104
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheGetQueue.java
vendored
Normal file
104
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheGetQueue.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
95
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheSaveQueue.java
vendored
Normal file
95
Plan/src/main/java/com/djrapitops/plan/data/cache/DataCacheSaveQueue.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 + "");
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user