[2.6.0-DEV] Improved Error Handling and Bugfixes & Small things

- Better error handling & logging. Implemented for SQLDB.java - other
catch clauses yet to be changed.
This was done mainly to be able to run Debugger tests on it.

Bugfixes:
- DB Auto-Commit bug #12 fixed
- New DB creation was no-longer execption free after adding throws
clauses, fixed that.

Bugs:
- SQLException: The prepared statement has been finalized when closing
database on disable, cause yet unknown
- "___ added to cache" called 5-6 times when player joins

Untested:
- Events
- SessionData
- KillData
- Does DB save everything or just plan_users

UnImplemented:
- Location adding in baches
- Location data getting seperately for analysis, not saved to UserData
to speed up get.
- 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-17 12:26:13 +02:00
parent d706d3431f
commit ab03c43204
27 changed files with 857 additions and 870 deletions

View File

@ -73,13 +73,14 @@ public enum Phrase {
ANALYSIS_FAIL_NO_DATA(ANALYSIS + "Analysis failed, no data in the database."),
ANALYSIS_BEGIN_ANALYSIS(ANALYSIS + "Data Fetched, beginning Analysis of data.."),
ANALYSIS_COMPLETE(ANALYSIS + "Analysis Complete."),
DATA_CORRUPTION_WARN("Some data might be corrupted: "+REPLACE0),
DATA_CORRUPTION_WARN("Some data might be corrupted: " + REPLACE0),
//
ERROR_PLANLITE("PlanLite not found, if you're have plugins using PlanAPI v1.6.0 download PlanLite."),
ERROR_CONSOLE_PLAYER("This point of code should not be accessable on console. Inform author: "+REPLACE0+" Console: REPLACE1"),
ERROR_CONSOLE_PLAYER("This point of code should not be accessable on console. Inform author: " + REPLACE0 + " Console: REPLACE1"),
ERROR_NO_DATA_VIEW(ChatColor.YELLOW + "Webserver disabled but Alternative IP/PlanLite not used, no way to view data!"),
ERROR_WEBSERVER_OFF_ANALYSIS(ChatColor.YELLOW + "" + PREFIX + "This command can be only used if the webserver is running on this server."),
ERROR_WEBSERVER_OFF_INSPECT(ChatColor.YELLOW + "" + PREFIX + "This command can be only used if webserver/planlite is enabled on this server."),
ERROR_LOGGED("Ran into an error. It has been logged to the Errors.txt"),
//
CMD_FOOTER(COLOR_TER.color() + "" + ARROWS_RIGHT),
MANAGE_ERROR_INCORRECT_PLUGIN(ChatColor.RED + "" + PREFIX + "Plugin not supported: "),
@ -93,6 +94,7 @@ public enum Phrase {
MANAGE_ERROR_BACKUP_FILE_NOT_FOUND(ChatColor.RED + "" + PREFIX + "Backup file doesn't exist!"),
MANAGE_MOVE_SUCCESS(ChatColor.GREEN + "" + PREFIX + "All data moved successfully!"),
MANAGE_COPY_SUCCESS(ChatColor.GREEN + "" + PREFIX + "All data copied successfully!"),
MANAGE_PROCESS_FAIL(ChatColor.RED + "" + PREFIX + "Something went wrong while processing the data!"),
MANAGE_CLEAR_SUCCESS(ChatColor.GREEN + "" + PREFIX + "All data cleared successfully!"),
MANAGE_REMOVE_SUCCESS(CMD_FOOTER + " " + COLOR_MAIN.color() + "Data of " + COLOR_TER.color() + "REPLACE0" + COLOR_MAIN.color() + " was removed from Database " + COLOR_TER.color() + "REPLACE1" + COLOR_MAIN.color() + "."),
MANAGE_IMPORTING(CMD_FOOTER + " " + COLOR_MAIN.color() + " Importing Data.."),
@ -215,7 +217,7 @@ public enum Phrase {
String[] split = localeRow.split(" <> ");
Phrase.valueOf(split[0]).setText(split[1]);
} catch (IllegalArgumentException e) {
getPlugin(Plan.class).logError("There is a miswritten line in locale on line "+localeRows.indexOf(localeRow));
getPlugin(Plan.class).logError("There is a miswritten line in locale on line " + localeRows.indexOf(localeRow));
}
}
} catch (IOException e) {

View File

@ -22,10 +22,13 @@ package main.java.com.djrapitops.plan;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.concurrent.Executors;
@ -38,6 +41,7 @@ import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.database.databases.*;
import main.java.com.djrapitops.plan.ui.Html;
import main.java.com.djrapitops.plan.ui.webserver.WebSocketServer;
import main.java.com.djrapitops.plan.utilities.FormatUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.ConsoleCommandSender;
@ -180,6 +184,42 @@ public class Plan extends JavaPlugin {
getLogger().severe(message);
}
public void toLog(String source, Exception e) {
logError(Phrase.ERROR_LOGGED + "");
toLog(source + " Caught " + e);
for (StackTraceElement x : e.getStackTrace()) {
toLog(" " + x);
}
toLog("");
}
public void toLog(String source, Collection<Exception> e) {
for (Exception ex : e) {
toLog(source, ex);
}
}
public void toLog(String message) {
File folder = getDataFolder();
if (!folder.exists()) {
folder.mkdir();
}
File log = new File(getDataFolder(), "Errors.txt");
try {
if (!log.exists()) {
log.createNewFile();
}
FileWriter fw = new FileWriter(log, true);
try (PrintWriter pw = new PrintWriter(fw)) {
String timestamp = FormatUtils.formatTimeStamp(new Date().getTime() + "");
pw.println("[" + timestamp + "] " + message);
pw.flush();
}
} catch (IOException e) {
getLogger().severe("Failed to create DBerrors.txt file");
}
}
/**
* @return Plan API
*/
@ -210,7 +250,6 @@ public class Plan extends JavaPlugin {
String type = Settings.DB_TYPE + "";
db = null;
for (Database database : databases) {
if (type.equalsIgnoreCase(database.getConfigName())) {
this.db = database;
@ -218,12 +257,10 @@ public class Plan extends JavaPlugin {
break;
}
}
if (db == null) {
log(Phrase.DATABASE_TYPE_DOES_NOT_EXIST.toString());
return false;
}
if (!db.init()) {
log(Phrase.DATABASE_FAILURE_DISABLE.toString());
setEnabled(false);

View File

@ -11,7 +11,6 @@ import main.java.com.djrapitops.plan.utilities.HtmlUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.UUIDFetcher;
import org.bukkit.Bukkit;
import static org.bukkit.Bukkit.getOfflinePlayer;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -19,8 +18,6 @@ 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

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -76,6 +77,7 @@ public class ManageBackupCommand extends SubCommand {
(new BukkitRunnable() {
@Override
public void run() {
try {
Date now = new Date();
SQLiteDB backupDB = new SQLiteDB(plugin,
args[0] + "-backup-" + now.toString().substring(4, 10).replaceAll(" ", "-").replaceAll(":", "-"));
@ -103,6 +105,10 @@ public class ManageBackupCommand extends SubCommand {
backupDB.saveMultipleUserData(allUserData);
backupDB.saveCommandUse(copyFromDB.getCommandUse());
sender.sendMessage(Phrase.MANAGE_COPY_SUCCESS.toString());
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL.toString());
}
this.cancel();
}
}).runTaskAsynchronously(plugin);

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.sql.SQLException;
import java.util.Arrays;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
@ -15,7 +16,7 @@ import org.bukkit.scheduler.BukkitRunnable;
* @author Rsl1122
*/
public class ManageClearCommand extends SubCommand {
private final Plan plugin;
/**
@ -24,8 +25,8 @@ public class ManageClearCommand extends SubCommand {
* @param plugin Current instance of Plan
*/
public ManageClearCommand(Plan plugin) {
super("clear", "plan.manage", Phrase.CMD_USG_MANAGE_CLEAR+"", CommandType.CONSOLE_WITH_ARGUMENTS, "<DB> [-a]");
super("clear", "plan.manage", Phrase.CMD_USG_MANAGE_CLEAR + "", CommandType.CONSOLE_WITH_ARGUMENTS, "<DB> [-a]");
this.plugin = plugin;
}
@ -57,7 +58,7 @@ public class ManageClearCommand extends SubCommand {
sender.sendMessage(Phrase.COMMAND_ADD_CONFIRMATION_ARGUMENT.parse(Phrase.WARN_REMOVE.parse(args[0])));
return true;
}
Database clearDB = null;
for (Database database : plugin.getDatabases()) {
if (dbToClear.equalsIgnoreCase(database.getConfigName())) {
@ -70,14 +71,22 @@ public class ManageClearCommand extends SubCommand {
plugin.logError(dbToClear + " was null!");
return true;
}
final Database clearThisDB = clearDB;
(new BukkitRunnable() {
@Override
public void run() {
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
clearThisDB.removeAllData();
sender.sendMessage(Phrase.MANAGE_CLEAR_SUCCESS+"");
try {
if (clearThisDB.removeAllData()) {
sender.sendMessage(Phrase.MANAGE_CLEAR_SUCCESS + "");
} else {
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
this.cancel();
}
}).runTaskAsynchronously(plugin);

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@ -17,6 +18,7 @@ import main.java.com.djrapitops.plan.utilities.DataCombineUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitTask;
/**
*
@ -96,10 +98,9 @@ public class ManageCombineCommand extends SubCommand {
plugin.logError(toDB + " was null!");
return true;
}
final Set<UUID> fromUUIDS = fromDatabase.getSavedUUIDs();
final Set<UUID> toUUIDS = toDatabase.getSavedUUIDs();
try {
final Set<UUID> fromUUIDS = fromDatabase.getSavedUUIDs();
final Set<UUID> toUUIDS = toDatabase.getSavedUUIDs();
if (fromUUIDS.isEmpty() && toUUIDS.isEmpty()) {
sender.sendMessage(Phrase.MANAGE_ERROR_NO_PLAYERS + " (" + fromDB + ")");
return true;
@ -107,55 +108,60 @@ public class ManageCombineCommand extends SubCommand {
final Database moveFromDB = fromDatabase;
final Database moveToDB = toDatabase;
(new BukkitRunnable() {
BukkitTask asyncDBCombineTask = (new BukkitRunnable() {
@Override
public void run() {
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
HashMap<UUID, UserData> allFromUserData = new HashMap<>();
HashMap<UUID, UserData> allToUserData = new HashMap<>();
for (UUID uuid : fromUUIDS) {
moveFromDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allFromUserData.put(uuid, data);
}
});
}
for (UUID uuid : toUUIDS) {
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);
uuids.addAll(fromUUIDS);
try {
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
HashMap<UUID, UserData> allFromUserData = new HashMap<>();
HashMap<UUID, UserData> allToUserData = new HashMap<>();
for (UUID uuid : fromUUIDS) {
moveFromDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allFromUserData.put(uuid, data);
}
});
}
for (UUID uuid : toUUIDS) {
moveToDB.giveUserDataToProcessors(uuid, new DBCallableProcessor() {
@Override
public void process(UserData data) {
allToUserData.put(uuid, data);
}
});
}
while (fromUUIDS.size() > allFromUserData.size() || toUUIDS.size() > allToUserData.size()) {
List<UserData> combinedUserData = DataCombineUtils.combineUserDatas(allFromUserData, allToUserData, uuids);
}
Set<UUID> uuids = new HashSet<>();
uuids.addAll(toUUIDS);
uuids.addAll(fromUUIDS);
HashMap<String, Integer> commandUse = DataCombineUtils.combineCommandUses(moveFromDB.getCommandUse(), moveToDB.getCommandUse());
List<UserData> combinedUserData = DataCombineUtils.combineUserDatas(allFromUserData, allToUserData, uuids);
moveToDB.removeAllData();
HashMap<String, Integer> commandUse = DataCombineUtils.combineCommandUses(moveFromDB.getCommandUse(), moveToDB.getCommandUse());
moveToDB.saveMultipleUserData(combinedUserData);
moveToDB.saveCommandUse(commandUse);
moveToDB.removeAllData();
sender.sendMessage(Phrase.MANAGE_MOVE_SUCCESS + "");
if (!toDB.equals(plugin.getDB().getConfigName())) {
sender.sendMessage(Phrase.MANAGE_DB_CONFIG_REMINDER + "");
moveToDB.saveMultipleUserData(combinedUserData);
moveToDB.saveCommandUse(commandUse);
sender.sendMessage(Phrase.MANAGE_MOVE_SUCCESS + "");
if (!toDB.equals(plugin.getDB().getConfigName())) {
sender.sendMessage(Phrase.MANAGE_DB_CONFIG_REMINDER + "");
}
} catch (SQLException | NullPointerException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
this.cancel();
}
}).runTaskAsynchronously(plugin);
} catch (NullPointerException e) {
sender.sendMessage(Phrase.MANAGE_DATABASE_FAILURE + "");
} catch (SQLException | NullPointerException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
return true;
}

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.sql.SQLException;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.command.CommandType;
@ -60,7 +61,8 @@ public class ManageHotswapCommand extends SubCommand {
db.getVersion(); //Test db connection
}
}
} catch (NullPointerException e) {
} catch (NullPointerException | SQLException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_DATABASE_FAILURE + "");
return true;
}

View File

@ -23,7 +23,6 @@ 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;
/**
*

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -95,7 +96,14 @@ public class ManageMoveCommand extends SubCommand {
plugin.logError(toDB + " was null!");
return true;
}
final Set<UUID> uuids = fromDatabase.getSavedUUIDs();
final Set<UUID> uuids;
try {
uuids = fromDatabase.getSavedUUIDs();
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
return true;
}
if (uuids.isEmpty()) {
sender.sendMessage(Phrase.MANAGE_ERROR_NO_PLAYERS + " (" + fromDB + ")");
return true;
@ -118,8 +126,8 @@ public class ManageMoveCommand extends SubCommand {
}
});
}
while(uuids.size() > allUserData.size()) {
while (uuids.size() > allUserData.size()) {
}
moveToDB.saveMultipleUserData(allUserData);
moveToDB.saveCommandUse(moveFromDB.getCommandUse());
@ -127,8 +135,9 @@ public class ManageMoveCommand extends SubCommand {
if (!toDB.equals(plugin.getDB().getConfigName())) {
sender.sendMessage(Phrase.MANAGE_DB_CONFIG_REMINDER + "");
}
} catch (NullPointerException e) {
sender.sendMessage(Phrase.MANAGE_DATABASE_FAILURE + "");
} catch (SQLException | NullPointerException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
this.cancel();

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.UUID;
import main.java.com.djrapitops.plan.Phrase;
@ -13,7 +14,6 @@ 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;
/**
*
@ -29,7 +29,7 @@ public class ManageRemoveCommand extends SubCommand {
* @param plugin Current instance of Plan
*/
public ManageRemoveCommand(Plan plugin) {
super("remove", "plan.manage", Phrase.CMD_USG_MANAGE_REMOVE+"", CommandType.CONSOLE_WITH_ARGUMENTS, Phrase.ARG_PLAYER+" [-a]");
super("remove", "plan.manage", Phrase.CMD_USG_MANAGE_REMOVE + "", CommandType.CONSOLE_WITH_ARGUMENTS, Phrase.ARG_PLAYER + " [-a]");
this.plugin = plugin;
}
@ -79,14 +79,22 @@ public class ManageRemoveCommand extends SubCommand {
sender.sendMessage(Phrase.COMMAND_ADD_CONFIRMATION_ARGUMENT.parse(Phrase.WARN_REMOVE.parse(plugin.getDB().getConfigName())));
return true;
}
(new BukkitRunnable() {
@Override
public void run() {
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
plugin.getHandler().clearFromCache(uuid);
plugin.getDB().removeAccount(uuid.toString());
sender.sendMessage(Phrase.MANAGE_REMOVE_SUCCESS.parse(playerName, plugin.getDB().getConfigName()));
try {
plugin.getHandler().clearFromCache(uuid);
if (plugin.getDB().removeAccount(uuid.toString())) {
sender.sendMessage(Phrase.MANAGE_REMOVE_SUCCESS.parse(playerName, plugin.getDB().getConfigName()));
} else {
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
this.cancel();
}
}).runTaskAsynchronously(plugin);

View File

@ -1,6 +1,7 @@
package main.java.com.djrapitops.plan.command.commands.manage;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -33,7 +34,7 @@ public class ManageRestoreCommand extends SubCommand {
* @param plugin Current instance of Plan
*/
public ManageRestoreCommand(Plan plugin) {
super("restore", "plan.restore", Phrase.CMD_USG_MANAGE_RESTORE+"", CommandType.CONSOLE, Phrase.ARG_RESTORE+"");
super("restore", "plan.restore", Phrase.CMD_USG_MANAGE_RESTORE + "", CommandType.CONSOLE, Phrase.ARG_RESTORE + "");
this.plugin = plugin;
}
@ -51,7 +52,7 @@ public class ManageRestoreCommand extends SubCommand {
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
try {
if (args.length < 2) {
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.parse(Phrase.USE_RESTORE+""));
sender.sendMessage(Phrase.COMMAND_REQUIRES_ARGUMENTS.parse(Phrase.USE_RESTORE + ""));
return true;
}
String db = args[1].toLowerCase();
@ -82,41 +83,46 @@ public class ManageRestoreCommand extends SubCommand {
BukkitTask asyncRestoreTask = (new BukkitRunnable() {
@Override
public void run() {
String backupDBName = args[0];
try {
String backupDBName = args[0];
File backupDBFile = new File(plugin.getDataFolder(), backupDBName + (backupDBName.contains(".db") ? "" : ".db"));
if (!backupDBFile.exists()) {
sender.sendMessage(Phrase.MANAGE_ERROR_BACKUP_FILE_NOT_FOUND + " "+args[0]);
this.cancel();
return;
File backupDBFile = new File(plugin.getDataFolder(), backupDBName + (backupDBName.contains(".db") ? "" : ".db"));
if (!backupDBFile.exists()) {
sender.sendMessage(Phrase.MANAGE_ERROR_BACKUP_FILE_NOT_FOUND + " " + args[0]);
this.cancel();
return;
}
if (backupDBName.contains(".db")) {
backupDBName = backupDBName.replace(".db", "");
}
SQLiteDB backupDB = new SQLiteDB(plugin, backupDBName);
if (!backupDB.init()) {
sender.sendMessage(Phrase.MANAGE_DATABASE_FAILURE + "");
this.cancel();
return;
}
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
copyToDB.removeAllData();
Set<UUID> uuids = backupDB.getSavedUUIDs();
List<UserData> allUserData = new ArrayList<>();
for (UUID uuid : uuids) {
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());
sender.sendMessage(Phrase.MANAGE_COPY_SUCCESS.toString());
} catch (SQLException | NullPointerException e) {
plugin.toLog(this.getClass().getName(), e);
sender.sendMessage(Phrase.MANAGE_PROCESS_FAIL + "");
}
if (backupDBName.contains(".db")) {
backupDBName = backupDBName.replace(".db", "");
}
SQLiteDB backupDB = new SQLiteDB(plugin, backupDBName);
if (!backupDB.init()) {
sender.sendMessage(Phrase.MANAGE_DATABASE_FAILURE + "");
this.cancel();
return;
}
sender.sendMessage(Phrase.MANAGE_PROCESS_START.parse());
copyToDB.removeAllData();
Set<UUID> uuids = backupDB.getSavedUUIDs();
List<UserData> allUserData = new ArrayList<>();
for (UUID uuid : uuids) {
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());
sender.sendMessage(Phrase.MANAGE_COPY_SUCCESS.toString());
this.cancel();
}
}).runTaskAsynchronously(plugin);

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.data.cache;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@ -32,8 +33,8 @@ public class DataCacheHandler {
private final DemographicsHandler demographicsHandler;
private final BasicInfoHandler basicInfoHandler;
private final RuleBreakingHandler ruleBreakingHandler;
private final HashMap<String, Integer> commandUse;
private final CommandUseHandler commandUseHandler;
private HashMap<String, Integer> commandUse;
private CommandUseHandler commandUseHandler;
private final KillHandler killHandler;
private final SessionHandler sessionHandler;
private final Database db;
@ -60,15 +61,21 @@ public class DataCacheHandler {
demographicsHandler = new DemographicsHandler(plugin, this);
basicInfoHandler = new BasicInfoHandler(plugin, this);
ruleBreakingHandler = new RuleBreakingHandler(plugin, this);
commandUse = db.getCommandUse();
commandUseHandler = new CommandUseHandler(commandUse);
newPlayerCreator = new NewPlayerCreator(plugin, this);
killHandler = new KillHandler(plugin);
sessionHandler = new SessionHandler(plugin);
timesSaved = 0;
maxPlayers = plugin.getServer().getMaxPlayers();
try {
commandUse = db.getCommandUse();
commandUseHandler = new CommandUseHandler(commandUse);
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
plugin.logError(Phrase.DATABASE_FAILURE_DISABLE + "");
plugin.getServer().getPluginManager().disablePlugin(plugin);
}
int minutes = Settings.SAVE_CACHE_MIN.getNumber();
if (minutes <= 0) {
minutes = 5;
@ -90,7 +97,6 @@ public class DataCacheHandler {
handler.clearCache();
}
saveCommandUse();
handler.clearNulls();
timesSaved++;
}
}).runTaskTimerAsynchronously(plugin, 60 * 20 * minutes, 60 * 20 * minutes);
@ -122,7 +128,12 @@ public class DataCacheHandler {
}
}
};
db.giveUserDataToProcessors(uuid, cacher, processor);
try {
db.giveUserDataToProcessors(uuid, cacher, processor);
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
this.cancel();
}
} else {
processor.process(uData);
}
@ -147,12 +158,17 @@ public class DataCacheHandler {
* Saves all data in the cache to Database with AsyncTasks
*/
public void saveCachedUserData() {
clearNulls();
BukkitTask asyncFullCacheSaveTask = (new BukkitRunnable() {
@Override
public void run() {
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
db.saveMultipleUserData(data);
try {
db.saveMultipleUserData(data);
} catch (SQLException ex) {
plugin.toLog(this.getClass().getName(), ex);
}
timesSaved++;
this.cancel();
}
@ -163,14 +179,19 @@ public class DataCacheHandler {
* Saves all data in the cache to Database and closes the database down.
*/
public void saveCacheOnDisable() {
clearNulls();
List<UserData> data = new ArrayList<>();
data.addAll(dataCache.values());
data.parallelStream().forEach((userData) -> {
sessionHandler.endSession(userData);
});
db.saveMultipleUserData(data);
db.saveCommandUse(commandUse);
db.close();
try {
db.saveMultipleUserData(data);
db.saveCommandUse(commandUse);
db.close();
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
/**
@ -179,11 +200,16 @@ 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) {
db.saveUserData(uuid, dataCache.get(uuid));
try {
db.saveUserData(uuid, dataCache.get(uuid));
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
this.cancel();
}
@ -197,7 +223,11 @@ public class DataCacheHandler {
* Data is saved on a new line with a long value matching current Date
*/
public void saveCommandUse() {
db.saveCommandUse(commandUse);
try {
db.saveCommandUse(commandUse);
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
// Should only be called from Async thread
@ -270,7 +300,7 @@ public class DataCacheHandler {
(new BukkitRunnable() {
@Override
public void run() {
if (entry.getValue().isAccessed()) {
if (!entry.getValue().isAccessed()) {
entry.setValue(null);
plugin.log("Cleared " + entry.getKey().toString() + " from Cache. (Delay task)");
this.cancel();

View File

@ -5,9 +5,6 @@ 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 org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
/**
*

View File

@ -4,7 +4,6 @@ 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;
/**
*

View File

@ -13,8 +13,6 @@ import main.java.com.djrapitops.plan.api.Gender;
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 org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
/**
*
@ -42,16 +40,15 @@ public class DemographicsHandler {
* If message contains triggerwords and words that define data important,
* informatino will be saved in the DemographicsData of UserData provided
*
* @param event The Chat event passed by listener
* @param message Chat Message
* @param data UserData corresponding to player of this event.
*/
public void handleChatEvent(AsyncPlayerChatEvent event, UserData data) {
public void handleChatEvent(String message, UserData data) {
List<String> triggers = Arrays.asList(Settings.DEM_TRIGGERS.toString().split(", "));
List<String> female = Arrays.asList(Settings.DEM_FEMALE.toString().split(", "));
List<String> male = Arrays.asList(Settings.DEM_MALE.toString().split(", "));
List<String> ignore = Arrays.asList(Settings.DEM_IGNORE.toString().split(", "));
String message = event.getMessage();
String[] messageA = message.toLowerCase().split("\\s+");
boolean trigger = false;

View File

@ -5,10 +5,6 @@ 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.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
/**
*

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.data.handlers;
import java.sql.SQLException;
import java.util.Date;
import java.util.UUID;
import main.java.com.djrapitops.plan.Plan;
@ -19,7 +20,13 @@ public class KillHandler {
public void handlePlayerKill(UserData killerData, UUID victimUUID, String weapon) {
long now = new Date().toInstant().getEpochSecond()*(long)1000;
int victimID = plugin.getDB().getUserId(victimUUID+"");
int victimID;
try {
victimID = plugin.getDB().getUserId(victimUUID+"");
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
return;
}
killerData.addPlayerKill(new KillData(victimUUID, victimID, weapon, now));
}

View File

@ -1,5 +1,6 @@
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;
@ -59,7 +60,11 @@ public class NewPlayerCreator {
data.setLastGmSwapTime(zero);
data.setDeaths(0);
data.setMobKills(0);
db.saveUserData(player.getUniqueId(), data);
try {
db.saveUserData(player.getUniqueId(), data);
} catch (SQLException e) {
plugin.toLog(this.getClass().getName(), e);
}
}
}

View File

@ -1,12 +1,8 @@
package main.java.com.djrapitops.plan.data.handlers;
import java.util.Date;
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.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent;
/**
*
@ -43,7 +39,6 @@ public class RuleBreakingHandler {
*/
public void handleKick(UserData data) {
data.setTimesKicked(data.getTimesKicked() + 1);
data.setPlayTime(data.getPlayTime() + (new Date().getTime() - data.getLastPlayed()));
data.setLastPlayed(new Date().getTime());
handler.getActivityHandler().handleLogOut(data);
}
}

View File

@ -50,7 +50,7 @@ public class PlanChatListener implements Listener {
@Override
public void process(UserData data) {
basicInfoH.addNickname(p.getDisplayName(), data);
demographicsHandler.handleChatEvent(event, data);
demographicsHandler.handleChatEvent(event.getMessage(), data);
}
};
handler.getUserDataForProcessing(chatProcessor, p.getUniqueId());

View File

@ -14,7 +14,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scheduler.BukkitRunnable;
/**
*

View File

@ -1,5 +1,6 @@
package main.java.com.djrapitops.plan.database;
import java.sql.SQLException;
import java.util.*;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.UserData;
@ -14,114 +15,31 @@ public abstract class Database {
private final Plan plugin;
/**
* Abstract class constructor.
*
* @param plugin Current instance of Plan
*/
public Database(Plan plugin) {
this.plugin = plugin;
}
/**
* Initiates the Database.
*
* @return false
*/
public boolean init() {
public boolean init(){
return false;
}
/**
* Returns the UserData fetched from the Database.
*
* @param uuid UUID of Player
* @param processors The DBCallableProcessor Objects used to process data after async
* get task is complete.
*/
public abstract void giveUserDataToProcessors(UUID uuid, DBCallableProcessor... processors);
/**
* Saves the UserData to the Database.
*
* @param uuid UUID of Player
* @param data UserData of Player
*/
public abstract void saveUserData(UUID uuid, UserData data);
/**
* Saves multiple UserData to the Database using batch processing.
*
* @param data List of Data
*/
public abstract void saveMultipleUserData(List<UserData> data);
/**
* Check if the player is found in the database.
*
* @param uuid UUID of Player
* @return true if player is found in the database
*/
public abstract void giveUserDataToProcessors(UUID uuid, 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);
/**
* Cleans the database.
*/
public abstract void clean();
/**
* Used by the Config section.
*
* @return
*/
public abstract String getName();
/**
* Used by the Config section.
*
* @return
*/
public String getConfigName() {
return getName().toLowerCase().replace(" ", "");
}
/**
* Used by the Config section.
*
* @return
*/
public ConfigurationSection getConfigSection() {
return plugin.getConfig().getConfigurationSection(getConfigName());
}
/**
* Get the version of the database in case of updates.
*
* @return Current version of the database
*/
public abstract int getVersion();
/**
* Set the version of the database.
*
* @param version Version number
*/
public abstract void setVersion(int version);
/**
* 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);
public abstract int getVersion() throws SQLException;
public abstract void setVersion(int version) throws SQLException;
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 Set<UUID> getSavedUUIDs() throws SQLException;
public abstract HashMap<String, Integer> getCommandUse() throws SQLException;
public abstract int getUserId(String uuid) throws SQLException;
}

View File

@ -36,8 +36,9 @@ public class MySQLDB extends SQLDB {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://" + config.getString("mysql.host") + ":" + config.getString("mysql.port") + "/" + config.getString("mysql.database");
return DriverManager.getConnection(url, config.getString("mysql.user"), config.getString("mysql.password"));
Connection connection = DriverManager.getConnection(url, config.getString("mysql.user"), config.getString("mysql.password"));
return connection;
} catch (ClassNotFoundException | SQLException e) {
getPlugin(Plan.class).logError(Phrase.DB_CONNECTION_FAIL.parse(getConfigName(), e.getMessage()));
return null;

View File

@ -44,8 +44,9 @@ public class SQLiteDB extends SQLDB {
public Connection getNewConnection(String dbName) {
try {
Class.forName("org.sqlite.JDBC");
return DriverManager.getConnection("jdbc:sqlite:" + new File(plugin.getDataFolder(), dbName+".db").getAbsolutePath());
Connection connection = DriverManager.getConnection("jdbc:sqlite:" + new File(plugin.getDataFolder(), dbName+".db").getAbsolutePath());
return connection;
} catch (ClassNotFoundException | SQLException e) {
return null;
}

View File

@ -12,7 +12,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Phrase;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.SessionData;

View File

@ -74,7 +74,7 @@ public class Analysis {
while (rawData.size() != uuids.size()) {
uuids.stream()
.filter((uuid) -> (!added.contains(uuid)))
.forEach((uuid) -> {
.forEach((uuid) -> {
if (inspectCache.isCached(uuid)) {
UserData userData = inspectCache.getFromCache(uuid);
rawData.add(userData);
@ -84,7 +84,7 @@ public class Analysis {
}
// Create empty Dataset
final RawAnalysisData sorted = new RawAnalysisData();
sorted.setCommandUse(plugin.getDB().getCommandUse());
sorted.setCommandUse(plugin.getHandler().getCommandUse());
log(Phrase.ANALYSIS_BEGIN_ANALYSIS + "");
AnalysisData analysisData = new AnalysisData();
@ -134,6 +134,7 @@ public class Analysis {
sorted.getRegistered().add(uData.getRegistered());
} catch (NullPointerException e) {
plugin.logError(Phrase.DATA_CORRUPTION_WARN.parse(uData.getUuid() + ""));
plugin.toLog(this.getClass().getName(), e);
}
});
@ -237,12 +238,16 @@ public class Analysis {
private List<UUID> fetchPlayersInDB() {
final List<UUID> uuids = new ArrayList<>();
log(Phrase.ANALYSIS_FETCH_PLAYERS + "");
Set<UUID> savedUUIDs = plugin.getDB().getSavedUUIDs();
savedUUIDs.parallelStream()
.filter((uuid) -> (getOfflinePlayer(uuid).hasPlayedBefore()))
.forEach((uuid) -> {
uuids.add(uuid);
});
try {
Set<UUID> savedUUIDs = plugin.getDB().getSavedUUIDs();
savedUUIDs.parallelStream()
.filter((uuid) -> (getOfflinePlayer(uuid).hasPlayedBefore()))
.forEach((uuid) -> {
uuids.add(uuid);
});
} catch (Exception e) {
plugin.toLog(this.getClass().getName(), e);
}
return uuids;
}