[2.6.0-DEV] Changed Database Geting to Async, Changed handlers.

- Changed the way UserData is cached so that it is cached asyncronously.
#16
This was quite complex and I might have made mistakes so I will have to
test it properly.
- Location gathering temporarily disabled, will not be disabled in 2.6.0
when it is finished.

Bugs:
- NullPointerException when data is cleared from cache.
- Might be the reason that kick was not saved when player was kicked.
- DB in auto-commit mode for some reason. Too tired to figure.

Untested:
- All Events
- Manage commands (might get in a infinite loop)
- Error causing UserData when calling a DBCallableProcessor (will be
tested with Debugger)
- SessionData
- KillData

UnImplemented:
- Location adding in baches
- http://www.kryogenix.org/code/browser/sorttable/
- Player data table
- Player session length
- Player online activity graph, week
- PlanLite features
This commit is contained in:
Rsl1122 2017-02-16 18:52:52 +02:00
parent 595adfa740
commit 730ea69e2f
28 changed files with 385 additions and 273 deletions

View File

@ -195,7 +195,7 @@ public class Plan extends JavaPlugin {
pluginManager.registerEvents(new PlanCommandPreprocessListener(this), this);
pluginManager.registerEvents(new PlanDeathEventListener(this), this);
if (Settings.GATHERLOCATIONS.isTrue()) {
pluginManager.registerEvents(new PlanPlayerMoveListener(this), this);
// pluginManager.registerEvents(new PlanPlayerMoveListener(this), this);
}
}

View File

@ -18,6 +18,9 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*

View File

@ -10,6 +10,7 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.database.databases.SQLiteDB;
import org.bukkit.command.Command;
@ -30,7 +31,7 @@ public class ManageBackupCommand extends SubCommand {
* @param plugin Current instance of Plan
*/
public ManageBackupCommand(Plan plugin) {
super("backup", "plan.manage", Phrase.CMD_USG_MANAGE_BACKUP+"", CommandType.CONSOLE, "<DB>");
super("backup", "plan.manage", Phrase.CMD_USG_MANAGE_BACKUP + "", CommandType.CONSOLE, "<DB>");
this.plugin = plugin;
}
@ -48,7 +49,7 @@ public class ManageBackupCommand extends SubCommand {
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
try {
if (args.length < 1) {
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.parse(Phrase.USE_BACKUP+""));
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.parse(Phrase.USE_BACKUP + ""));
return true;
}
String db = args[0].toLowerCase();
@ -76,9 +77,9 @@ public class ManageBackupCommand extends SubCommand {
@Override
public void run() {
Date now = new Date();
SQLiteDB backupDB = new SQLiteDB(plugin,
args[0]+"-backup-"+now.toString().substring(4, 10).replaceAll(" ", "-").replaceAll(":", "-"));
SQLiteDB backupDB = new SQLiteDB(plugin,
args[0] + "-backup-" + now.toString().substring(4, 10).replaceAll(" ", "-").replaceAll(":", "-"));
if (!backupDB.init()) {
sender.sendMessage(Phrase.MANAGE_DATABASE_FAILURE + "");
this.cancel();
@ -86,10 +87,18 @@ public class ManageBackupCommand extends SubCommand {
}
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
backupDB.removeAllData();
Set<UUID> uuids = copyFromDB.getSavedUUIDs();
Set<UUID> uuids = copyFromDB.getSavedUUIDs();
List<UserData> allUserData = new ArrayList<>();
for (UUID uuid : uuids) {
allUserData.add(copyFromDB.getUserData(uuid));
copyFromDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allUserData.add(data);
}
});
}
while (uuids.size() > allUserData.size()) {
}
backupDB.saveMultipleUserData(allUserData);
backupDB.saveCommandUse(copyFromDB.getCommandUse());

View File

@ -11,6 +11,7 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.utilities.DataCombineUtils;
import org.bukkit.command.Command;
@ -31,7 +32,7 @@ public class ManageCombineCommand extends SubCommand {
* @param plugin Current instance of Plan
*/
public ManageCombineCommand(Plan plugin) {
super("combine", "plan.manage", Phrase.CMD_USG_MANAGE_COMBINE+"", CommandType.CONSOLE_WITH_ARGUMENTS, Phrase.ARG_MOVE+"");
super("combine", "plan.manage", Phrase.CMD_USG_MANAGE_COMBINE + "", CommandType.CONSOLE_WITH_ARGUMENTS, Phrase.ARG_MOVE + "");
this.plugin = plugin;
}
@ -51,7 +52,7 @@ public class ManageCombineCommand extends SubCommand {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (args.length < 2) {
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.parse(Phrase.USE_COMBINE+""));
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.parse(Phrase.USE_COMBINE + ""));
return true;
}
String fromDB = args[0].toLowerCase();
@ -113,10 +114,23 @@ public class ManageCombineCommand extends SubCommand {
HashMap<UUID, UserData> allFromUserData = new HashMap<>();
HashMap<UUID, UserData> allToUserData = new HashMap<>();
for (UUID uuid : fromUUIDS) {
allFromUserData.put(uuid, moveFromDB.getUserData(uuid));
moveFromDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allFromUserData.put(uuid, data);
}
});
}
for (UUID uuid : toUUIDS) {
allToUserData.put(uuid, moveToDB.getUserData(uuid));
moveToDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allToUserData.put(uuid, data);
}
});
}
while (fromUUIDS.size() > allFromUserData.size() || toUUIDS.size() > allToUserData.size()) {
}
Set<UUID> uuids = new HashSet<>();
uuids.addAll(toUUIDS);

View File

@ -11,15 +11,19 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.data.importing.Importer;
import main.java.com.djrapitops.plan.data.importing.OnTimeImporter;
import org.bukkit.Bukkit;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.GameMode;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*
@ -35,7 +39,7 @@ public class ManageImportCommand extends SubCommand {
* @param plugin Current instance of Plan
*/
public ManageImportCommand(Plan plugin) {
super("import", "plan.manage", Phrase.CMD_USG_MANAGE_IMPORT+"", CommandType.CONSOLE, Phrase.ARG_IMPORT+"");
super("import", "plan.manage", Phrase.CMD_USG_MANAGE_IMPORT + "", CommandType.CONSOLE, Phrase.ARG_IMPORT + "");
this.plugin = plugin;
}
@ -56,7 +60,7 @@ public class ManageImportCommand extends SubCommand {
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
if (args.length < 1) {
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS_ONE.toString() + " "+Phrase.USE_IMPORT);
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS_ONE.toString() + " " + Phrase.USE_IMPORT);
return true;
}
@ -80,7 +84,7 @@ public class ManageImportCommand extends SubCommand {
}
// Header
sender.sendMessage(Phrase.MANAGE_IMPORTING+"");
sender.sendMessage(Phrase.MANAGE_IMPORTING + "");
Set<UUID> uuids = new HashSet<>();
for (OfflinePlayer p : Bukkit.getOfflinePlayers()) {
uuids.add(p.getUniqueId());
@ -88,29 +92,38 @@ public class ManageImportCommand extends SubCommand {
HashMap<UUID, Long> numbericData = importPlugins.get(importFromPlugin).grabNumericData(uuids);
DataCacheHandler handler = plugin.getHandler();
if (importFromPlugin.equals("ontime")) {
importOnTime(numbericData, handler);
importOnTime(numbericData, handler, sender);
}
handler.saveCachedUserData();
sender.sendMessage(Phrase.MANAGE_SUCCESS+"");
return true;
}
private void importOnTime(HashMap<UUID, Long> onTimeData, DataCacheHandler handler) {
for (UUID uuid : onTimeData.keySet()) {
OfflinePlayer player = getOfflinePlayer(uuid);
if (handler.getActivityHandler().isFirstTimeJoin(uuid)) {
handler.newPlayer(player);
private void importOnTime(HashMap<UUID, Long> onTimeData, DataCacheHandler handler, CommandSender sender) {
BukkitTask asyncOnTimeImportTask = (new BukkitRunnable() {
@Override
public void run() {
for (UUID uuid : onTimeData.keySet()) {
OfflinePlayer player = getOfflinePlayer(uuid);
if (handler.getActivityHandler().isFirstTimeJoin(uuid)) {
handler.newPlayer(player);
}
DBCallableProcessor importer = new DBCallableProcessor() {
@Override
public void process(UserData data) {
Long playTime = onTimeData.get(uuid);
if (playTime > data.getPlayTime()) {
data.setPlayTime(playTime);
data.setLastGamemode(GameMode.SURVIVAL);
data.setAllGMTimes(playTime, 0, 0, 0);
data.setLastGmSwapTime(playTime);
}
}
};
}
handler.saveCachedUserData();
sender.sendMessage(Phrase.MANAGE_SUCCESS + "");
this.cancel();
}
UserData uData = handler.getCurrentData(uuid);
Long playTime = onTimeData.get(uuid);
if (playTime > uData.getPlayTime()) {
uData.setPlayTime(playTime);
uData.setLastGamemode(GameMode.SURVIVAL);
uData.setAllGMTimes(playTime, 0, 0, 0);
uData.setLastGmSwapTime(playTime);
}
}
}).runTaskAsynchronously(plugin);
}
}

View File

@ -10,6 +10,7 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -110,7 +111,15 @@ public class ManageMoveCommand extends SubCommand {
moveToDB.removeAllData();
List<UserData> allUserData = new ArrayList<>();
for (UUID uuid : uuids) {
allUserData.add(moveFromDB.getUserData(uuid));
moveFromDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allUserData.add(data);
}
});
}
while(uuids.size() > allUserData.size()) {
}
moveToDB.saveMultipleUserData(allUserData);
moveToDB.saveCommandUse(moveFromDB.getCommandUse());

View File

@ -8,11 +8,12 @@ import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.UUIDFetcher;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import static org.bukkit.Bukkit.getOfflinePlayer;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*

View File

@ -11,6 +11,7 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.CommandType;
import main.java.com.djrapitops.plan.command.SubCommand;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.database.databases.SQLiteDB;
import org.bukkit.command.Command;
@ -103,7 +104,15 @@ public class ManageRestoreCommand extends SubCommand {
Set<UUID> uuids = backupDB.getSavedUUIDs();
List<UserData> allUserData = new ArrayList<>();
for (UUID uuid : uuids) {
allUserData.add(backupDB.getUserData(uuid));
backupDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allUserData.add(data);
}
});
}
while(uuids.size() > allUserData.size()) {
}
copyToDB.saveMultipleUserData(allUserData);
copyToDB.saveCommandUse(backupDB.getCommandUse());

View File

@ -15,7 +15,7 @@ import org.bukkit.entity.Player;
public class UserData {
private boolean isAccessed;
private int accessing;
private UUID uuid;
private Location location;
@ -160,16 +160,20 @@ public class UserData {
currentSession = session;
}
public void updateBanned(Player p) {
isBanned = p.isBanned();
public void updateBanned(boolean isBanned) {
this.isBanned = isBanned;
}
public boolean isAccessed() {
return isAccessed;
return accessing > 0;
}
public void setAccessing(boolean value) {
isAccessed = value;
public void access() {
accessing++;
}
public void stopAccessing() {
accessing--;
}
// Getters -------------------------------------------------------------

View File

@ -0,0 +1,12 @@
package main.java.com.djrapitops.plan.data.cache;
import main.java.com.djrapitops.plan.data.UserData;
/**
*
* @author Rsl1122
*/
public abstract class DBCallableProcessor {
public abstract void process(UserData data);
}

View File

@ -13,7 +13,6 @@ import main.java.com.djrapitops.plan.data.*;
import main.java.com.djrapitops.plan.data.handlers.*;
import main.java.com.djrapitops.plan.database.Database;
import org.bukkit.Bukkit;
import static org.bukkit.Bukkit.getPlayer;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
@ -57,7 +56,7 @@ public class DataCacheHandler {
dataCache = new HashMap<>();
activityHandler = new ActivityHandler(plugin, this);
gamemodeTimesHandler = new GamemodeTimesHandler(plugin, this);
locationHandler = new LocationHandler(plugin, this);
locationHandler = new LocationHandler(plugin);
demographicsHandler = new DemographicsHandler(plugin, this);
basicInfoHandler = new BasicInfoHandler(plugin, this);
ruleBreakingHandler = new RuleBreakingHandler(plugin, this);
@ -95,12 +94,6 @@ public class DataCacheHandler {
timesSaved++;
}
}).runTaskTimerAsynchronously(plugin, 60 * 20 * minutes, 60 * 20 * minutes);
// (new BukkitRunnable() {
// @Override
// public void run() {
//
// }
// }).runTaskTimerAsynchronously(plugin, 60 * 20 * sMinutes, 60 * 20 * sMinutes);
}
/**
@ -108,39 +101,46 @@ public class DataCacheHandler {
*
* Caches the data to the HashMap if cache: true
*
* @param processor DBCallableProcessor Object used to process the data
* after it was retrieved
* @param uuid Player's UUID
* @param cache Wether or not the UserData will be Cached in this instance
* of DataCacheHandler
* @return UserData matching the Player
*/
public UserData getCurrentData(UUID uuid, boolean cache) {
if (cache) {
if (dataCache.get(uuid) == null) {
UserData uData = db.getUserData(uuid);
if (uData != null) {
dataCache.put(uuid, uData);
plugin.log(Phrase.ADD_TO_CACHE.parse(uuid.toString()));
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.ADD_TO_CACHE.parse(uuid.toString()));
}
}
};
db.giveUserDataToProcessors(uuid, cacher, processor);
} else {
processor.process(uData);
}
this.cancel();
}
return dataCache.get(uuid);
} else {
if (dataCache.get(uuid) != null) {
return dataCache.get(uuid);
}
UserData uData = db.getUserData(uuid);
return uData;
}
}).runTaskAsynchronously(plugin);
}
/**
** Uses Database to retrieve the UserData of a matching player Caches the
* data to the HashMap
*
* @param processor DBCallableProcessor Object used to process the data
* after it was retrieved
* @param uuid Player's UUID
* @return UserData matching the Player
*/
public UserData getCurrentData(UUID uuid) {
return getCurrentData(uuid, true);
public void getUserDataForProcessing(DBCallableProcessor processor, UUID uuid) {
getUserDataForProcessing(processor, uuid, true);
}
/**
@ -197,39 +197,26 @@ public class DataCacheHandler {
* Data is saved on a new line with a long value matching current Date
*/
public void saveCommandUse() {
BukkitTask asyncCommandUseSaveTask = (new BukkitRunnable() {
@Override
public void run() {
db.saveCommandUse(commandUse);
}
}).runTaskAsynchronously(plugin);
db.saveCommandUse(commandUse);
}
// Should only be called from Async thread
private void saveHandlerDataToCache() {
Bukkit.getServer().getOnlinePlayers().parallelStream().forEach((p) -> {
saveHandlerDataToCache(p);
});
}
/**
* Saves a single player's data to the cache from the handler if the player
* is online.
*
* @param uuid UUID of the Player to save
*/
public void saveHandlerDataToCache(UUID uuid) {
Player p = getPlayer(uuid);
if (p != null) {
if (p.isOnline()) {
saveHandlerDataToCache(p);
}
}
}
// Should only be called from Async thread
private void saveHandlerDataToCache(Player p) {
UserData data = getCurrentData(p.getUniqueId());
activityHandler.saveToCache(p, data);
gamemodeTimesHandler.saveToCache(p, data);
DBCallableProcessor cacheUpdater = new DBCallableProcessor() {
@Override
public void process(UserData data) {
activityHandler.saveToCache(data);
gamemodeTimesHandler.saveToCache(p.getGameMode(), data);
}
};
getUserDataForProcessing(cacheUpdater, p.getUniqueId());
}
/**
@ -248,12 +235,13 @@ public class DataCacheHandler {
* @param uuid Player's UUID
*/
public void clearFromCache(UUID uuid) {
if (dataCache.get(uuid) != null) {
if (dataCache.get(uuid).isAccessed()) {
UserData userData = dataCache.get(uuid);
if (userData != null) {
if (userData.isAccessed()) {
(new BukkitRunnable() {
@Override
public void run() {
if (!dataCache.get(uuid).isAccessed()) {
if (!userData.isAccessed()) {
dataCache.remove(uuid);
plugin.log("Cleared " + uuid.toString() + " from Cache. (Delay task)");
this.cancel();
@ -379,31 +367,42 @@ public class DataCacheHandler {
/**
* @return Current instance of ServerDataHandler
*/
public CommandUseHandler getServerDataHandler() {
public CommandUseHandler getCommandUseHandler() {
return commandUseHandler;
}
public SessionHandler getSessionHandler() {
return sessionHandler;
}
/**
* If /reload is run this treats every online player as a new login.
*
* Calls all the methods that are ran when PlayerJoinEvent is fired
*/
public void handleReload() {
for (Player player : Bukkit.getOnlinePlayers()) {
UUID uuid = player.getUniqueId();
boolean isNewPlayer = activityHandler.isFirstTimeJoin(uuid);
if (isNewPlayer) {
newPlayer(player);
BukkitTask asyncReloadCacheUpdateTask = (new BukkitRunnable() {
@Override
public void run() {
for (Player player : Bukkit.getOnlinePlayers()) {
UUID uuid = player.getUniqueId();
boolean isNewPlayer = activityHandler.isFirstTimeJoin(uuid);
if (isNewPlayer) {
newPlayer(player);
}
DBCallableProcessor cacheUpdater = new DBCallableProcessor() {
@Override
public void process(UserData data) {
activityHandler.handleReload(data);
basicInfoHandler.handleReload(player.getDisplayName(), player.getAddress().getAddress(), data);
gamemodeTimesHandler.handleReload(player.getGameMode(), data);
}
};
getUserDataForProcessing(cacheUpdater, player.getUniqueId());
}
this.cancel();
}
UserData data = getCurrentData(uuid);
activityHandler.handleReload(player, data);
basicInfoHandler.handleReload(player, data);
gamemodeTimesHandler.handleReload(player, data);
}
}).runTaskAsynchronously(plugin);
saveCachedUserData();
}

View File

@ -7,6 +7,7 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.Settings;
import main.java.com.djrapitops.plan.data.UserData;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
/**
*
@ -49,14 +50,20 @@ public class InspectCacheHandler {
if (!handler.getDB().wasSeenBefore(uuid)) {
return;
}
cache.put(uuid, handler.getCurrentData(uuid, false));
DBCallableProcessor cacher = new DBCallableProcessor() {
@Override
public void process(UserData data) {
cache.put(uuid, data);
}
};
handler.getUserDataForProcessing(cacher, uuid, false);
long clearTime = new Date().toInstant().getEpochSecond() + (long) 60 * (long) minutes;
if (clearTimes.get(uuid) == null) {
clearTimes.put(uuid, (long) 0);
}
if (clearTimes.get(uuid) < clearTime) {
clearTimes.put(uuid, clearTime);
(new BukkitRunnable() {
BukkitTask timedInspectCacheClearTask = (new BukkitRunnable() {
@Override
public void run() {
if (new Date().toInstant().getEpochSecond() - clearTimes.get(uuid) < 30) {

View File

@ -14,7 +14,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
* @author Rsl1122
*/
public class ActivityHandler {
private final Plan plugin;
private final DataCacheHandler handler;
@ -44,10 +44,9 @@ public class ActivityHandler {
*
* lastPlayed is set to long matching current Date.
*
* @param player Player which data is being saved
* @param data UserData matching the Player
*/
public void saveToCache(Player player, UserData data) {
public void saveToCache(UserData data) {
long timeNow = new Date().getTime();
data.setPlayTime(data.getPlayTime() + (timeNow - data.getLastPlayed()));
data.setLastPlayed(timeNow);
@ -59,15 +58,14 @@ public class ActivityHandler {
* Updates if player is banned or not, Adds one to login times, Adds current
* location to location list.
*
* @param event JoinEvent from listener
* @param isBanned is the player banned?
* @param data UserData matching the Player
*/
public void handleLogin(PlayerJoinEvent event, UserData data) {
public void handleLogin(boolean isBanned, UserData data) {
data.setLastPlayed(new Date().getTime());
Player player = event.getPlayer();
data.updateBanned(player);
data.updateBanned(isBanned);
data.setLoginTimes(data.getLoginTimes() + 1);
handler.getSessionHandler().startSession(data);
// handler.getLocationHandler().addLocation(player.getUniqueId(), player.getLocation());
}
@ -76,10 +74,9 @@ public class ActivityHandler {
*
* Saves PlayTime, Set's LastPlayed value to long matching current Date
*
* @param event QuitEvent from Listener
* @param data UserData matching the Player
*/
public void handleLogOut(PlayerQuitEvent event, UserData data) {
public void handleLogOut(UserData data) {
Date now = new Date();
long timeNow = now.getTime();
data.setPlayTime(data.getPlayTime() + (timeNow - data.getLastPlayed()));
@ -92,10 +89,9 @@ public class ActivityHandler {
*
* Updates PlayTime, Sets LastPlayed value to long matching current Date
*
* @param player Player who is online
* @param data UserData matching the Player
*/
public void handleReload(Player player, UserData data) {
public void handleReload(UserData data) {
Date now = new Date();
long timeNow = now.getTime();
data.setPlayTime(data.getPlayTime() + (timeNow - data.getLastPlayed()));

View File

@ -1,10 +1,10 @@
package main.java.com.djrapitops.plan.data.handlers;
import java.net.InetAddress;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
/**
*
@ -27,33 +27,32 @@ public class BasicInfoHandler {
/**
* Adds new nicknames and IPs to UserData
*
* @param event JoinEvent to get the Player
* @param nickname Displayname of player
* @param ip IP of player
* @param data UserData matching the Player
*/
public void handleLogin(PlayerJoinEvent event, UserData data) {
Player player = event.getPlayer();
String nickname = player.getDisplayName();
if (!nickname.isEmpty()) {
if (data.addNickname(nickname)) {
data.setLastNick(nickname);
}
}
data.addIpAddress(player.getAddress().getAddress());
public void handleLogin(String nickname, InetAddress ip, UserData data) {
addNickname(nickname, data);
data.addIpAddress(ip);
}
/**
* Adds new nicknames and IPs to UserData in case of /reload
*
* @param player A player that is online when /reload is run
* @param nickname Displayname of player
* @param ip IP of player
* @param data UserData matching the Player
*/
public void handleReload(Player player, UserData data) {
String nickname = player.getDisplayName();
public void handleReload(String nickname, InetAddress ip, UserData data) {
addNickname(nickname, data);
data.addIpAddress(ip);
}
public void addNickname(String nickname, UserData data) {
if (!nickname.isEmpty()) {
if (data.addNickname(nickname)) {
data.setLastNick(nickname);
}
}
data.addIpAddress(player.getAddress().getAddress());
}
}

View File

@ -110,12 +110,11 @@ public class DemographicsHandler {
* @param event JoinEvent to get the InetAddress
* @param data UserData corresponding the player
*/
public void handleLogin(PlayerJoinEvent event, UserData data) {
InetAddress address = event.getPlayer().getAddress().getAddress();
public void handleLogin(InetAddress ip, UserData data) {
DemographicsData demData = data.getDemData();
try {
String result = "";
URL url = new URL("http://freegeoip.net/csv/" + address.getHostAddress());
URL url = new URL("http://freegeoip.net/csv/" + ip.getHostAddress());
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String resultline;

View File

@ -33,11 +33,11 @@ public class GamemodeTimesHandler {
/**
* Updates lastGamemode to current gamemode on Login
*
* @param event JoinEvent from listener
* @param gm Gamemode upon login
* @param data UserData matching the Player
*/
public void handleLogin(PlayerJoinEvent event, UserData data) {
data.setLastGamemode(event.getPlayer().getGameMode());
public void handleLogin(GameMode gm, UserData data) {
data.setLastGamemode(gm);
}
/**
@ -45,19 +45,18 @@ public class GamemodeTimesHandler {
*
* Updates GMTimes with new values and sets lastSwap and lastGM.
*
* @param event GMChangeEvent from Listener
* @param newGM the GameMode player changed to
* @param data UserData matching the Player
*/
public void handleChangeEvent(PlayerGameModeChangeEvent event, UserData data) {
public void handleChangeEvent(GameMode newGM, UserData data) {
HashMap<GameMode, Long> times = data.getGmTimes();
handler.getActivityHandler().saveToCache(event.getPlayer(), data);
handler.getActivityHandler().saveToCache(data);
long lastSwap = data.getLastGmSwapTime();
long playTime = data.getPlayTime();
GameMode oldGM = data.getLastGamemode();
data.setGMTime(oldGM, times.get(oldGM) + (playTime - lastSwap));
GameMode newGM = event.getNewGameMode();
data.setLastGamemode(newGM);
data.setLastGmSwapTime(playTime);
@ -66,16 +65,15 @@ public class GamemodeTimesHandler {
/**
* Updates GMTimes with new values and saves it to cache.
*
* @param player Player whose data is being saved
* @param currentGM Current Gamemode of the Player
* @param data UserData matching the Player
*/
public void saveToCache(Player player, UserData data) {
public void saveToCache(GameMode currentGM, UserData data) {
HashMap<GameMode, Long> times = data.getGmTimes();
handler.getActivityHandler().saveToCache(player, data);
handler.getActivityHandler().saveToCache(data);
long lastSwap = data.getLastGmSwapTime();
long playtime = data.getPlayTime();
GameMode currentGM = player.getGameMode();
data.setGMTime(currentGM, times.get(currentGM) + (playtime - lastSwap));
data.setLastGmSwapTime(playtime);
@ -84,20 +82,20 @@ public class GamemodeTimesHandler {
/**
* Updates GMTImes for player who is online when /reload is run.
*
* @param player Player whose data is updated
* @param currentGM Gamemode if online during reload
* @param data UserData matching Player
*/
public void handleReload(Player player, UserData data) {
saveToCache(player, data);
public void handleReload(GameMode currentGM, UserData data) {
saveToCache(currentGM, data);
}
/**
* Updates GMTimes on Logout.
*
* @param event QuitEvent from Listener
* @param currentGM Current gamemode at logout
* @param data UserData matching Player
*/
public void handleLogOut(PlayerQuitEvent event, UserData data) {
saveToCache(event.getPlayer(), data);
public void handleLogOut(GameMode currentGM, UserData data) {
saveToCache(currentGM, data);
}
}

View File

@ -17,8 +17,7 @@ public class KillHandler {
this.plugin = plugin;
}
public void handlePlayerKill(UserData killerData, UserData victim, String weapon) {
UUID victimUUID = victim.getUuid();
public void handlePlayerKill(UserData killerData, UUID victimUUID, String weapon) {
long now = new Date().toInstant().getEpochSecond()*(long)1000;
int victimID = plugin.getDB().getUserId(victimUUID+"");
killerData.addPlayerKill(new KillData(victimUUID, victimID, weapon, now));

View File

@ -1,14 +1,9 @@
package main.java.com.djrapitops.plan.data.handlers;
import java.util.Collection;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.event.player.PlayerQuitEvent;
/**
*
@ -16,26 +11,24 @@ import org.bukkit.event.player.PlayerQuitEvent;
*/
public class LocationHandler {
private final DataCacheHandler handler;
private Plan plugin;
/**
* Class Constructor.
*
* @param plugin Current instance of Plan
* @param h Current instance of DataCacheHandler
*/
public LocationHandler(Plan plugin, DataCacheHandler h) {
this.handler = h;
public LocationHandler(Plan plugin) {
this.plugin = plugin;
}
/**
* Adds location to the UserData if it is not being saved.
*
* @param uuid UUID of the matching Player
* @param data UserData of player
* @param loc Location from the MoveEvent listener.
*/
public void addLocation(UUID uuid, Location loc) {
UserData data = handler.getCurrentData(uuid);
public void addLocation(UserData data, Location loc) {
if (!data.isAccessed()) {
data.addLocation(loc);
} else {
@ -46,26 +39,12 @@ public class LocationHandler {
/**
* Adds multiple locaitons to the UserData.
*
* @param uuid UUID of the matching Player
* @param data Userdata of Player
* @param locs The Locations that are added.
*/
public void addLocations(UUID uuid, Collection<Location> locs) {
handler.getCurrentData(uuid).addLocations(locs);
}
/**
* Handles QuitEvent by updating BedLocation.
*
* Uses OfflinePlayer to prevent null bedlocation.
*
* @param event QuitEvent from Listener.
* @param data UserData matching Player.
*/
public void handleLogOut(PlayerQuitEvent event, UserData data) {
OfflinePlayer p = getOfflinePlayer(event.getPlayer().getUniqueId());
Location bedSpawnLocation = p.getBedSpawnLocation();
if (bedSpawnLocation == null) {
return;
public void addLocations(UserData data, Collection<Location> locs) {
if (!data.isAccessed()) {
data.addLocations(locs);
}
}
}

View File

@ -27,23 +27,21 @@ public class RuleBreakingHandler {
}
/**
* Update if player is banned or not.
* Update if player is banned or not on logout.
*
* @param event QuitEvent given by Listener
* @param isBanned
* @param data UserData matching Player
*/
public void handleLogout(PlayerQuitEvent event, UserData data) {
Player player = event.getPlayer();
data.updateBanned(player);
public void handleLogout(boolean isBanned, UserData data) {
data.updateBanned(isBanned);
}
/**
* Update if player is banned or not.
* Update if player is banned or not on kick.
*
* @param event KickEvent given by Listener
* @param data UserData matching Player
*/
public void handleKick(PlayerKickEvent event, UserData data) {
public void handleKick(UserData data) {
data.setTimesKicked(data.getTimesKicked() + 1);
data.setPlayTime(data.getPlayTime() + (new Date().getTime() - data.getLastPlayed()));
data.setLastPlayed(new Date().getTime());

View File

@ -2,7 +2,9 @@ package main.java.com.djrapitops.plan.data.listeners;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.data.handlers.BasicInfoHandler;
import main.java.com.djrapitops.plan.data.handlers.DemographicsHandler;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@ -19,6 +21,7 @@ public class PlanChatListener implements Listener {
private final Plan plugin;
private final DataCacheHandler handler;
private final DemographicsHandler demographicsHandler;
private final BasicInfoHandler basicInfoH;
/**
* Class Constructor.
@ -29,6 +32,7 @@ public class PlanChatListener implements Listener {
this.plugin = plugin;
handler = plugin.getHandler();
demographicsHandler = handler.getDemographicsHandler();
basicInfoH = handler.getBasicInfoHandler();
}
/**
@ -42,11 +46,13 @@ public class PlanChatListener implements Listener {
return;
}
Player p = event.getPlayer();
UserData data = handler.getCurrentData(p.getUniqueId());
String nickname = p.getDisplayName();
if (!nickname.isEmpty()) {
data.addNickname(nickname);
}
demographicsHandler.handleChatEvent(event, data);
DBCallableProcessor chatProcessor = new DBCallableProcessor() {
@Override
public void process(UserData data) {
basicInfoH.addNickname(p.getDisplayName(), data);
demographicsHandler.handleChatEvent(event, data);
}
};
handler.getUserDataForProcessing(chatProcessor, p.getUniqueId());
}
}

View File

@ -26,7 +26,7 @@ public class PlanCommandPreprocessListener implements Listener {
public PlanCommandPreprocessListener(Plan plugin) {
this.plugin = plugin;
handler = plugin.getHandler();
serverH = handler.getServerDataHandler();
serverH = handler.getCommandUseHandler();
}
/**

View File

@ -2,6 +2,7 @@ package main.java.com.djrapitops.plan.data.listeners;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.data.handlers.KillHandler;
import org.bukkit.entity.LivingEntity;
@ -37,18 +38,33 @@ public class PlanDeathEventListener implements Listener {
LivingEntity dead = event.getEntity();
Player killer = dead.getKiller();
boolean killerIsPlayer = killer != null;
UserData killersData = null;
if (killerIsPlayer) {
killersData = handler.getCurrentData(killer.getUniqueId());
DBCallableProcessor deathProcess = new DBCallableProcessor() {
@Override
public void process(UserData killersData) {
continueProcessing(dead, killerIsPlayer, killer, killersData);
}
};
handler.getUserDataForProcessing(deathProcess, killer.getUniqueId());
} else {
continueProcessing(dead, false, null, null);
}
}
public void continueProcessing(LivingEntity dead, boolean killerIsPlayer, Player killer, UserData killersData) {
if (dead instanceof Player) {
Player killed = (Player) dead;
UserData killedsData = handler.getCurrentData(killed.getUniqueId());
if (killerIsPlayer) {
String weaponName = killer.getInventory().getItemInMainHand().getType().name();
kH.handlePlayerKill(killersData, killedsData, weaponName);
}
kH.handlePlayerDeath(killedsData);
DBCallableProcessor deathProcess = new DBCallableProcessor() {
@Override
public void process(UserData killedsData) {
if (killerIsPlayer) {
String weaponName = killer.getInventory().getItemInMainHand().getType().name();
kH.handlePlayerKill(killersData, killed.getUniqueId(), weaponName);
}
kH.handlePlayerDeath(killedsData);
}
};
handler.getUserDataForProcessing(deathProcess, killed.getUniqueId());
} else if (killerIsPlayer) {
kH.handleMobKill(killersData);
}

View File

@ -2,6 +2,7 @@ package main.java.com.djrapitops.plan.data.listeners;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.data.handlers.GamemodeTimesHandler;
import org.bukkit.entity.Player;
@ -42,7 +43,12 @@ public class PlanGamemodeChangeListener implements Listener {
return;
}
Player p = event.getPlayer();
UserData data = handler.getCurrentData(p.getUniqueId());
gmTimesH.handleChangeEvent(event, data);
DBCallableProcessor gmProcessor = new DBCallableProcessor() {
@Override
public void process(UserData data) {
gmTimesH.handleChangeEvent(event.getNewGameMode(), data);
}
};
handler.getUserDataForProcessing(gmProcessor, p.getUniqueId());
}
}

View File

@ -1,8 +1,10 @@
package main.java.com.djrapitops.plan.data.listeners;
import java.net.InetAddress;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.data.handlers.*;
import org.bukkit.entity.Player;
@ -25,10 +27,8 @@ public class PlanPlayerListener implements Listener {
private final ActivityHandler activityH;
private final BasicInfoHandler basicInfoH;
private final GamemodeTimesHandler gmTimesH;
private final LocationHandler locationH;
private final DemographicsHandler demographicH;
private final RuleBreakingHandler rulebreakH;
private final CommandUseHandler serverHandler;
/**
* Class Constructor.
@ -45,9 +45,7 @@ public class PlanPlayerListener implements Listener {
basicInfoH = handler.getBasicInfoHandler();
gmTimesH = handler.getGamemodeTimesHandler();
demographicH = handler.getDemographicsHandler();
locationH = handler.getLocationHandler();
rulebreakH = handler.getRuleBreakingHandler();
serverHandler = handler.getServerDataHandler();
}
/**
@ -66,17 +64,18 @@ public class PlanPlayerListener implements Listener {
if (isNewPlayer) {
handler.newPlayer(player);
}
UserData data = handler.getCurrentData(uuid);
activityH.handleLogin(event, data);
basicInfoH.handleLogin(event, data);
gmTimesH.handleLogin(event, data);
demographicH.handleLogin(event, data);
(new BukkitRunnable() {
DBCallableProcessor loginProcessor = new DBCallableProcessor() {
@Override
public void run() {
public void process(UserData data) {
activityH.handleLogin(player.isBanned(), data);
InetAddress ip = player.getAddress().getAddress();
basicInfoH.handleLogin(player.getDisplayName(), ip, data);
gmTimesH.handleLogin(player.getGameMode(), data);
demographicH.handleLogin(ip, data);
handler.saveCachedData(uuid);
}
}).runTaskLater(plugin, 15 * 20);
};
handler.getUserDataForProcessing(loginProcessor, uuid);
}
/**
@ -89,12 +88,17 @@ public class PlanPlayerListener implements Listener {
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
UUID uuid = event.getPlayer().getUniqueId();
UserData data = handler.getCurrentData(uuid);
activityH.handleLogOut(event, data);
locationH.handleLogOut(event, data);
gmTimesH.handleLogOut(event, data);
handler.saveCachedData(uuid);
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
DBCallableProcessor logoutProcessor = new DBCallableProcessor() {
@Override
public void process(UserData data) {
activityH.handleLogOut(data);
gmTimesH.handleLogOut(player.getGameMode(), data);
handler.saveCachedData(uuid);
}
};
handler.getUserDataForProcessing(logoutProcessor, uuid);
}
/**
@ -110,9 +114,14 @@ public class PlanPlayerListener implements Listener {
return;
}
UUID uuid = event.getPlayer().getUniqueId();
UserData data = handler.getCurrentData(uuid);
rulebreakH.handleKick(event, data);
handler.saveCachedData(uuid);
handler.clearFromCache(uuid);
DBCallableProcessor kickProcessor = new DBCallableProcessor() {
@Override
public void process(UserData data) {
rulebreakH.handleKick(data);
handler.saveCachedData(uuid);
handler.clearFromCache(uuid);
}
};
handler.getUserDataForProcessing(kickProcessor, uuid);
}
}

View File

@ -43,13 +43,13 @@ public class PlanPlayerMoveListener implements Listener {
if (event.isCancelled()) {
return;
}
Player p = event.getPlayer();
Location from = event.getFrom();
Location to = event.getTo();
if (from.getBlockX() == to.getBlockX() && from.getBlockZ() == to.getBlockZ()) {
return;
}
Player p = event.getPlayer();
Location savedLocation = to.getBlock().getLocation();
locationH.addLocation(p.getUniqueId(), savedLocation);
// locationH.addLocation(uData, savedLocation);
}
}

View File

@ -3,6 +3,7 @@ package main.java.com.djrapitops.plan.database;
import java.util.*;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import org.bukkit.configuration.ConfigurationSection;
/**
@ -35,10 +36,11 @@ public abstract class Database {
* Returns the UserData fetched from the Database.
*
* @param uuid UUID of Player
* @return UserData of Player
* @param processors The DBCallableProcessor Objects used to process data after async
* get task is complete.
*/
public abstract UserData getUserData(UUID uuid);
public abstract void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors);
/**
* Saves the UserData to the Database.
*
@ -49,10 +51,11 @@ public abstract class Database {
/**
* 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.
*
@ -109,11 +112,16 @@ public abstract class Database {
* Closes the database.
*/
public abstract void close();
public abstract void removeAccount(String uuid);
public abstract void removeAllData();
public abstract void saveCommandUse(HashMap<String, Integer> data);
public abstract Set<UUID> getSavedUUIDs();
public abstract HashMap<String, Integer> getCommandUse();
public abstract int getUserId(String uuid);
}

View File

@ -15,13 +15,14 @@ import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
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 static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitRunnable;
import static org.bukkit.Bukkit.getOfflinePlayer;
public abstract class SQLDB extends Database {
@ -30,6 +31,7 @@ public abstract class SQLDB extends Database {
private final boolean supportsModification;
private Connection connection;
private int transactionsActive;
private final String userName;
private final String locationName;
@ -91,6 +93,7 @@ public abstract class SQLDB extends Database {
super(plugin);
this.plugin = plugin;
this.supportsModification = supportsModification;
transactionsActive = 0;
userName = "plan_users";
locationName = "plan_locations";
@ -438,11 +441,11 @@ public abstract class SQLDB extends Database {
commitRequired = true;
}
statement.executeBatch();
statement.close();
if (commitRequired) {
connection.commit();
}
}
statement.close();
connection.setAutoCommit(true);
} catch (SQLException e) {
@ -515,12 +518,12 @@ public abstract class SQLDB extends Database {
}
@Override
public UserData getUserData(UUID uuid) {
public void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors) {
checkConnection();
// Check if user is in the database
if (!wasSeenBefore(uuid)) {
plugin.logError(uuid + " was not found from the database!");
return null;
return;
}
List<World> worldList = Bukkit.getServer().getWorlds();
World defaultWorld = worldList.get(0);
@ -573,11 +576,12 @@ public abstract class SQLDB extends Database {
data.addSessions(getSessionData(userId));
data.setPlayerKills(getPlayerKills(userId));
for (DBCallableProcessor processor : processors) {
processor.process(data);
}
} catch (SQLException e) {
data = null;
e.printStackTrace();
}
return data;
}
private HashMap<GameMode, Long> getGMTimes(String userId) throws SQLException {
@ -718,8 +722,9 @@ public abstract class SQLDB extends Database {
connection.setAutoCommit(false);
PreparedStatement uStatement = connection.prepareStatement(uSQL);
boolean commitRequired = false;
transactionsActive++;
for (UserData uData : data) {
uData.setAccessing(true);
uData.access();
int userId = getUserId(uData.getUuid().toString());
if (userId == -1) {
saveLast.add(uData);
@ -745,30 +750,35 @@ public abstract class SQLDB extends Database {
uStatement.addBatch();
} catch (SQLException | NullPointerException e) {
saveLast.add(uData);
uData.setAccessing(false);
uData.stopAccessing();
continue;
}
uData.setAccessing(false);
uData.stopAccessing();
commitRequired = true;
}
uStatement.executeBatch();
uStatement.close();
transactionsActive--;
if (commitRequired) {
connection.commit();
}
uStatement.close();
connection.setAutoCommit(true);
if (noActiveTransaction()) {
connection.setAutoCommit(true);
}
data.removeAll(saveLast);
for (UserData uData : data) {
uData.setAccessing(true);
uData.access();
int userId = getUserId(uData.getUuid().toString());
saveLocationList(userId, uData.getLocations());
saveNickList(userId, uData.getNicknames(), uData.getLastNick());
saveIPList(userId, uData.getIps());
saveSessionList(userId, uData.getSessions());
savePlayerKills(userId, uData.getPlayerKills());
connection.setAutoCommit(true);
if (noActiveTransaction()) {
connection.setAutoCommit(true);
}
saveGMTimes(userId, uData.getGmTimes());
uData.setAccessing(false);
uData.stopAccessing();
}
for (UserData userData : saveLast) {
saveUserData(userData.getUuid(), userData);
@ -781,7 +791,7 @@ public abstract class SQLDB extends Database {
@Override
public void saveUserData(UUID uuid, UserData data) {
checkConnection();
data.setAccessing(true);
data.access();
int userId = getUserId(uuid.toString());
try {
int update = 0;
@ -854,30 +864,33 @@ public abstract class SQLDB extends Database {
statement.close();
userId = getUserId(uuid.toString());
}
connection.setAutoCommit(false);
saveLocationList(userId, data.getLocations());
saveNickList(userId, data.getNicknames(), data.getLastNick());
saveIPList(userId, data.getIps());
saveSessionList(userId, data.getSessions());
savePlayerKills(userId, data.getPlayerKills());
connection.setAutoCommit(true);
if (noActiveTransaction()) {
connection.setAutoCommit(true);
}
saveGMTimes(userId, data.getGmTimes());
} catch (SQLException | NullPointerException e) {
e.printStackTrace();
}
data.setAccessing(false);
data.stopAccessing();
}
public void saveLocationList(int userId, List<Location> locations) {
if (locations.isEmpty()) {
return;
}
transactionsActive++;
try {
PreparedStatement deleteStatement = connection.prepareStatement(
"DELETE FROM " + locationName + " WHERE UPPER(" + locationColumnUserID + ") LIKE UPPER(?)");
deleteStatement.setString(1, "" + userId);
deleteStatement.execute();
deleteStatement.close();
connection.setAutoCommit(false);
PreparedStatement saveStatement = connection.prepareStatement("INSERT INTO " + locationName + " ("
+ locationColumnUserID + ", "
+ locationColumnCoordinatesX + ", "
@ -908,19 +921,19 @@ public abstract class SQLDB extends Database {
} catch (SQLException e) {
e.printStackTrace();
}
transactionsActive--;
}
public void saveNickList(int userId, HashSet<String> names, String lastNick) {
if (names.isEmpty()) {
return;
}
transactionsActive++;
try {
PreparedStatement statement = connection.prepareStatement(
"DELETE FROM " + nicknamesName + " WHERE UPPER(" + nicknamesColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, "" + userId);
statement.execute();
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + nicknamesName + " ("
+ nicknamesColumnUserID + ", "
+ nicknamesColumnCurrent + ", "
@ -943,19 +956,19 @@ public abstract class SQLDB extends Database {
} catch (SQLException e) {
e.printStackTrace();
}
transactionsActive--;
}
public void saveSessionList(int userId, List<SessionData> sessions) {
if (sessions.isEmpty()) {
return;
}
transactionsActive++;
try {
PreparedStatement statement = connection.prepareStatement(
"DELETE FROM " + sessionName + " WHERE UPPER(" + sessionColumnUserID + ") LIKE UPPER(?)");
statement.setString(1, "" + userId);
statement.execute();
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + sessionName + " ("
+ sessionColumnUserID + ", "
+ sessionColumnSessionStart + ", "
@ -978,19 +991,19 @@ public abstract class SQLDB extends Database {
} catch (SQLException e) {
e.printStackTrace();
}
transactionsActive--;
}
public void savePlayerKills(int userId, List<KillData> kills) {
if (kills.isEmpty()) {
return;
}
transactionsActive++;
try {
PreparedStatement statement = connection.prepareStatement(
"DELETE FROM " + killsName + " WHERE UPPER(" + killsColumnKillerUserID + ") LIKE UPPER(?)");
statement.setString(1, "" + userId);
statement.execute();
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + killsName + " ("
+ killsColumnKillerUserID + ", "
+ killsColumnVictimUserID + ", "
@ -1015,12 +1028,14 @@ public abstract class SQLDB extends Database {
} catch (SQLException e) {
e.printStackTrace();
}
transactionsActive--;
}
public void saveIPList(int userId, HashSet<InetAddress> ips) {
if (ips.isEmpty()) {
return;
}
transactionsActive++;
try {
PreparedStatement statement = connection.prepareStatement(
"DELETE FROM " + ipsName + " WHERE UPPER(" + ipsColumnUserID + ") LIKE UPPER(?)");
@ -1028,7 +1043,6 @@ public abstract class SQLDB extends Database {
statement.execute();
statement.close();
connection.setAutoCommit(false);
statement = connection.prepareStatement("INSERT INTO " + ipsName + " ("
+ ipsColumnUserID + ", "
+ ipsColumnIP
@ -1049,6 +1063,7 @@ public abstract class SQLDB extends Database {
} catch (SQLException e) {
e.printStackTrace();
}
transactionsActive--;
}
public void saveGMTimes(int userId, HashMap<GameMode, Long> gamemodeTimes) {
@ -1128,4 +1143,8 @@ public abstract class SQLDB extends Database {
return connection;
}
private boolean noActiveTransaction() {
return transactionsActive == 0;
}
}

View File

@ -16,10 +16,10 @@ import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.AnalysisCacheHandler;
import main.java.com.djrapitops.plan.data.cache.InspectCacheHandler;
import main.java.com.djrapitops.plan.ui.Html;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.GameMode;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
import static org.bukkit.Bukkit.getOfflinePlayer;
/**
*
@ -74,9 +74,9 @@ public class Analysis {
while (rawData.size() != uuids.size()) {
uuids.stream()
.filter((uuid) -> (!added.contains(uuid)))
.forEach((uuid) -> {
UserData userData = inspectCache.getFromCache(uuid);
if (userData != null) {
.forEach((uuid) -> {
if (inspectCache.isCached(uuid)) {
UserData userData = inspectCache.getFromCache(uuid);
rawData.add(userData);
added.add(uuid);
}