mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-29 08:36:45 +01:00
More safety against corrupt data when loading data for FlatFile
This commit is contained in:
parent
d77c8c88a3
commit
2203d61c10
@ -385,6 +385,7 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writeUserToLine(PlayerProfile profile, String playerName, UUID uuid, StringBuilder writer) {
|
private void writeUserToLine(PlayerProfile profile, String playerName, UUID uuid, StringBuilder writer) {
|
||||||
|
// FlyingMonkey_:0:::0:0:0:0:0:0:0:0:0:0:5:0:156:460:
|
||||||
writer.append(playerName).append(":");
|
writer.append(playerName).append(":");
|
||||||
writer.append(profile.getSkillLevel(PrimarySkillType.MINING)).append(":");
|
writer.append(profile.getSkillLevel(PrimarySkillType.MINING)).append(":");
|
||||||
writer.append(":");
|
writer.append(":");
|
||||||
@ -936,6 +937,8 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
|||||||
HashSet<String> players = new HashSet<>();
|
HashSet<String> players = new HashSet<>();
|
||||||
|
|
||||||
while ((line = in.readLine()) != null) {
|
while ((line = in.readLine()) != null) {
|
||||||
|
String oldVersion = null;
|
||||||
|
|
||||||
// Remove empty lines from the file
|
// Remove empty lines from the file
|
||||||
if (line.isEmpty()) {
|
if (line.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
@ -968,8 +971,6 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String oldVersion = null;
|
|
||||||
|
|
||||||
if (character.length > 33 && !character[33].isEmpty()) {
|
if (character.length > 33 && !character[33].isEmpty()) {
|
||||||
// Removal of Spout Support
|
// Removal of Spout Support
|
||||||
// Version 1.4.07-dev2
|
// Version 1.4.07-dev2
|
||||||
@ -984,11 +985,21 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
|||||||
if (Config.getInstance().getTruncateSkills()) {
|
if (Config.getInstance().getTruncateSkills()) {
|
||||||
for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
|
for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
|
||||||
int index = getSkillIndex(skill);
|
int index = getSkillIndex(skill);
|
||||||
|
|
||||||
if (index >= character.length) {
|
if (index >= character.length) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cap = Config.getInstance().getLevelCap(skill);
|
int cap = Config.getInstance().getLevelCap(skill);
|
||||||
if (Integer.parseInt(character[index]) > cap) {
|
int skillLevel = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
skillLevel = Integer.parseInt(character[index]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
mcMMO.p.getLogger().severe("Repairing some corrupt or unexpected data in mcmmo.users it is possible some data may be lost.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skillLevel > cap) {
|
||||||
mcMMO.p.getLogger().warning("Truncating " + skill.getName() + " to configured max level for player " + character[USERNAME_INDEX]);
|
mcMMO.p.getLogger().warning("Truncating " + skill.getName() + " to configured max level for player " + character[USERNAME_INDEX]);
|
||||||
character[index] = cap + "";
|
character[index] = cap + "";
|
||||||
updated = true;
|
updated = true;
|
||||||
@ -1224,34 +1235,34 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
|||||||
MobHealthbarType mobHealthbarType;
|
MobHealthbarType mobHealthbarType;
|
||||||
int scoreboardTipsShown;
|
int scoreboardTipsShown;
|
||||||
|
|
||||||
// TODO on updates, put new values in a try{} ?
|
String username = character[USERNAME_INDEX];
|
||||||
|
|
||||||
skillsXp.put(PrimarySkillType.TAMING, (float) Integer.parseInt(character[EXP_TAMING]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.TAMING, EXP_TAMING, username);
|
||||||
skillsXp.put(PrimarySkillType.MINING, (float) Integer.parseInt(character[EXP_MINING]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.MINING, EXP_MINING, username);
|
||||||
skillsXp.put(PrimarySkillType.REPAIR, (float) Integer.parseInt(character[EXP_REPAIR]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.REPAIR, EXP_REPAIR, username);
|
||||||
skillsXp.put(PrimarySkillType.WOODCUTTING, (float) Integer.parseInt(character[EXP_WOODCUTTING]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.WOODCUTTING, EXP_WOODCUTTING, username);
|
||||||
skillsXp.put(PrimarySkillType.UNARMED, (float) Integer.parseInt(character[EXP_UNARMED]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.UNARMED, EXP_UNARMED, username);
|
||||||
skillsXp.put(PrimarySkillType.HERBALISM, (float) Integer.parseInt(character[EXP_HERBALISM]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.HERBALISM, EXP_HERBALISM, username);
|
||||||
skillsXp.put(PrimarySkillType.EXCAVATION, (float) Integer.parseInt(character[EXP_EXCAVATION]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.EXCAVATION, EXP_EXCAVATION, username);
|
||||||
skillsXp.put(PrimarySkillType.ARCHERY, (float) Integer.parseInt(character[EXP_ARCHERY]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ARCHERY, EXP_ARCHERY, username);
|
||||||
skillsXp.put(PrimarySkillType.SWORDS, (float) Integer.parseInt(character[EXP_SWORDS]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.SWORDS, EXP_SWORDS, username);
|
||||||
skillsXp.put(PrimarySkillType.AXES, (float) Integer.parseInt(character[EXP_AXES]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.AXES, EXP_AXES, username);
|
||||||
skillsXp.put(PrimarySkillType.ACROBATICS, (float) Integer.parseInt(character[EXP_ACROBATICS]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ACROBATICS, EXP_ACROBATICS, username);
|
||||||
skillsXp.put(PrimarySkillType.FISHING, (float) Integer.parseInt(character[EXP_FISHING]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.FISHING, EXP_FISHING, username);
|
||||||
skillsXp.put(PrimarySkillType.ALCHEMY, (float) Integer.parseInt(character[EXP_ALCHEMY]));
|
tryLoadSkillFloatValuesFromRawData(skillsXp, character, PrimarySkillType.ALCHEMY, EXP_ALCHEMY, username);
|
||||||
|
|
||||||
// Taming - Unused
|
// Taming - Unused
|
||||||
skillsDATS.put(SuperAbilityType.SUPER_BREAKER, Integer.valueOf(character[COOLDOWN_SUPER_BREAKER]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SUPER_BREAKER, COOLDOWN_SUPER_BREAKER, username);
|
||||||
// Repair - Unused
|
// Repair - Unused
|
||||||
skillsDATS.put(SuperAbilityType.TREE_FELLER, Integer.valueOf(character[COOLDOWN_TREE_FELLER]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.TREE_FELLER, COOLDOWN_TREE_FELLER, username);
|
||||||
skillsDATS.put(SuperAbilityType.BERSERK, Integer.valueOf(character[COOLDOWN_BERSERK]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BERSERK, COOLDOWN_BERSERK, username);
|
||||||
skillsDATS.put(SuperAbilityType.GREEN_TERRA, Integer.valueOf(character[COOLDOWN_GREEN_TERRA]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.GREEN_TERRA, COOLDOWN_GREEN_TERRA, username);
|
||||||
skillsDATS.put(SuperAbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(character[COOLDOWN_GIGA_DRILL_BREAKER]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.GIGA_DRILL_BREAKER, COOLDOWN_GIGA_DRILL_BREAKER, username);
|
||||||
// Archery - Unused
|
// Archery - Unused
|
||||||
skillsDATS.put(SuperAbilityType.SERRATED_STRIKES, Integer.valueOf(character[COOLDOWN_SERRATED_STRIKES]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SERRATED_STRIKES, COOLDOWN_SERRATED_STRIKES, username);
|
||||||
skillsDATS.put(SuperAbilityType.SKULL_SPLITTER, Integer.valueOf(character[COOLDOWN_SKULL_SPLITTER]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.SKULL_SPLITTER, COOLDOWN_SKULL_SPLITTER, username);
|
||||||
// Acrobatics - Unused
|
// Acrobatics - Unused
|
||||||
skillsDATS.put(SuperAbilityType.BLAST_MINING, Integer.valueOf(character[COOLDOWN_BLAST_MINING]));
|
tryLoadSkillCooldownFromRawData(skillsDATS, character, SuperAbilityType.BLAST_MINING, COOLDOWN_BLAST_MINING, username);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mobHealthbarType = MobHealthbarType.valueOf(character[HEALTHBAR]);
|
mobHealthbarType = MobHealthbarType.valueOf(character[HEALTHBAR]);
|
||||||
@ -1285,26 +1296,60 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
|
|||||||
return new PlayerProfile(character[USERNAME_INDEX], uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniquePlayerDataMap);
|
return new PlayerProfile(character[USERNAME_INDEX], uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniquePlayerDataMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<PrimarySkillType, Integer> getSkillMapFromLine(String[] character) {
|
private void tryLoadSkillCooldownFromRawData(@NotNull Map<SuperAbilityType, Integer> cooldownMap, @NotNull String[] character, @NotNull SuperAbilityType superAbilityType, int cooldownSuperBreaker, @NotNull String userName) {
|
||||||
Map<PrimarySkillType, Integer> skills = new EnumMap<>(PrimarySkillType.class); // Skill & Level
|
try {
|
||||||
|
cooldownMap.put(superAbilityType, Integer.valueOf(character[cooldownSuperBreaker]));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
mcMMO.p.getLogger().severe("Data corruption when trying to load the value for skill "+superAbilityType.toString()+" for player named " + userName+ " setting value to zero");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
skills.put(PrimarySkillType.TAMING, Integer.valueOf(character[SKILLS_TAMING]));
|
private void tryLoadSkillFloatValuesFromRawData(@NotNull Map<PrimarySkillType, Float> skillMap, @NotNull String[] character, @NotNull PrimarySkillType primarySkillType, int expTaming, @NotNull String userName) {
|
||||||
skills.put(PrimarySkillType.MINING, Integer.valueOf(character[SKILLS_MINING]));
|
try {
|
||||||
skills.put(PrimarySkillType.REPAIR, Integer.valueOf(character[SKILLS_REPAIR]));
|
float valueFromString = Integer.parseInt(character[expTaming]);
|
||||||
skills.put(PrimarySkillType.WOODCUTTING, Integer.valueOf(character[SKILLS_WOODCUTTING]));
|
skillMap.put(primarySkillType, valueFromString);
|
||||||
skills.put(PrimarySkillType.UNARMED, Integer.valueOf(character[SKILLS_UNARMED]));
|
} catch (NumberFormatException e) {
|
||||||
skills.put(PrimarySkillType.HERBALISM, Integer.valueOf(character[SKILLS_HERBALISM]));
|
skillMap.put(primarySkillType, 0F);
|
||||||
skills.put(PrimarySkillType.EXCAVATION, Integer.valueOf(character[SKILLS_EXCAVATION]));
|
mcMMO.p.getLogger().severe("Data corruption when trying to load the value for skill "+primarySkillType.toString()+" for player named " + userName+ " setting value to zero");
|
||||||
skills.put(PrimarySkillType.ARCHERY, Integer.valueOf(character[SKILLS_ARCHERY]));
|
e.printStackTrace();
|
||||||
skills.put(PrimarySkillType.SWORDS, Integer.valueOf(character[SKILLS_SWORDS]));
|
}
|
||||||
skills.put(PrimarySkillType.AXES, Integer.valueOf(character[SKILLS_AXES]));
|
}
|
||||||
skills.put(PrimarySkillType.ACROBATICS, Integer.valueOf(character[SKILLS_ACROBATICS]));
|
|
||||||
skills.put(PrimarySkillType.FISHING, Integer.valueOf(character[SKILLS_FISHING]));
|
private void tryLoadSkillIntValuesFromRawData(@NotNull Map<PrimarySkillType, Integer> skillMap, @NotNull String[] character, @NotNull PrimarySkillType primarySkillType, int expTaming, @NotNull String userName) {
|
||||||
skills.put(PrimarySkillType.ALCHEMY, Integer.valueOf(character[SKILLS_ALCHEMY]));
|
try {
|
||||||
|
int valueFromString = Integer.parseInt(character[expTaming]);
|
||||||
|
skillMap.put(primarySkillType, valueFromString);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
skillMap.put(primarySkillType, 0);
|
||||||
|
mcMMO.p.getLogger().severe("Data corruption when trying to load the value for skill "+primarySkillType.toString()+" for player named " + userName+ " setting value to zero");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private @NotNull Map<PrimarySkillType, Integer> getSkillMapFromLine(@NotNull String[] character) {
|
||||||
|
Map<PrimarySkillType, Integer> skills = new EnumMap<>(PrimarySkillType.class); // Skill & Level
|
||||||
|
String username = character[USERNAME_INDEX];
|
||||||
|
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.TAMING, SKILLS_TAMING, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.MINING, SKILLS_MINING, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.REPAIR, SKILLS_REPAIR, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.WOODCUTTING, SKILLS_WOODCUTTING, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.UNARMED, SKILLS_UNARMED, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.HERBALISM, SKILLS_HERBALISM, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.EXCAVATION, SKILLS_EXCAVATION, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.ARCHERY, SKILLS_ARCHERY, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.SWORDS, SKILLS_SWORDS, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.AXES, SKILLS_AXES, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.ACROBATICS, SKILLS_ACROBATICS, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.FISHING, SKILLS_FISHING, username);
|
||||||
|
tryLoadSkillIntValuesFromRawData(skills, character, PrimarySkillType.ALCHEMY, SKILLS_ALCHEMY, username);
|
||||||
|
|
||||||
return skills;
|
return skills;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public DatabaseType getDatabaseType() {
|
public DatabaseType getDatabaseType() {
|
||||||
return DatabaseType.FLATFILE;
|
return DatabaseType.FLATFILE;
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,12 @@ package com.gmail.nossr50.party;
|
|||||||
|
|
||||||
import com.gmail.nossr50.config.Config;
|
import com.gmail.nossr50.config.Config;
|
||||||
import com.gmail.nossr50.datatypes.chat.ChatChannel;
|
import com.gmail.nossr50.datatypes.chat.ChatChannel;
|
||||||
import com.gmail.nossr50.datatypes.database.UpgradeType;
|
|
||||||
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||||
import com.gmail.nossr50.datatypes.party.ItemShareType;
|
import com.gmail.nossr50.datatypes.party.ItemShareType;
|
||||||
import com.gmail.nossr50.datatypes.party.Party;
|
import com.gmail.nossr50.datatypes.party.Party;
|
||||||
import com.gmail.nossr50.datatypes.party.PartyLeader;
|
import com.gmail.nossr50.datatypes.party.PartyLeader;
|
||||||
import com.gmail.nossr50.datatypes.party.ShareMode;
|
import com.gmail.nossr50.datatypes.party.ShareMode;
|
||||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
|
||||||
import com.gmail.nossr50.events.party.McMMOPartyAllianceChangeEvent;
|
import com.gmail.nossr50.events.party.McMMOPartyAllianceChangeEvent;
|
||||||
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
|
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
|
||||||
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
|
import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package com.gmail.nossr50.util.text;
|
package com.gmail.nossr50.util.text;
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Unit Test checks if Adventure was set up correctly and works as expected.
|
* This Unit Test checks if Adventure was set up correctly and works as expected.
|
||||||
|
Loading…
Reference in New Issue
Block a user