Add more tests, fix null name bug

This commit is contained in:
nossr50
2021-04-13 12:41:23 -07:00
parent 5b4af3f9ce
commit f7339277f8
25 changed files with 491 additions and 128 deletions

View File

@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.database.DatabaseType;
import com.gmail.nossr50.datatypes.database.PlayerStat;
import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -92,12 +93,17 @@ public interface DatabaseManager {
*/
@NotNull PlayerProfile loadPlayerProfile(@NotNull String playerName);
default @NotNull PlayerProfile loadPlayerProfile(@NotNull OfflinePlayer offlinePlayer) {
return loadPlayerProfile(offlinePlayer.getUniqueId(), offlinePlayer.getName());
}
/**
* Load a player from the database.
*
* @param uuid The uuid of the player to load from the database
* @return The player's data, or an unloaded PlayerProfile if not found
* @deprecated Use {@link DatabaseManager#loadPlayerProfile(org.bukkit.OfflinePlayer)} if possible
*/
@Deprecated
@NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid, @Nullable String playerName);
/**

View File

@@ -9,12 +9,15 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.SkillTools;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.logging.Logger;
@@ -28,6 +31,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
private final @NotNull Logger logger;
private final long purgeTime;
private final int startingLevel;
private boolean testing;
private final long UPDATE_WAIT_TIME = 600000L; // 10 minutes
private final @NotNull File usersFile;
@@ -82,6 +86,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
this.logger = logger;
this.purgeTime = purgeTime;
this.startingLevel = startingLevel;
this.testing = testing;
if(!testing) {
List<FlatFileDataFlag> flatFileDataFlags = checkFileHealthAndStructure();
@@ -218,6 +223,10 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
// Write the new file
out = new FileWriter(usersFilePath);
out.write(writer.toString());
if(testing) {
System.out.println(writer.toString());
}
}
catch (IOException e) {
logger.severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e);
@@ -321,8 +330,19 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
String line;
boolean wroteUser = false;
if(testing) {
System.out.println("-- saveUser bufferedreader feed --");
}
// While not at the end of the file
while ((line = in.readLine()) != null) {
if(testing) {
System.out.println(line);
}
if(line.startsWith("#")) {
writer.append(line).append("\r\n");
continue;
}
//Check for incomplete or corrupted data
if(!line.contains(":")) {
@@ -365,6 +385,11 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
writeUserToLine(profile, playerName, uuid, writer);
}
if(testing) {
System.out.println("-- saveUser (FileWriter contents before save) --");
System.out.println(writer.toString());
}
// Write the new file
out = new FileWriter(usersFilePath);
out.write(writer.toString());
@@ -445,7 +470,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
public @NotNull List<PlayerStat> readLeaderboard(@Nullable PrimarySkillType primarySkillType, int pageNumber, int statsPerPage) throws InvalidSkillException {
//Fix for a plugin that people are using that is throwing SQL errors
if(primarySkillType != null && mcMMO.p.getSkillTools().isChildSkill(primarySkillType)) {
if(primarySkillType != null && SkillTools.isChildSkill(primarySkillType)) {
logger.severe("A plugin hooking into mcMMO is being naughty with our database commands, update all plugins that hook into mcMMO and contact their devs!");
throw new InvalidSkillException("A plugin hooking into mcMMO that you are using is attempting to read leaderboard skills for child skills, child skills do not have leaderboards! This is NOT an mcMMO error!");
}
@@ -462,7 +487,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
Map<PrimarySkillType, Integer> skills = new EnumMap<PrimarySkillType, Integer>(PrimarySkillType.class);
for (PrimarySkillType skill : mcMMO.p.getSkillTools().NON_CHILD_SKILLS) {
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
skills.put(skill, getPlayerRank(playerName, playerStatHash.get(skill)));
}
@@ -549,15 +574,19 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
}
}
public @NotNull PlayerProfile loadPlayerProfile(@NotNull OfflinePlayer offlinePlayer) {
return loadPlayerByUUID(offlinePlayer.getUniqueId(), offlinePlayer.getName(), offlinePlayer.isOnline());
}
public @NotNull PlayerProfile loadPlayerProfile(@NotNull String playerName) {
return loadPlayerByName(playerName);
}
public @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid, @Nullable String playerName) {
return loadPlayerByUUID(uuid, playerName);
return loadPlayerByUUID(uuid, playerName, false);
}
private @NotNull PlayerProfile loadPlayerByUUID(@NotNull UUID uuid, @Nullable String playerName) {
private @NotNull PlayerProfile loadPlayerByUUID(@NotNull UUID uuid, @Nullable String playerName, boolean isOnline) {
BufferedReader in = null;
synchronized (fileWritingLock) {
@@ -594,9 +623,13 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
/* Check for nickname changes and update since we are here anyways */
if (!rawSplitData[USERNAME_INDEX].equalsIgnoreCase(playerName)) {
//logger.info("Name updated for player: " + rawSplitData[USERNAME_INDEX] + " => " + playerName);
rawSplitData[USERNAME_INDEX] = playerName;
if(playerName != null) {
if(isOnline) {
if (!rawSplitData[USERNAME_INDEX].equalsIgnoreCase(playerName)) {
//logger.info("Name updated for player: " + rawSplitData[USERNAME_INDEX] + " => " + playerName);
rawSplitData[USERNAME_INDEX] = playerName;
}
}
}
return loadFromLine(rawSplitData);
@@ -969,15 +1002,39 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
playerStatHash.put(PrimarySkillType.ALCHEMY, alchemy);
}
/**
* Makes sure that the users file has valid entries
* @return
*/
private void initEmptyDB() {
BufferedWriter bufferedWriter = null;
synchronized (fileWritingLock) {
try {
// Open the file to write the player
bufferedWriter = new BufferedWriter(new FileWriter(usersFilePath, true));
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime localDateTime = LocalDateTime.now();
bufferedWriter.append("# mcMMO Database created on ").append(localDateTime.format(dateTimeFormatter)).append("\r\n"); //Empty file
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bufferedWriter != null) {
try {
bufferedWriter.close();
}
catch (IOException e) {
// Ignore
}
}
}
}
}
public @Nullable List<FlatFileDataFlag> checkFileHealthAndStructure() {
ArrayList<FlatFileDataFlag> flagsFound = null;
logger.info("(" + usersFile.getPath() + ") Validating database file..");
FlatFileDataProcessor dataProcessor = null;
if(!usersFile.exists()) {
initEmptyDB();
}
if (usersFile.exists()) {
BufferedReader bufferedReader = null;
FileWriter fileWriter = null;
@@ -988,10 +1045,18 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
try {
String currentLine;
String dbCommentDate = null;
bufferedReader = new BufferedReader(new FileReader(usersFilePath));
//Analyze the data
while ((currentLine = bufferedReader.readLine()) != null) {
//Commented lines
if(currentLine.startsWith("#") && dbCommentDate == null) { //The first commented line in the file is likely to be our note about when the file was created
dbCommentDate = currentLine;
continue;
}
if(currentLine.isEmpty())
continue;
@@ -1005,6 +1070,9 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
logger.info("Saving the updated and or repaired FlatFile Database...");
fileWriter = new FileWriter(usersFilePath);
//Write data to file
if(dbCommentDate != null)
fileWriter.write(dbCommentDate);
fileWriter.write(dataProcessor.processDataForSave().toString());
}
} catch (IOException e) {
@@ -1078,6 +1146,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
Map<SuperAbilityType, Integer> skillsDATS = new EnumMap<>(SuperAbilityType.class); // Ability & Cooldown
Map<UniqueDataType, Integer> uniquePlayerDataMap = new EnumMap<>(UniqueDataType.class);
int scoreboardTipsShown;
long lastLogin;
String username = character[USERNAME_INDEX];
@@ -1108,13 +1177,6 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
// Acrobatics - Unused
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BLAST_MINING, COOLDOWN_BLAST_MINING, username);
// try {
// mobHealthbarType = MobHealthbarType.valueOf(character[HEALTHBAR]);
// }
// catch (Exception e) {
// mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
// }
UUID uuid;
try {
uuid = UUID.fromString(character[UUID_INDEX]);
@@ -1137,7 +1199,13 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
uniquePlayerDataMap.put(UniqueDataType.CHIMAERA_WING_DATS, 0);
}
return new PlayerProfile(character[USERNAME_INDEX], uuid, skills, skillsXp, skillsDATS, null, scoreboardTipsShown, uniquePlayerDataMap);
try {
lastLogin = Long.parseLong(character[LAST_LOGIN]);
} catch (Exception e) {
lastLogin = System.currentTimeMillis();
}
return new PlayerProfile(character[USERNAME_INDEX], uuid, skills, skillsXp, skillsDATS, scoreboardTipsShown, uniquePlayerDataMap, lastLogin);
}
private void tryLoadSkillCooldownFromRawData(@NotNull Map<SuperAbilityType, Integer> cooldownMap, @NotNull String[] character, @NotNull SuperAbilityType superAbilityType, int cooldownSuperBreaker, @NotNull String userName) {

View File

@@ -12,6 +12,7 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
import com.gmail.nossr50.util.Misc;
import com.gmail.nossr50.util.skills.SkillTools;
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.bukkit.entity.Player;
@@ -174,8 +175,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
catch (SQLException ex) {
printErrors(ex);
}
finally {
} finally {
tryClose(statement);
tryClose(connection);
massUpdateLock.unlock();
@@ -271,7 +271,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
statement.setInt(12, profile.getSkillLevel(PrimarySkillType.FISHING));
statement.setInt(13, profile.getSkillLevel(PrimarySkillType.ALCHEMY));
int total = 0;
for (PrimarySkillType primarySkillType : mcMMO.p.getSkillTools().NON_CHILD_SKILLS)
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS)
total += profile.getSkillLevel(primarySkillType);
statement.setInt(14, total);
statement.setInt(15, id);
@@ -330,7 +330,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?, scoreboardtips = ? WHERE user_id = ?");
statement.setString(1, profile.getMobHealthbarType() == null ? mcMMO.p.getGeneralConfig().getMobHealthbarDefault().name() : profile.getMobHealthbarType().name());
statement.setString(1, MobHealthbarType.HEARTS.name());
statement.setInt(2, profile.getScoreboardTipsShown());
statement.setInt(3, id);
success = (statement.executeUpdate() != 0);
@@ -355,7 +355,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
List<PlayerStat> stats = new ArrayList<>();
//Fix for a plugin that people are using that is throwing SQL errors
if(skill != null && mcMMO.p.getSkillTools().isChildSkill(skill)) {
if(skill != null && SkillTools.isChildSkill(skill)) {
mcMMO.p.getLogger().severe("A plugin hooking into mcMMO is being naughty with our database commands, update all plugins that hook into mcMMO and contact their devs!");
throw new InvalidSkillException("A plugin hooking into mcMMO that you are using is attempting to read leaderboard skills for child skills, child skills do not have leaderboards! This is NOT an mcMMO error!");
}
@@ -404,7 +404,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
try {
connection = getConnection(PoolIdentifier.MISC);
for (PrimarySkillType primarySkillType : mcMMO.p.getSkillTools().NON_CHILD_SKILLS) {
for (PrimarySkillType primarySkillType : SkillTools.NON_CHILD_SKILLS) {
String skillName = primarySkillType.name().toLowerCase(Locale.ENGLISH);
// Get count of all users with higher skill level than player
String sql = "SELECT COUNT(*) AS 'rank' FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
@@ -932,7 +932,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
}
if (mcMMO.p.getGeneralConfig().getTruncateSkills()) {
for (PrimarySkillType skill : mcMMO.p.getSkillTools().NON_CHILD_SKILLS) {
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
int cap = mcMMO.p.getSkillTools().getLevelCap(skill);
if (cap != Integer.MAX_VALUE) {
statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase(Locale.ENGLISH) + "` = " + cap + " WHERE `" + skill.name().toLowerCase(Locale.ENGLISH) + "` > " + cap);
@@ -1152,14 +1152,6 @@ public final class SQLDatabaseManager implements DatabaseManager {
skillsDATS.put(SuperAbilityType.BLAST_MINING, result.getInt(OFFSET_DATS + 12));
uniqueData.put(UniqueDataType.CHIMAERA_WING_DATS, result.getInt(OFFSET_DATS + 13));
try {
mobHealthbarType = MobHealthbarType.valueOf(result.getString(OFFSET_OTHER + 1));
}
catch (Exception e) {
mobHealthbarType = mcMMO.p.getGeneralConfig().getMobHealthbarDefault();
}
try {
scoreboardTipsShown = result.getInt(OFFSET_OTHER + 2);
}
@@ -1174,7 +1166,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
uuid = null;
}
return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniqueData);
return new PlayerProfile(playerName, uuid, skills, skillsXp, skillsDATS, scoreboardTipsShown, uniqueData, null);
}
private void printErrors(SQLException ex) {
@@ -1291,10 +1283,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
resultSet = statement.executeQuery("SHOW INDEX FROM `" + tablePrefix + "skills` WHERE `Key_name` LIKE 'idx\\_%'");
resultSet.last();
if (resultSet.getRow() != mcMMO.p.getSkillTools().NON_CHILD_SKILLS.size()) {
if (resultSet.getRow() != SkillTools.NON_CHILD_SKILLS.size()) {
mcMMO.p.getLogger().info("Indexing tables, this may take a while on larger databases");
for (PrimarySkillType skill : mcMMO.p.getSkillTools().NON_CHILD_SKILLS) {
for (PrimarySkillType skill : SkillTools.NON_CHILD_SKILLS) {
String skill_name = skill.name().toLowerCase(Locale.ENGLISH);
try {