Fixes a few problems

Makes sure to actually load the configuration when starting the plugin
Makes sure all numeric configuration values are within expected bounds
Adds improved descriptions of configuration values' bounds
Removes the option to not override the vertical speed
Adds options for whether sneaking and sprinting should be blocked while in an arena
Adds more materials to the default config's whitelist
Fixes reloading not properly loading the new config
Fixes config options not loading because the root node was missing
Prevents players combusting while in an arena
This commit is contained in:
Kristian Knarvik 2023-04-11 20:04:04 +02:00
parent 2f4d4ff4c6
commit 4de5ae469b
10 changed files with 132 additions and 60 deletions

View File

@ -111,7 +111,7 @@ public final class Dropper extends JavaPlugin {
// Reload configuration
this.reloadConfig();
this.configuration.load();
this.configuration.load(this.getConfig());
// Clear record caches
this.dropperRecordExpansion.clearCaches();
@ -136,6 +136,9 @@ public final class Dropper extends JavaPlugin {
// Plugin startup logic
instance = this;
this.saveDefaultConfig();
getConfig().options().copyDefaults(true);
saveConfig();
reloadConfig();
this.configuration = new DropperConfiguration(this.getConfig());
this.configuration.load();
this.playerRegistry = new DropperArenaPlayerRegistry();
@ -163,7 +166,7 @@ public final class Dropper extends JavaPlugin {
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
this.dropperRecordExpansion = new DropperRecordExpansion(this);
if (!this.dropperRecordExpansion.register()) {
getLogger().log(Level.WARNING, "Unable to register PlaceholderAPI expansion!");
log(Level.WARNING, "Unable to register PlaceholderAPI expansion!");
}
}
}
@ -195,7 +198,7 @@ public final class Dropper extends JavaPlugin {
command.setTabCompleter(tabCompleter);
}
} else {
getLogger().log(Level.SEVERE, "Unable to register the command " + commandName);
log(Level.SEVERE, "Unable to register the command " + commandName);
}
}

View File

@ -129,7 +129,7 @@ public class DropperArenaGroup implements ConfigurationSerializable {
DropperArena dropperArena = arenaHandler.getArena(anArenaId);
if (dropperArena == null) {
// The arena would only be null if the arena has been deleted, but not removed from this group
Dropper.getInstance().getLogger().log(Level.WARNING, "The dropper group " + this.getGroupName() +
Dropper.log(Level.WARNING, "The dropper group " + this.getGroupName() +
" contains the arena id " + anArenaId + " which is not a valid arena id!");
continue;
}
@ -166,7 +166,7 @@ public class DropperArenaGroup implements ConfigurationSerializable {
DropperArena dropperArena = arenaHandler.getArena(anArenaId);
if (dropperArena == null) {
// The arena would only be null if the arena has been deleted, but not removed from this group
Dropper.getInstance().getLogger().log(Level.WARNING, String.format("The dropper group %s contains the" +
Dropper.log(Level.WARNING, String.format("The dropper group %s contains the" +
" arena id %s which is not a valid arena id!", this.getGroupName(), anArenaId));
continue;
}

View File

@ -164,8 +164,8 @@ public class DropperArenaHandler {
this.arenaNameLookup.remove(arena.getArenaNameSanitized());
this.arenaGroups.remove(arenaId);
if (!ArenaStorageHelper.removeArenaData(arenaId)) {
Dropper.getInstance().getLogger().log(Level.WARNING, "Unable to remove dropper arena data file " +
arenaId + ".yml. You must remove it manually!");
Dropper.log(Level.WARNING, "Unable to remove dropper arena data file " + arenaId + ".yml. " +
"You must remove it manually!");
}
this.saveArenas();
}
@ -179,8 +179,8 @@ public class DropperArenaHandler {
try {
ArenaStorageHelper.saveArenaData(this.arenas.get(arenaId).getData());
} catch (IOException e) {
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to save arena data! Data loss can occur!");
Dropper.getInstance().getLogger().log(Level.SEVERE, e.getMessage());
Dropper.log(Level.SEVERE, "Unable to save arena data! Data loss can occur!");
Dropper.log(Level.SEVERE, e.getMessage());
}
}
@ -191,9 +191,9 @@ public class DropperArenaHandler {
try {
ArenaStorageHelper.saveDropperArenaGroups(new HashSet<>(this.arenaGroups.values()));
} catch (IOException e) {
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to save current arena groups! " +
Dropper.log(Level.SEVERE, "Unable to save current arena groups! " +
"Data loss can occur!");
Dropper.getInstance().getLogger().log(Level.SEVERE, e.getMessage());
Dropper.log(Level.SEVERE, e.getMessage());
}
}
@ -218,9 +218,9 @@ public class DropperArenaHandler {
try {
ArenaStorageHelper.saveArenas(this.arenas);
} catch (IOException e) {
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to save current arenas! " +
Dropper.log(Level.SEVERE, "Unable to save current arenas! " +
"Data loss can occur!");
Dropper.getInstance().getLogger().log(Level.SEVERE, e.getMessage());
Dropper.log(Level.SEVERE, e.getMessage());
}
}

View File

@ -109,8 +109,8 @@ public class DropperArenaSession {
// Remove this session for game sessions to stop listeners from fiddling more with the player
boolean removedSession = Dropper.getInstance().getPlayerRegistry().removePlayer(player.getUniqueId());
if (!removedSession) {
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to remove dropper arena session for " +
player.getName() + ". This will have unintended consequences.");
Dropper.log(Level.SEVERE, "Unable to remove dropper arena session for " + player.getName() + ". " +
"This will have unintended consequences.");
}
}

View File

@ -15,9 +15,13 @@ import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* The configuration keeping track of the player's current configuration
*/
public class DropperConfiguration {
private final FileConfiguration configuration;
private FileConfiguration configuration;
private final static String rootNode = "dropper.";
private double verticalVelocity;
private float horizontalVelocity;
@ -27,9 +31,10 @@ public class DropperConfiguration {
private boolean mustDoNormalModeFirst;
private boolean makePlayersInvisible;
private boolean disableHitCollision;
private boolean overrideVerticalVelocity;
private double liquidHitBoxDepth;
private double solidHitBoxDistance;
private boolean blockSneaking;
private boolean blockSprinting;
private Set<Material> blockWhitelist;
/**
@ -41,15 +46,6 @@ public class DropperConfiguration {
this.configuration = configuration;
}
/**
* Gets whether vertical velocity should be overridden
*
* @return <p>Whether vertical velocity should be overridden</p>
*/
public boolean overrideVerticalVelocity() {
return this.overrideVerticalVelocity;
}
/**
* Gets the default vertical velocity
*
@ -155,21 +151,50 @@ public class DropperConfiguration {
return this.solidHitBoxDistance;
}
/**
* Gets whether players trying to sneak while in a dropper arena to increase their downwards speed should be blocked
*
* @return <p>Whether to block sneak to speed up</p>
*/
public boolean blockSneaking() {
return blockSneaking;
}
/**
* Gets whether players trying to sprint to improve their horizontal speed while in a dropper arena should be blocked
*
* @return <p>Whether to block sprint to speed up</p>
*/
public boolean blockSprinting() {
return this.blockSprinting;
}
/**
* Loads all configuration values from disk
*
* @param configuration <p>The configuration to load</p>
*/
public void load(FileConfiguration configuration) {
this.configuration = configuration;
this.load();
}
/**
* Loads all configuration values from disk
*/
public void load() {
this.verticalVelocity = configuration.getDouble("verticalVelocity", 1.0);
this.horizontalVelocity = (float) configuration.getDouble("horizontalVelocity", 1.0);
this.randomlyInvertedTimer = configuration.getInt("randomlyInvertedTimer", 7);
this.mustDoGroupedInSequence = configuration.getBoolean("mustDoGroupedInSequence", true);
this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean("ignoreRecordsUntilGroupBeatenOnce", false);
this.mustDoNormalModeFirst = configuration.getBoolean("mustDoNormalModeFirst", true);
this.makePlayersInvisible = configuration.getBoolean("makePlayersInvisible", false);
this.disableHitCollision = configuration.getBoolean("disableHitCollision", true);
this.overrideVerticalVelocity = configuration.getBoolean("overrideVerticalVelocity", true);
this.liquidHitBoxDepth = configuration.getDouble("liquidHitBoxDepth", -0.8);
this.solidHitBoxDistance = configuration.getDouble("solidHitBoxDistance", 0.2);
this.verticalVelocity = configuration.getDouble(rootNode + "verticalVelocity", 1.0);
this.horizontalVelocity = (float) configuration.getDouble(rootNode + "horizontalVelocity", 1.0);
this.randomlyInvertedTimer = configuration.getInt(rootNode + "randomlyInvertedTimer", 7);
this.mustDoGroupedInSequence = configuration.getBoolean(rootNode + "mustDoGroupedInSequence", true);
this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean(rootNode + "ignoreRecordsUntilGroupBeatenOnce", false);
this.mustDoNormalModeFirst = configuration.getBoolean(rootNode + "mustDoNormalModeFirst", true);
this.makePlayersInvisible = configuration.getBoolean(rootNode + "makePlayersInvisible", false);
this.disableHitCollision = configuration.getBoolean(rootNode + "disableHitCollision", true);
this.liquidHitBoxDepth = configuration.getDouble(rootNode + "liquidHitBoxDepth", -0.8);
this.solidHitBoxDistance = configuration.getDouble(rootNode + "solidHitBoxDistance", 0.2);
this.blockSprinting = configuration.getBoolean(rootNode + "blockSprinting", true);
this.blockSneaking = configuration.getBoolean(rootNode + "blockSneaking", true);
sanitizeValues();
loadBlockWhitelist();
@ -205,7 +230,7 @@ public class DropperConfiguration {
*/
private void loadBlockWhitelist() {
this.blockWhitelist = new HashSet<>();
List<?> blockWhitelist = configuration.getList("blockWhiteList", new ArrayList<>());
List<?> blockWhitelist = configuration.getList(rootNode + "blockWhitelist", new ArrayList<>());
for (Object value : blockWhitelist) {
if (!(value instanceof String string)) {
continue;
@ -249,4 +274,25 @@ public class DropperConfiguration {
return false;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder(
"Current configuration:" +
"\n" + "Vertical velocity: " + verticalVelocity +
"\n" + "Horizontal velocity: " + horizontalVelocity +
"\n" + "Randomly inverted timer: " + randomlyInvertedTimer +
"\n" + "Must do groups in sequence: " + mustDoGroupedInSequence +
"\n" + "Ignore records until group beaten once: " + ignoreRecordsUntilGroupBeatenOnce +
"\n" + "Must do normal mode first: " + mustDoNormalModeFirst +
"\n" + "Make players invisible: " + makePlayersInvisible +
"\n" + "Disable hit collision: " + disableHitCollision +
"\n" + "Liquid hit box depth: " + liquidHitBoxDepth +
"\n" + "Solid hit box distance: " + solidHitBoxDistance +
"\n" + "Block whitelist: ");
for (Material material : blockWhitelist) {
builder.append("\n - ").append(material.name());
}
return builder.toString();
}
}

View File

@ -1,11 +1,13 @@
package net.knarcraft.dropper.listener;
import net.knarcraft.dropper.Dropper;
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
import net.knarcraft.dropper.arena.DropperArenaSession;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDamageEvent;
/**
@ -36,4 +38,18 @@ public class DamageListener implements Listener {
}
}
@EventHandler(ignoreCancelled = true)
public void onPlayerCombustion(EntityCombustEvent event) {
if (event.getEntityType() != EntityType.PLAYER) {
return;
}
DropperArenaPlayerRegistry registry = Dropper.getInstance().getPlayerRegistry();
DropperArenaSession arenaSession = registry.getArenaSession(event.getEntity().getUniqueId());
if (arenaSession != null) {
// Cancel combustion for any player in an arena
event.setCancelled(true);
}
}
}

View File

@ -50,7 +50,9 @@ public class MoveListener implements Listener {
}
// Prevent the player from flying upwards while in flight mode
if (event.getFrom().getY() < event.getTo().getY()) {
if (event.getFrom().getY() < event.getTo().getY() ||
(configuration.blockSneaking() && event.getPlayer().isSneaking()) ||
(configuration.blockSprinting() && event.getPlayer().isSprinting())) {
event.setCancelled(true);
return;
}
@ -125,14 +127,12 @@ public class MoveListener implements Listener {
* @param session <p>The session to update the velocity for</p>
*/
private void updatePlayerVelocity(@NotNull DropperArenaSession session) {
// Override the vertical velocity, if enabled
if (configuration.overrideVerticalVelocity()) {
// Override the vertical velocity
Player player = session.getPlayer();
Vector playerVelocity = player.getVelocity();
double arenaVelocity = session.getArena().getPlayerVerticalVelocity();
Vector newVelocity = new Vector(playerVelocity.getX(), -arenaVelocity, playerVelocity.getZ());
Vector newVelocity = new Vector(playerVelocity.getX() * 5, -arenaVelocity, playerVelocity.getZ() * 5);
player.setVelocity(newVelocity);
}
// Toggle the direction of the player's flying, as necessary
toggleFlyInversion(session);

View File

@ -32,7 +32,7 @@ public class PlayerLeaveListener implements Listener {
return;
}
Dropper.getInstance().getLogger().log(Level.WARNING, "Found player " + player.getUniqueId() +
Dropper.log(Level.WARNING, "Found player " + player.getUniqueId() +
" leaving in the middle of a session!");
leftSessions.put(player.getUniqueId(), arenaSession);
}
@ -42,10 +42,10 @@ public class PlayerLeaveListener implements Listener {
UUID playerId = event.getPlayer().getUniqueId();
// Force the player to quit from the session once they re-join
if (leftSessions.containsKey(playerId)) {
Dropper.getInstance().getLogger().log(Level.WARNING, "Found un-exited dropper session!");
Dropper.log(Level.WARNING, "Found un-exited dropper session!");
Bukkit.getScheduler().runTaskLater(Dropper.getInstance(), () -> {
leftSessions.get(playerId).triggerQuit(false);
Dropper.getInstance().getLogger().log(Level.WARNING, "Triggered a quit!");
Dropper.log(Level.WARNING, "Triggered a quit!");
leftSessions.remove(playerId);
}, 80);
}

View File

@ -24,7 +24,6 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* A helper class for saving and loading arenas
@ -153,10 +152,9 @@ public final class ArenaStorageHelper {
ArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey()));
SerializableMaterial winBlockType = (SerializableMaterial) configurationSection.get(
ArenaStorageKey.WIN_BLOCK_TYPE.getKey());
Logger logger = Dropper.getInstance().getLogger();
if (arenaName == null || spawnLocation == null) {
logger.log(Level.SEVERE, "Could not load the arena at configuration " +
Dropper.log(Level.SEVERE, "Could not load the arena at configuration " +
"section " + configurationSection.getName() + ". Please check the arenas storage file for issues.");
return null;
}
@ -166,7 +164,7 @@ public final class ArenaStorageHelper {
DropperArenaData arenaData = loadArenaData(arenaId);
if (arenaData == null) {
logger.log(Level.SEVERE, "Unable to load arena data for " + arenaId);
Dropper.log(Level.SEVERE, "Unable to load arena data for " + arenaId);
Map<ArenaGameMode, DropperArenaRecordsRegistry> recordRegistries = new HashMap<>();
for (ArenaGameMode arenaGameMode : ArenaGameMode.values()) {
@ -222,7 +220,7 @@ public final class ArenaStorageHelper {
private static @NotNull File getArenaDataFile(@NotNull UUID arenaId) {
File arenaDataFile = new File(arenaDataFolder, arenaId + ".yml");
if (!arenaDataFolder.exists() && !arenaDataFolder.mkdirs()) {
Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to create the arena data directories");
Dropper.log(Level.SEVERE, "Unable to create the arena data directories");
}
return arenaDataFile;
}

View File

@ -1,8 +1,10 @@
# Configuration values for droppers
dropper:
# Whether the vertical velocity should be overridden, and thus changeable. If not enabled, all horizontalVelocity
# settings, both the global one and per-arena, will be ignored.
overrideVerticalVelocity: true
# Whether to block using the shift key to drop faster than the intended drop speed
blockSneaking: true
# Whether to block using the sprint key for slightly improved air speed
blockSprinting: true
# The vertical velocity used as default for all arenas. Must be greater than 0. 3.92 is the max speed of a falling
# player.
@ -48,3 +50,10 @@ dropper:
- +WALL_SIGNS
- +STANDING_SIGNS
- STRUCTURE_VOID
- WALL_TORCH
- SOUL_WALL_TORCH
- REDSTONE_WALL_TORCH
- +BANNERS
- +BUTTONS
- +CORALS
- +WALL_CORALS