mirror of
				https://github.com/SunNetservers/MiniGames.git
				synced 2025-11-04 03:33:47 +01:00 
			
		
		
		
	Implements persistent storage of records
This commit is contained in:
		@@ -2,6 +2,7 @@ package net.knarcraft.dropper;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaHandler;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaPlayerRegistry;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
			
		||||
import net.knarcraft.dropper.command.CreateArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.EditArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.EditArenaTabCompleter;
 | 
			
		||||
@@ -11,12 +12,15 @@ import net.knarcraft.dropper.command.LeaveArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.ListArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.RemoveArenaCommand;
 | 
			
		||||
import net.knarcraft.dropper.command.RemoveArenaTabCompleter;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableMaterial;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
			
		||||
import net.knarcraft.dropper.listener.DamageListener;
 | 
			
		||||
import net.knarcraft.dropper.listener.MoveListener;
 | 
			
		||||
import net.knarcraft.dropper.listener.PlayerLeaveListener;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
import org.bukkit.command.PluginCommand;
 | 
			
		||||
import org.bukkit.command.TabCompleter;
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
 | 
			
		||||
import org.bukkit.plugin.PluginManager;
 | 
			
		||||
import org.bukkit.plugin.java.JavaPlugin;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
@@ -61,6 +65,15 @@ public final class Dropper extends JavaPlugin {
 | 
			
		||||
        return this.playerRegistry;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onLoad() {
 | 
			
		||||
        super.onLoad();
 | 
			
		||||
        // Register serialization classes
 | 
			
		||||
        ConfigurationSerialization.registerClass(SerializableMaterial.class);
 | 
			
		||||
        ConfigurationSerialization.registerClass(DropperArenaRecordsRegistry.class);
 | 
			
		||||
        ConfigurationSerialization.registerClass(SerializableUUID.class);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void onEnable() {
 | 
			
		||||
        // Plugin startup logic
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,23 @@
 | 
			
		||||
package net.knarcraft.dropper.arena;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableUUID;
 | 
			
		||||
import net.knarcraft.dropper.property.RecordResult;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.stream.Stream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A registry keeping track of all records
 | 
			
		||||
 */
 | 
			
		||||
public class DropperArenaRecordsRegistry {
 | 
			
		||||
public class DropperArenaRecordsRegistry implements ConfigurationSerializable {
 | 
			
		||||
 | 
			
		||||
    private final Map<Player, Integer> leastDeaths;
 | 
			
		||||
    private final Map<Player, Long> shortestTimeMilliSeconds;
 | 
			
		||||
    private final Map<SerializableUUID, Integer> leastDeaths;
 | 
			
		||||
    private final Map<SerializableUUID, Long> shortestTimeMilliSeconds;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Instantiates a new empty records registry
 | 
			
		||||
@@ -30,8 +33,8 @@ public class DropperArenaRecordsRegistry {
 | 
			
		||||
     * @param leastDeaths              <p>The existing least death records to use</p>
 | 
			
		||||
     * @param shortestTimeMilliSeconds <p>The existing leash time records to use</p>
 | 
			
		||||
     */
 | 
			
		||||
    public DropperArenaRecordsRegistry(@NotNull Map<Player, Integer> leastDeaths,
 | 
			
		||||
                                       @NotNull Map<Player, Long> shortestTimeMilliSeconds) {
 | 
			
		||||
    public DropperArenaRecordsRegistry(@NotNull Map<SerializableUUID, Integer> leastDeaths,
 | 
			
		||||
                                       @NotNull Map<SerializableUUID, Long> shortestTimeMilliSeconds) {
 | 
			
		||||
        this.leastDeaths = new HashMap<>(leastDeaths);
 | 
			
		||||
        this.shortestTimeMilliSeconds = new HashMap<>(shortestTimeMilliSeconds);
 | 
			
		||||
    }
 | 
			
		||||
@@ -41,7 +44,7 @@ public class DropperArenaRecordsRegistry {
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Existing death records</p>
 | 
			
		||||
     */
 | 
			
		||||
    public Map<Player, Integer> getLeastDeathsRecords() {
 | 
			
		||||
    public Map<SerializableUUID, Integer> getLeastDeathsRecords() {
 | 
			
		||||
        return new HashMap<>(this.leastDeaths);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -50,29 +53,32 @@ public class DropperArenaRecordsRegistry {
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>Existing time records</p>
 | 
			
		||||
     */
 | 
			
		||||
    public Map<Player, Long> getShortestTimeMilliSecondsRecords() {
 | 
			
		||||
    public Map<SerializableUUID, Long> getShortestTimeMilliSecondsRecords() {
 | 
			
		||||
        return new HashMap<>(this.shortestTimeMilliSeconds);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers a new deaths-record
 | 
			
		||||
     *
 | 
			
		||||
     * @param player <p>The player that performed the records</p>
 | 
			
		||||
     * @param deaths <p>The number of deaths suffered before the player finished the arena</p>
 | 
			
		||||
     * @param playerId <p>The id of the player that performed the records</p>
 | 
			
		||||
     * @param deaths   <p>The number of deaths suffered before the player finished the arena</p>
 | 
			
		||||
     * @return <p>The result explaining what type of record was achieved</p>
 | 
			
		||||
     */
 | 
			
		||||
    public @NotNull RecordResult registerDeathRecord(@NotNull Player player, int deaths) {
 | 
			
		||||
    public @NotNull RecordResult registerDeathRecord(@NotNull UUID playerId, int deaths) {
 | 
			
		||||
        RecordResult result;
 | 
			
		||||
        Stream<Map.Entry<Player, Integer>> records = leastDeaths.entrySet().stream();
 | 
			
		||||
        Stream<Map.Entry<SerializableUUID, Integer>> records = leastDeaths.entrySet().stream();
 | 
			
		||||
        SerializableUUID serializableUUID = new SerializableUUID(playerId);
 | 
			
		||||
 | 
			
		||||
        if (records.allMatch((entry) -> deaths < entry.getValue())) {
 | 
			
		||||
            //If the given value is less than all other values, that's a world record!
 | 
			
		||||
            result = RecordResult.WORLD_RECORD;
 | 
			
		||||
            leastDeaths.put(player, deaths);
 | 
			
		||||
        } else if (leastDeaths.containsKey(player) && deaths < leastDeaths.get(player)) {
 | 
			
		||||
            leastDeaths.put(serializableUUID, deaths);
 | 
			
		||||
            save();
 | 
			
		||||
        } else if (leastDeaths.containsKey(serializableUUID) && deaths < leastDeaths.get(serializableUUID)) {
 | 
			
		||||
            //If the given value is less than the player's previous value, that's a personal best!
 | 
			
		||||
            result = RecordResult.PERSONAL_BEST;
 | 
			
		||||
            leastDeaths.put(player, deaths);
 | 
			
		||||
            leastDeaths.put(serializableUUID, deaths);
 | 
			
		||||
            save();
 | 
			
		||||
        } else {
 | 
			
		||||
            result = RecordResult.NONE;
 | 
			
		||||
        }
 | 
			
		||||
@@ -83,22 +89,26 @@ public class DropperArenaRecordsRegistry {
 | 
			
		||||
    /**
 | 
			
		||||
     * Registers a new time-record
 | 
			
		||||
     *
 | 
			
		||||
     * @param player       <p>The player that performed the records</p>
 | 
			
		||||
     * @param playerId     <p>The id of the player that performed the records</p>
 | 
			
		||||
     * @param milliseconds <p>The number of milliseconds it took the player to finish the dropper arena</p>
 | 
			
		||||
     * @return <p>The result explaining what type of record was achieved</p>
 | 
			
		||||
     */
 | 
			
		||||
    public @NotNull RecordResult registerTimeRecord(@NotNull Player player, long milliseconds) {
 | 
			
		||||
    public @NotNull RecordResult registerTimeRecord(@NotNull UUID playerId, long milliseconds) {
 | 
			
		||||
        RecordResult result;
 | 
			
		||||
        Stream<Map.Entry<Player, Long>> records = shortestTimeMilliSeconds.entrySet().stream();
 | 
			
		||||
        Stream<Map.Entry<SerializableUUID, Long>> records = shortestTimeMilliSeconds.entrySet().stream();
 | 
			
		||||
        SerializableUUID serializableUUID = new SerializableUUID(playerId);
 | 
			
		||||
 | 
			
		||||
        if (records.allMatch((entry) -> milliseconds < entry.getValue())) {
 | 
			
		||||
            //If the given value is less than all other values, that's a world record!
 | 
			
		||||
            result = RecordResult.WORLD_RECORD;
 | 
			
		||||
            shortestTimeMilliSeconds.put(player, milliseconds);
 | 
			
		||||
        } else if (shortestTimeMilliSeconds.containsKey(player) && milliseconds < shortestTimeMilliSeconds.get(player)) {
 | 
			
		||||
            shortestTimeMilliSeconds.put(serializableUUID, milliseconds);
 | 
			
		||||
            save();
 | 
			
		||||
        } else if (shortestTimeMilliSeconds.containsKey(serializableUUID) &&
 | 
			
		||||
                milliseconds < shortestTimeMilliSeconds.get(serializableUUID)) {
 | 
			
		||||
            //If the given value is less than the player's previous value, that's a personal best!
 | 
			
		||||
            result = RecordResult.PERSONAL_BEST;
 | 
			
		||||
            shortestTimeMilliSeconds.put(player, milliseconds);
 | 
			
		||||
            shortestTimeMilliSeconds.put(serializableUUID, milliseconds);
 | 
			
		||||
            save();
 | 
			
		||||
        } else {
 | 
			
		||||
            result = RecordResult.NONE;
 | 
			
		||||
        }
 | 
			
		||||
@@ -106,4 +116,36 @@ public class DropperArenaRecordsRegistry {
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves changed records
 | 
			
		||||
     */
 | 
			
		||||
    private void save() {
 | 
			
		||||
        Dropper.getInstance().getArenaHandler().saveArenas();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> serialize() {
 | 
			
		||||
        Map<String, Object> data = new HashMap<>();
 | 
			
		||||
        data.put("leastDeaths", this.leastDeaths);
 | 
			
		||||
        data.put("shortestTime", this.shortestTimeMilliSeconds);
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deserializes the given data
 | 
			
		||||
     *
 | 
			
		||||
     * @param data <p>The data to deserialize</p>
 | 
			
		||||
     * @return <p>The deserialized records registry</p>
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings({"unused", "unchecked"})
 | 
			
		||||
    public static DropperArenaRecordsRegistry deserialize(Map<String, Object> data) {
 | 
			
		||||
        Map<SerializableUUID, Integer> leastDeathsData =
 | 
			
		||||
                (Map<SerializableUUID, Integer>) data.getOrDefault("leastDeaths", new HashMap<>());
 | 
			
		||||
        Map<SerializableUUID, Long> shortestTimeMillisecondsData =
 | 
			
		||||
                (Map<SerializableUUID, Long>) data.getOrDefault("shortestTime", new HashMap<>());
 | 
			
		||||
 | 
			
		||||
        return new DropperArenaRecordsRegistry(leastDeathsData, shortestTimeMillisecondsData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -105,9 +105,9 @@ public class DropperArenaSession {
 | 
			
		||||
    private void registerRecord() {
 | 
			
		||||
        DropperArenaRecordsRegistry recordsRegistry = this.arena.getRecordsRegistry();
 | 
			
		||||
        RecordResult recordResult = switch (this.gameMode) {
 | 
			
		||||
            case LEAST_TIME -> recordsRegistry.registerTimeRecord(this.player,
 | 
			
		||||
            case LEAST_TIME -> recordsRegistry.registerTimeRecord(this.player.getUniqueId(),
 | 
			
		||||
                    System.currentTimeMillis() - this.startTime);
 | 
			
		||||
            case LEAST_DEATHS -> recordsRegistry.registerDeathRecord(this.player, this.deaths);
 | 
			
		||||
            case LEAST_DEATHS -> recordsRegistry.registerDeathRecord(this.player.getUniqueId(), this.deaths);
 | 
			
		||||
            case DEFAULT -> RecordResult.NONE;
 | 
			
		||||
        };
 | 
			
		||||
        switch (recordResult) {
 | 
			
		||||
 
 | 
			
		||||
@@ -32,9 +32,10 @@ public class CreateArenaCommand implements CommandExecutor {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //TODO: Make sure the arena name doesn't contain any unwanted characters
 | 
			
		||||
        // Remove known characters that are likely to cause trouble if used in an arena name
 | 
			
		||||
        String arenaName = arguments[0].replaceAll("[§ :=&]", "");
 | 
			
		||||
 | 
			
		||||
        DropperArena arena = new DropperArena(arguments[0], player.getLocation());
 | 
			
		||||
        DropperArena arena = new DropperArena(arenaName, player.getLocation());
 | 
			
		||||
        Dropper.getInstance().getArenaHandler().addArena(arena);
 | 
			
		||||
        commandSender.sendMessage("The arena was successfully created!");
 | 
			
		||||
        return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,37 @@
 | 
			
		||||
package net.knarcraft.dropper.container;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A material container able to be serialized
 | 
			
		||||
 *
 | 
			
		||||
 * @param material <p>The material stored by this record</p>
 | 
			
		||||
 */
 | 
			
		||||
public record SerializableMaterial(Material material) implements ConfigurationSerializable {
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> serialize() {
 | 
			
		||||
        Map<String, Object> data = new HashMap<>();
 | 
			
		||||
        data.put("name", material.name());
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deserializes a serialized material
 | 
			
		||||
     *
 | 
			
		||||
     * @param data <p>The serialized data</p>
 | 
			
		||||
     * @return <p>The deserialized material</p>
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings("unused")
 | 
			
		||||
    public static SerializableMaterial deserialize(Map<String, Object> data) {
 | 
			
		||||
        Material material = Material.matchMaterial((String) data.getOrDefault("name", "AIR"));
 | 
			
		||||
        return new SerializableMaterial(material);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,50 @@
 | 
			
		||||
package net.knarcraft.dropper.container;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A UUID container able to be serialized
 | 
			
		||||
 *
 | 
			
		||||
 * @param uuid <p>The UUID stored by this record</p>
 | 
			
		||||
 */
 | 
			
		||||
public record SerializableUUID(UUID uuid) implements ConfigurationSerializable {
 | 
			
		||||
 | 
			
		||||
    @NotNull
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, Object> serialize() {
 | 
			
		||||
        Map<String, Object> data = new HashMap<>();
 | 
			
		||||
        data.put("id", uuid.toString());
 | 
			
		||||
        return data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Deserializes a serialized UUID
 | 
			
		||||
     *
 | 
			
		||||
     * @param data <p>The serialized data</p>
 | 
			
		||||
     * @return <p>The deserialized UUID</p>
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressWarnings("unused")
 | 
			
		||||
    public static SerializableUUID deserialize(Map<String, Object> data) {
 | 
			
		||||
        String id = (String) data.getOrDefault("id", null);
 | 
			
		||||
        if (id != null) {
 | 
			
		||||
            return new SerializableUUID(UUID.fromString(id));
 | 
			
		||||
        } else {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object object) {
 | 
			
		||||
        if (object instanceof SerializableUUID) {
 | 
			
		||||
            return this.uuid.equals(((SerializableUUID) object).uuid);
 | 
			
		||||
        } else {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -41,6 +41,11 @@ public enum ArenaStorageKey {
 | 
			
		||||
     * The key for the type of this arena's win block
 | 
			
		||||
     */
 | 
			
		||||
    WIN_BLOCK_TYPE("winBlockType"),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The hey for this arena's records
 | 
			
		||||
     */
 | 
			
		||||
    RECORDS("records"),
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
    private final @NotNull String key;
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package net.knarcraft.dropper.util;
 | 
			
		||||
import net.knarcraft.dropper.Dropper;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArena;
 | 
			
		||||
import net.knarcraft.dropper.arena.DropperArenaRecordsRegistry;
 | 
			
		||||
import net.knarcraft.dropper.container.SerializableMaterial;
 | 
			
		||||
import net.knarcraft.dropper.property.ArenaStorageKey;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
@@ -49,7 +50,8 @@ public final class ArenaStorageHelper {
 | 
			
		||||
            configSection.set(ArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey(), arena.getPlayerVerticalVelocity());
 | 
			
		||||
            configSection.set(ArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey(), arena.getPlayerHorizontalVelocity());
 | 
			
		||||
            configSection.set(ArenaStorageKey.STAGE.getKey(), arena.getStage());
 | 
			
		||||
            configSection.set(ArenaStorageKey.WIN_BLOCK_TYPE.getKey(), arena.getWinBlockType());
 | 
			
		||||
            configSection.set(ArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
 | 
			
		||||
            configSection.set(ArenaStorageKey.RECORDS.getKey(), arena.getRecordsRegistry());
 | 
			
		||||
        }
 | 
			
		||||
        //TODO: Save records belonging to the arena
 | 
			
		||||
        configuration.save(arenaFile);
 | 
			
		||||
@@ -100,18 +102,25 @@ public final class ArenaStorageHelper {
 | 
			
		||||
        double verticalVelocity = configurationSection.getDouble(ArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey());
 | 
			
		||||
        double horizontalVelocity = configurationSection.getDouble(ArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey());
 | 
			
		||||
        Integer stage = (Integer) configurationSection.get(ArenaStorageKey.STAGE.getKey());
 | 
			
		||||
        Material winBlockType = (Material) configurationSection.get(ArenaStorageKey.WIN_BLOCK_TYPE.getKey());
 | 
			
		||||
        SerializableMaterial winBlockType = (SerializableMaterial) configurationSection.get(
 | 
			
		||||
                ArenaStorageKey.WIN_BLOCK_TYPE.getKey());
 | 
			
		||||
        DropperArenaRecordsRegistry recordsRegistry = (DropperArenaRecordsRegistry) configurationSection.get(
 | 
			
		||||
                ArenaStorageKey.RECORDS.getKey());
 | 
			
		||||
 | 
			
		||||
        if (arenaName == null || spawnLocation == null) {
 | 
			
		||||
            Dropper.getInstance().getLogger().log(Level.SEVERE, "Could not load the arena at configuration " +
 | 
			
		||||
                    "section " + configurationSection.getName() + ". Please check the arenas storage file for issues.");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        if (winBlockType == null) {
 | 
			
		||||
            winBlockType = Material.WATER;
 | 
			
		||||
            winBlockType = new SerializableMaterial(Material.WATER);
 | 
			
		||||
        }
 | 
			
		||||
        //TODO: Load records for this arena
 | 
			
		||||
        if (recordsRegistry == null) {
 | 
			
		||||
            recordsRegistry = new DropperArenaRecordsRegistry();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return new DropperArena(arenaName, spawnLocation, exitLocation, verticalVelocity, horizontalVelocity, stage,
 | 
			
		||||
                winBlockType, new DropperArenaRecordsRegistry());
 | 
			
		||||
                winBlockType.material(), recordsRegistry);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -6,10 +6,14 @@ description: A plugin for dropper mini-games
 | 
			
		||||
 | 
			
		||||
commands:
 | 
			
		||||
  dropperlist:
 | 
			
		||||
    aliases:
 | 
			
		||||
      - dlist
 | 
			
		||||
    permission: dropper.join
 | 
			
		||||
    usage: /<command>
 | 
			
		||||
    description: Used to list all current dropper arenas
 | 
			
		||||
  dropperjoin:
 | 
			
		||||
    aliases:
 | 
			
		||||
      - djoin
 | 
			
		||||
    permission: dropper.join
 | 
			
		||||
    usage: |
 | 
			
		||||
      /<command> <arena> [mode]
 | 
			
		||||
@@ -18,18 +22,26 @@ commands:
 | 
			
		||||
      time = A shortest-time competitive game-mode
 | 
			
		||||
    description: Used to join a dropper arena
 | 
			
		||||
  dropperleave:
 | 
			
		||||
    aliases:
 | 
			
		||||
      - dleave
 | 
			
		||||
    permission: dropper.join
 | 
			
		||||
    usage: /<command>
 | 
			
		||||
    description: Used to leave the current dropper arena
 | 
			
		||||
  droppercreate:
 | 
			
		||||
    aliases:
 | 
			
		||||
      - dcreate
 | 
			
		||||
    permission: dropper.create
 | 
			
		||||
    usage: /<command> (Details not finalized)
 | 
			
		||||
    description: Used to create a new dropper arena
 | 
			
		||||
  dropperedit:
 | 
			
		||||
    aliases:
 | 
			
		||||
      - dedit
 | 
			
		||||
    permission: dropper.edit
 | 
			
		||||
    usage: /<command> (Details not finalized)
 | 
			
		||||
    description: Used to edit an existing dropper arena
 | 
			
		||||
  dropperremove:
 | 
			
		||||
    aliases:
 | 
			
		||||
      - dremove
 | 
			
		||||
    permission: dropper.remove
 | 
			
		||||
    usage: /<command> <arena>
 | 
			
		||||
    description: Used to remove an existing dropper arena
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user