Fixes a bug in killBlockNames, and reduces writes

This commit is contained in:
Kristian Knarvik 2023-09-17 08:03:03 +02:00
parent a7cfe36c72
commit 162aff0c1f
4 changed files with 141 additions and 46 deletions

View File

@ -21,6 +21,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import static net.knarcraft.minigames.util.InputValidationHelper.isInvalid; import static net.knarcraft.minigames.util.InputValidationHelper.isInvalid;
@ -167,13 +168,13 @@ public class DropperArena implements Arena {
public void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward) { public void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward) {
this.rewards.computeIfAbsent(rewardCondition, k -> new HashSet<>()); this.rewards.computeIfAbsent(rewardCondition, k -> new HashSet<>());
this.rewards.get(rewardCondition).add(reward); this.rewards.get(rewardCondition).add(reward);
this.dropperArenaHandler.saveArenas(); this.saveArena();
} }
@Override @Override
public void clearRewards(@NotNull RewardCondition rewardCondition) { public void clearRewards(@NotNull RewardCondition rewardCondition) {
this.rewards.remove(rewardCondition); this.rewards.remove(rewardCondition);
this.dropperArenaHandler.saveArenas(); this.saveArena();
} }
@Override @Override
@ -267,7 +268,7 @@ public class DropperArena implements Arena {
return false; return false;
} else { } else {
this.spawnLocation = newLocation; this.spawnLocation = newLocation;
this.dropperArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -283,7 +284,7 @@ public class DropperArena implements Arena {
return false; return false;
} else { } else {
this.exitLocation = newLocation; this.exitLocation = newLocation;
this.dropperArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -300,7 +301,7 @@ public class DropperArena implements Arena {
this.arenaName = arenaName; this.arenaName = arenaName;
// Update the arena lookup map to make sure the new name can be used immediately // Update the arena lookup map to make sure the new name can be used immediately
this.dropperArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized()); this.dropperArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized());
this.dropperArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} else { } else {
return false; return false;
@ -320,7 +321,7 @@ public class DropperArena implements Arena {
return false; return false;
} else { } else {
this.winBlockType = material; this.winBlockType = material;
this.dropperArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -338,7 +339,7 @@ public class DropperArena implements Arena {
return false; return false;
} else { } else {
this.playerHorizontalVelocity = horizontalVelocity; this.playerHorizontalVelocity = horizontalVelocity;
this.dropperArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -354,11 +355,24 @@ public class DropperArena implements Arena {
return false; return false;
} else { } else {
this.playerVerticalVelocity = verticalVelocity; this.playerVerticalVelocity = verticalVelocity;
this.dropperArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
/**
* Saves this arena to disk
*/
public void saveArena() {
try {
DropperArenaStorageHelper.saveSingleDropperArena(this);
} catch (IOException exception) {
MiniGames.log(Level.SEVERE, "Unable to save arena! " +
"Data loss can occur!");
MiniGames.log(Level.SEVERE, exception.getMessage());
}
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof DropperArena otherArena)) { if (!(other instanceof DropperArena otherArena)) {

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.logging.Level;
import static net.knarcraft.minigames.util.InputValidationHelper.isInvalid; import static net.knarcraft.minigames.util.InputValidationHelper.isInvalid;
@ -180,13 +181,13 @@ public class ParkourArena implements Arena {
public void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward) { public void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward) {
this.rewards.computeIfAbsent(rewardCondition, k -> new HashSet<>()); this.rewards.computeIfAbsent(rewardCondition, k -> new HashSet<>());
this.rewards.get(rewardCondition).add(reward); this.rewards.get(rewardCondition).add(reward);
this.parkourArenaHandler.saveArenas(); this.saveArena();
} }
@Override @Override
public void clearRewards(@NotNull RewardCondition rewardCondition) { public void clearRewards(@NotNull RewardCondition rewardCondition) {
this.rewards.remove(rewardCondition); this.rewards.remove(rewardCondition);
this.parkourArenaHandler.saveArenas(); this.saveArena();
} }
@Override @Override
@ -314,7 +315,7 @@ public class ParkourArena implements Arena {
return false; return false;
} else { } else {
this.spawnLocation = newLocation; this.spawnLocation = newLocation;
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -330,7 +331,7 @@ public class ParkourArena implements Arena {
return false; return false;
} else { } else {
this.exitLocation = newLocation; this.exitLocation = newLocation;
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -347,7 +348,7 @@ public class ParkourArena implements Arena {
this.arenaName = arenaName; this.arenaName = arenaName;
// Update the arena lookup map to make sure the new name can be used immediately // Update the arena lookup map to make sure the new name can be used immediately
this.parkourArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized()); this.parkourArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized());
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} else { } else {
return false; return false;
@ -367,7 +368,7 @@ public class ParkourArena implements Arena {
return false; return false;
} else { } else {
this.winBlockType = material; this.winBlockType = material;
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -383,7 +384,7 @@ public class ParkourArena implements Arena {
return false; return false;
} else { } else {
this.winLocation = newLocation.clone(); this.winLocation = newLocation.clone();
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
} }
@ -406,7 +407,7 @@ public class ParkourArena implements Arena {
this.killPlaneBlockNames = killPlaneBlockNames; this.killPlaneBlockNames = killPlaneBlockNames;
this.killPlaneBlocks = parsed; this.killPlaneBlocks = parsed;
} }
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
@ -422,7 +423,7 @@ public class ParkourArena implements Arena {
} }
this.checkpoints.add(checkpoint.clone()); this.checkpoints.add(checkpoint.clone());
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
@ -437,10 +438,23 @@ public class ParkourArena implements Arena {
} }
this.checkpoints.clear(); this.checkpoints.clear();
this.parkourArenaHandler.saveArenas(); this.saveArena();
return true; return true;
} }
/**
* Saves this arena to disk
*/
public void saveArena() {
try {
ParkourArenaStorageHelper.saveSingleParkourArena(this);
} catch (IOException exception) {
MiniGames.log(Level.SEVERE, "Unable to save arena! " +
"Data loss can occur!");
MiniGames.log(Level.SEVERE, exception.getMessage());
}
}
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof ParkourArena otherArena)) { if (!(other instanceof ParkourArena otherArena)) {

View File

@ -97,22 +97,46 @@ public final class DropperArenaStorageHelper {
YamlConfiguration configuration = new YamlConfiguration(); YamlConfiguration configuration = new YamlConfiguration();
ConfigurationSection arenaSection = configuration.createSection(dropperArenasConfigurationSection); ConfigurationSection arenaSection = configuration.createSection(dropperArenasConfigurationSection);
for (DropperArena arena : arenas.values()) { for (DropperArena arena : arenas.values()) {
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name saveDropperArena(arenaSection, arena);
// must be stored as well
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
configSection.set(DropperArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
configSection.set(DropperArenaStorageKey.NAME.getKey(), arena.getArenaName());
configSection.set(DropperArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
configSection.set(DropperArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
configSection.set(DropperArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey(), arena.getPlayerVerticalVelocity());
configSection.set(DropperArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey(), arena.getPlayerHorizontalVelocity());
configSection.set(DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
RewardStorageHelper.saveRewards(arena, configSection, DropperArenaStorageKey.REWARDS.getKey());
saveDropperArenaData(arena.getData());
} }
configuration.save(dropperArenaFile); configuration.save(dropperArenaFile);
} }
/**
* Saves a single arena
*
* @param arena <p>The arena to save</p>
* @throws IOException <p>If unable to write to the file</p>
*/
public static void saveSingleDropperArena(DropperArena arena) throws IOException {
YamlConfiguration configuration = new YamlConfiguration();
ConfigurationSection arenaSection = configuration.createSection(dropperArenasConfigurationSection);
saveDropperArena(arenaSection, arena);
configuration.save(dropperArenaFile);
}
/**
* Updates the given configuration section with the arena's data, and stores arena data for the arena
*
* @param arenaSection <p>The configuration section to update</p>
* @param arena <p>The arena to save</p>
* @throws IOException <p>If unable to save the arena data</p>
*/
public static void saveDropperArena(ConfigurationSection arenaSection, DropperArena arena) throws IOException {
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name
// must be stored as well
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
configSection.set(DropperArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
configSection.set(DropperArenaStorageKey.NAME.getKey(), arena.getArenaName());
configSection.set(DropperArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
configSection.set(DropperArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
configSection.set(DropperArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey(), arena.getPlayerVerticalVelocity());
configSection.set(DropperArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey(), arena.getPlayerHorizontalVelocity());
configSection.set(DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
RewardStorageHelper.saveRewards(arena, configSection, DropperArenaStorageKey.REWARDS.getKey());
saveDropperArenaData(arena.getData());
}
/** /**
* Loads all arenas * Loads all arenas
* *

View File

@ -99,23 +99,61 @@ public final class ParkourArenaStorageHelper {
YamlConfiguration configuration = new YamlConfiguration(); YamlConfiguration configuration = new YamlConfiguration();
ConfigurationSection arenaSection = configuration.createSection(parkourArenasConfigurationSection); ConfigurationSection arenaSection = configuration.createSection(parkourArenasConfigurationSection);
for (ParkourArena arena : arenas.values()) { for (ParkourArena arena : arenas.values()) {
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name saveParkourArena(arenaSection, arena);
// must be stored as well
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
configSection.set(ParkourArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
configSection.set(ParkourArenaStorageKey.NAME.getKey(), arena.getArenaName());
configSection.set(ParkourArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
configSection.set(ParkourArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
configSection.set(ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
configSection.set(ParkourArenaStorageKey.WIN_LOCATION.getKey(), arena.getWinLocation());
configSection.set(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey(), arena.getKillPlaneBlockNames());
configSection.set(ParkourArenaStorageKey.CHECKPOINTS.getKey(), arena.getCheckpoints());
RewardStorageHelper.saveRewards(arena, configSection, ParkourArenaStorageKey.REWARDS.getKey());
saveParkourArenaData(arena.getData());
} }
configuration.save(parkourArenaFile); configuration.save(parkourArenaFile);
} }
/**
* Saves a single arena
*
* @param arena <p>The arena to save</p>
* @throws IOException <p>If unable to write to the file</p>
*/
public static void saveSingleParkourArena(ParkourArena arena) throws IOException {
YamlConfiguration configuration = new YamlConfiguration();
ConfigurationSection arenaSection = configuration.createSection(parkourArenasConfigurationSection);
saveParkourArena(arenaSection, arena);
configuration.save(parkourArenaFile);
}
/**
* Updates the given configuration section with the arena's data, and stores arena data for the arena
*
* @param arenaSection <p>The configuration section to update</p>
* @param arena <p>The arena to save</p>
* @throws IOException <p>If unable to save the arena data</p>
*/
public static void saveParkourArena(ConfigurationSection arenaSection, ParkourArena arena) throws IOException {
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name
// must be stored as well
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
configSection.set(ParkourArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
configSection.set(ParkourArenaStorageKey.NAME.getKey(), arena.getArenaName());
configSection.set(ParkourArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
configSection.set(ParkourArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
configSection.set(ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
configSection.set(ParkourArenaStorageKey.WIN_LOCATION.getKey(), arena.getWinLocation());
configSection.set(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey(), getKillPlaneBlocks(arena));
configSection.set(ParkourArenaStorageKey.CHECKPOINTS.getKey(), arena.getCheckpoints());
RewardStorageHelper.saveRewards(arena, configSection, ParkourArenaStorageKey.REWARDS.getKey());
saveParkourArenaData(arena.getData());
}
/**
* Gets a list of the kill plane blocks for the given arena
*
* @param arena <p>The arena to get kill plane blocks for</p>
* @return <p>The kill plane blocks</p>
*/
private static List<String> getKillPlaneBlocks(ParkourArena arena) {
if (arena.getKillPlaneBlockNames() == null) {
return new ArrayList<>();
} else {
return new ArrayList<>(arena.getKillPlaneBlockNames());
}
}
/** /**
* Loads all arenas * Loads all arenas
* *
@ -163,7 +201,13 @@ public final class ParkourArenaStorageHelper {
Location winLocation = (Location) configurationSection.get(ParkourArenaStorageKey.WIN_LOCATION.getKey()); Location winLocation = (Location) configurationSection.get(ParkourArenaStorageKey.WIN_LOCATION.getKey());
SerializableMaterial winBlockType = (SerializableMaterial) configurationSection.get( SerializableMaterial winBlockType = (SerializableMaterial) configurationSection.get(
ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey()); ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey());
List<?> killPlaneBlockNames = configurationSection.getList(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey()); List<?> killPlaneBlockNamesList = configurationSection.getList(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey());
Set<String> killPlaneBlockNames;
if (killPlaneBlockNamesList == null) {
killPlaneBlockNames = new HashSet<>();
} else {
killPlaneBlockNames = new HashSet<>((List<String>) killPlaneBlockNamesList);
}
List<Location> checkpoints = (List<Location>) configurationSection.get(ParkourArenaStorageKey.CHECKPOINTS.getKey()); List<Location> checkpoints = (List<Location>) configurationSection.get(ParkourArenaStorageKey.CHECKPOINTS.getKey());
Map<RewardCondition, Set<Reward>> rewards = RewardStorageHelper.loadRewards(configurationSection, Map<RewardCondition, Set<Reward>> rewards = RewardStorageHelper.loadRewards(configurationSection,
@ -195,8 +239,7 @@ public final class ParkourArenaStorageHelper {
} }
return new ParkourArena(arenaId, arenaName, spawnLocation, exitLocation, winBlockType.getRawValue(), winLocation, return new ParkourArena(arenaId, arenaName, spawnLocation, exitLocation, winBlockType.getRawValue(), winLocation,
(Set<String>) killPlaneBlockNames, checkpoints, rewards, arenaData, killPlaneBlockNames, checkpoints, rewards, arenaData, MiniGames.getInstance().getParkourArenaHandler());
MiniGames.getInstance().getParkourArenaHandler());
} }
/** /**