mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2025-07-17 21:44:43 +02:00
Parkour implementation safety save 2
This is just a safety save in case the code gets too broken to fix.
This commit is contained in:
@ -0,0 +1,334 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaData;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaStorageKey;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaData;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaStorageKey;
|
||||
import net.knarcraft.minigames.container.SerializableMaterial;
|
||||
import net.knarcraft.minigames.container.SerializableUUID;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A helper class for saving and loading arenas
|
||||
*/
|
||||
public final class ArenaStorageHelper {
|
||||
|
||||
private final static File dataFolder = MiniGames.getInstance().getDataFolder();
|
||||
private final static String dropperArenasConfigurationSection = "dropperArenas";
|
||||
private final static String dropperGroupsConfigurationSection = "dropperGroups";
|
||||
private final static String parkourArenasConfigurationSection = "parkourArenas";
|
||||
private final static String parkourGroupsConfigurationSection = "parkourGroups";
|
||||
private static final File arenaFile = new File(dataFolder, "arenas.yml");
|
||||
private static final File groupFile = new File(dataFolder, "groups.yml");
|
||||
private static final File dropperArenaDataFolder = new File(dataFolder, "dropper_arena_data");
|
||||
private static final File parkourArenaDataFolder = new File(dataFolder, "parkour_arena_data");
|
||||
|
||||
private ArenaStorageHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given dropper arena groups
|
||||
*
|
||||
* @param arenaGroups <p>The arena groups to save</p>
|
||||
* @throws IOException <p>If unable to write to the file</p>
|
||||
*/
|
||||
public static void saveDropperArenaGroups(@NotNull Set<DropperArenaGroup> arenaGroups) throws IOException {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
ConfigurationSection groupSection = configuration.createSection(dropperGroupsConfigurationSection);
|
||||
|
||||
for (DropperArenaGroup arenaGroup : arenaGroups) {
|
||||
groupSection.set(arenaGroup.getGroupId().toString(), arenaGroup);
|
||||
}
|
||||
|
||||
configuration.save(groupFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all existing dropper arena groups
|
||||
*
|
||||
* @return <p>The loaded arena groups</p>
|
||||
*/
|
||||
public static @NotNull Set<DropperArenaGroup> loadDropperArenaGroups() {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(groupFile);
|
||||
ConfigurationSection groupSection = configuration.getConfigurationSection(dropperGroupsConfigurationSection);
|
||||
//If no such section exists, it must be the case that there is no data to load
|
||||
if (groupSection == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
Set<DropperArenaGroup> arenaGroups = new HashSet<>();
|
||||
|
||||
for (String sectionName : groupSection.getKeys(false)) {
|
||||
arenaGroups.add((DropperArenaGroup) groupSection.get(sectionName));
|
||||
}
|
||||
|
||||
return arenaGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given arenas
|
||||
*
|
||||
* @param arenas <p>The arenas to save</p>
|
||||
* @throws IOException <p>If unable to write to the file</p>
|
||||
*/
|
||||
public static void saveDropperArenas(@NotNull Map<UUID, DropperArena> arenas) throws IOException {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
ConfigurationSection arenaSection = configuration.createSection(dropperArenasConfigurationSection);
|
||||
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
|
||||
// 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()));
|
||||
saveDropperArenaData(arena.getData());
|
||||
}
|
||||
configuration.save(arenaFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given arenas
|
||||
*
|
||||
* @param arenas <p>The arenas to save</p>
|
||||
* @throws IOException <p>If unable to write to the file</p>
|
||||
*/
|
||||
public static void saveParkourArenas(@NotNull Map<UUID, ParkourArena> arenas) throws IOException {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
ConfigurationSection arenaSection = configuration.createSection(parkourArenasConfigurationSection);
|
||||
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
|
||||
// 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.getKillPlaneBlocks());
|
||||
configSection.set(ParkourArenaStorageKey.CHECKPOINTS.getKey(), arena.getCheckpoints());
|
||||
saveParkourArenaData(arena.getData());
|
||||
}
|
||||
configuration.save(arenaFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all arenas
|
||||
*
|
||||
* @return <p>The loaded arenas, or null if the arenas configuration section is missing.</p>
|
||||
*/
|
||||
public static @NotNull Map<UUID, DropperArena> loadDropperArenas() {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(arenaFile);
|
||||
ConfigurationSection arenaSection = configuration.getConfigurationSection(dropperArenasConfigurationSection);
|
||||
//If no such section exists, it must be the case that there is no data to load
|
||||
if (arenaSection == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
Map<UUID, DropperArena> loadedArenas = new HashMap<>();
|
||||
|
||||
for (String sectionName : arenaSection.getKeys(false)) {
|
||||
ConfigurationSection configurationSection = arenaSection.getConfigurationSection(sectionName);
|
||||
//I'm not sure whether this could actually happen
|
||||
if (configurationSection == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DropperArena arena = loadDropperArena(configurationSection);
|
||||
if (arena != null) {
|
||||
loadedArenas.put(arena.getArenaId(), arena);
|
||||
}
|
||||
}
|
||||
|
||||
return loadedArenas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an arena from the given configuration section
|
||||
*
|
||||
* @param configurationSection <p>The configuration section containing arena data</p>
|
||||
* @return <p>The loaded arena, or null if invalid</p>
|
||||
*/
|
||||
private static @Nullable DropperArena loadDropperArena(@NotNull ConfigurationSection configurationSection) {
|
||||
UUID arenaId = ((SerializableUUID) configurationSection.get(DropperArenaStorageKey.ID.getKey(),
|
||||
new SerializableUUID(UUID.randomUUID()))).getRawValue();
|
||||
String arenaName = configurationSection.getString(DropperArenaStorageKey.NAME.getKey());
|
||||
Location spawnLocation = (Location) configurationSection.get(DropperArenaStorageKey.SPAWN_LOCATION.getKey());
|
||||
Location exitLocation = (Location) configurationSection.get(DropperArenaStorageKey.EXIT_LOCATION.getKey());
|
||||
double verticalVelocity = configurationSection.getDouble(DropperArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey());
|
||||
float horizontalVelocity = sanitizeHorizontalVelocity((float) configurationSection.getDouble(
|
||||
DropperArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey()));
|
||||
SerializableMaterial winBlockType = (SerializableMaterial) configurationSection.get(
|
||||
DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey());
|
||||
|
||||
if (arenaName == null || spawnLocation == null) {
|
||||
MiniGames.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 = new SerializableMaterial(Material.WATER);
|
||||
}
|
||||
|
||||
DropperArenaData arenaData = loadDropperArenaData(arenaId);
|
||||
if (arenaData == null) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to load arena data for " + arenaId);
|
||||
|
||||
Map<ArenaGameMode, ArenaRecordsRegistry> recordRegistries = new HashMap<>();
|
||||
for (ArenaGameMode arenaGameMode : DropperArenaGameMode.values()) {
|
||||
recordRegistries.put(arenaGameMode, new DropperArenaRecordsRegistry(arenaId));
|
||||
}
|
||||
arenaData = new DropperArenaData(arenaId, recordRegistries, new HashMap<>());
|
||||
}
|
||||
|
||||
return new DropperArena(arenaId, arenaName, spawnLocation, exitLocation, verticalVelocity, horizontalVelocity,
|
||||
winBlockType.getRawValue(), arenaData, MiniGames.getInstance().getDropperArenaHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given arena data to a file
|
||||
*
|
||||
* @param arenaData <p>The arena data to store</p>
|
||||
*/
|
||||
public static void saveParkourArenaData(@NotNull ParkourArenaData arenaData) throws IOException {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
configuration.set(ParkourArenaStorageKey.DATA.getKey(), arenaData);
|
||||
|
||||
configuration.save(getParkourArenaDataFile(arenaData.getArenaId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given arena data to a file
|
||||
*
|
||||
* @param arenaData <p>The arena data to store</p>
|
||||
*/
|
||||
public static void saveDropperArenaData(@NotNull DropperArenaData arenaData) throws IOException {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
configuration.set(DropperArenaStorageKey.DATA.getKey(), arenaData);
|
||||
|
||||
configuration.save(getDropperArenaDataFile(arenaData.getArenaId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads arena data for the given arena id
|
||||
*
|
||||
* @param arenaId <p>The id of the arena to get data for</p>
|
||||
* @return <p>The loaded arena data</p>
|
||||
*/
|
||||
private static @Nullable DropperArenaData loadDropperArenaData(@NotNull UUID arenaId) {
|
||||
File arenaDataFile = getDropperArenaDataFile(arenaId);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(arenaDataFile);
|
||||
return (DropperArenaData) configuration.get(DropperArenaStorageKey.DATA.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads arena data for the given arena id
|
||||
*
|
||||
* @param arenaId <p>The id of the arena to get data for</p>
|
||||
* @return <p>The loaded arena data</p>
|
||||
*/
|
||||
private static @Nullable ParkourArenaData loadParkourArenaData(@NotNull UUID arenaId) {
|
||||
File arenaDataFile = getParkourArenaDataFile(arenaId);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(arenaDataFile);
|
||||
return (ParkourArenaData) configuration.get(ParkourArenaStorageKey.DATA.getKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes data for the arena with the given id
|
||||
*
|
||||
* @param arenaId <p>The id of the arena to remove data for</p>
|
||||
* @return <p>True if the data was successfully removed</p>
|
||||
*/
|
||||
public static boolean removeDropperArenaData(@NotNull UUID arenaId) {
|
||||
return getDropperArenaDataFile(arenaId).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes data for the arena with the given id
|
||||
*
|
||||
* @param arenaId <p>The id of the arena to remove data for</p>
|
||||
* @return <p>True if the data was successfully removed</p>
|
||||
*/
|
||||
public static boolean removeParkourArenaData(@NotNull UUID arenaId) {
|
||||
return getParkourArenaDataFile(arenaId).delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file used to store the given arena id's data
|
||||
*
|
||||
* @param arenaId <p>The id of the arena to get a data file for</p>
|
||||
* @return <p>The file the arena's data is/should be stored in</p>
|
||||
*/
|
||||
private static @NotNull File getDropperArenaDataFile(@NotNull UUID arenaId) {
|
||||
return getArenaDataFile(dropperArenaDataFolder, arenaId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file used to store the given arena id's data
|
||||
*
|
||||
* @param arenaId <p>The id of the arena to get a data file for</p>
|
||||
* @return <p>The file the arena's data is/should be stored in</p>
|
||||
*/
|
||||
private static @NotNull File getParkourArenaDataFile(@NotNull UUID arenaId) {
|
||||
return getArenaDataFile(parkourArenaDataFolder, arenaId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file used to store the given arena id's data
|
||||
*
|
||||
* @param root <p>The root directory for the file</p>
|
||||
* @param arenaId <p>The id of the arena to get a data file for</p>
|
||||
* @return <p>The file the arena's data is/should be stored in</p>
|
||||
*/
|
||||
private static @NotNull File getArenaDataFile(File root, @NotNull UUID arenaId) {
|
||||
File arenaDataFile = new File(root, arenaId + ".yml");
|
||||
if (!root.exists() && !root.mkdirs()) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to create the arena data directories");
|
||||
}
|
||||
return arenaDataFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes the given horizontal velocity to make sure it doesn't leave its bounds
|
||||
*
|
||||
* @param horizontalVelocity <p>The horizontal velocity to sanitize</p>
|
||||
* @return <p>The sanitized horizontal velocity</p>
|
||||
*/
|
||||
private static float sanitizeHorizontalVelocity(float horizontalVelocity) {
|
||||
if (horizontalVelocity < -1) {
|
||||
return -1;
|
||||
} else if (horizontalVelocity > 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return horizontalVelocity;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.arena.record.ArenaRecord;
|
||||
import net.knarcraft.minigames.arena.record.SummableArenaRecord;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* A helper class for getting combined record data for a dropper group
|
||||
*/
|
||||
public final class DropperGroupRecordHelper {
|
||||
|
||||
private DropperGroupRecordHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the combined least-death records for the given group and game-mode
|
||||
*
|
||||
* @param group <p>The group to get records from</p>
|
||||
* @param gameMode <p>The game-mode to get records for</p>
|
||||
* @return <p>The combined death records</p>
|
||||
*/
|
||||
public static @NotNull Set<ArenaRecord<Integer>> getCombinedDeaths(@NotNull DropperArenaGroup group,
|
||||
@NotNull DropperArenaGameMode gameMode) {
|
||||
Map<UUID, SummableArenaRecord<Integer>> records = new HashMap<>();
|
||||
@NotNull BiFunction<DropperArena, DropperArenaGameMode, Set<SummableArenaRecord<Integer>>> recordSupplier =
|
||||
(arena, aGameMode) -> arena.getData().getRecordRegistries().get(gameMode).getLeastDeathsRecords();
|
||||
|
||||
return getCombined(group, gameMode, records, recordSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the combined least-time records for the given group and game-mode
|
||||
*
|
||||
* @param group <p>The group to get records from</p>
|
||||
* @param gameMode <p>The game-mode to get records for</p>
|
||||
* @return <p>The combined least-time records</p>
|
||||
*/
|
||||
public static @NotNull Set<ArenaRecord<Long>> getCombinedTime(@NotNull DropperArenaGroup group,
|
||||
@NotNull DropperArenaGameMode gameMode) {
|
||||
Map<UUID, SummableArenaRecord<Long>> records = new HashMap<>();
|
||||
@NotNull BiFunction<DropperArena, DropperArenaGameMode, Set<SummableArenaRecord<Long>>> recordSupplier =
|
||||
(arena, aGameMode) -> arena.getData().getRecordRegistries().get(gameMode).getShortestTimeMilliSecondsRecords();
|
||||
|
||||
return getCombined(group, gameMode, records, recordSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the combined records for a group and game-mode
|
||||
*
|
||||
* @param group <p>The group to get combined records for</p>
|
||||
* @param gameMode <p>The game-mode to get records for</p>
|
||||
* @param records <p>The map to store the combined records to</p>
|
||||
* @param recordSupplier <p>The function that supplies records of this type</p>
|
||||
* @param <K> <p>The type of the records to combine</p>
|
||||
* @return <p>The combined records</p>
|
||||
*/
|
||||
private static <K extends Comparable<K>> @NotNull Set<ArenaRecord<K>> getCombined(@NotNull DropperArenaGroup group,
|
||||
@NotNull DropperArenaGameMode gameMode,
|
||||
@NotNull Map<UUID,
|
||||
SummableArenaRecord<K>> records,
|
||||
@NotNull BiFunction<DropperArena,
|
||||
DropperArenaGameMode,
|
||||
Set<SummableArenaRecord<K>>> recordSupplier) {
|
||||
DropperArenaHandler arenaHandler = MiniGames.getInstance().getDropperArenaHandler();
|
||||
|
||||
// Get all arenas in the group
|
||||
Set<DropperArena> arenas = getArenas(arenaHandler, group);
|
||||
|
||||
// Calculate the combined records
|
||||
Map<UUID, Integer> recordsFound = new HashMap<>();
|
||||
combineRecords(arenas, gameMode, records, recordsFound, recordSupplier);
|
||||
|
||||
// Filter out any players that haven't played through all arenas
|
||||
filterRecords(records, recordsFound, arenas.size());
|
||||
|
||||
return new HashSet<>(records.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters away any records that belong to users who haven't set records for all arenas in the group
|
||||
*
|
||||
* @param records <p>The records to filter</p>
|
||||
* @param recordsFound <p>The map of how many records have been registered for each user</p>
|
||||
* @param arenas <p>The number of arenas in the group</p>
|
||||
* @param <K> <p>The type of the given records</p>
|
||||
*/
|
||||
private static <K extends Comparable<K>> void filterRecords(@NotNull Map<UUID, SummableArenaRecord<K>> records,
|
||||
@NotNull Map<UUID, Integer> recordsFound, int arenas) {
|
||||
for (UUID userId : recordsFound.keySet()) {
|
||||
if (recordsFound.get(userId) != arenas) {
|
||||
records.remove(userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all arenas in the given group
|
||||
*
|
||||
* @param arenaHandler <p>The arena handler to get arenas from</p>
|
||||
* @param group <p>The group to get arenas for</p>
|
||||
* @return <p>The arenas found in the group</p>
|
||||
*/
|
||||
private static @NotNull Set<DropperArena> getArenas(@NotNull DropperArenaHandler arenaHandler,
|
||||
@NotNull DropperArenaGroup group) {
|
||||
// Get all arenas in the group
|
||||
Set<DropperArena> arenas = new HashSet<>();
|
||||
for (UUID arenaId : group.getArenas()) {
|
||||
DropperArena arena = arenaHandler.getArena(arenaId);
|
||||
if (arena != null) {
|
||||
arenas.add(arena);
|
||||
}
|
||||
}
|
||||
return arenas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines arena records
|
||||
*
|
||||
* @param arenas <p>The arenas whose records should be combined</p>
|
||||
* @param gameMode <p>The game-mode to combine records for</p>
|
||||
* @param combinedRecords <p>The map to store the combined records to</p>
|
||||
* @param recordsFound <p>The map used to store the number of records registered for each player</p>
|
||||
* @param recordSupplier <p>The function that supplies record data of this type</p>
|
||||
* @param <K> <p>The type of record to combine</p>
|
||||
*/
|
||||
private static <K extends Comparable<K>> void combineRecords(@NotNull Set<DropperArena> arenas,
|
||||
@NotNull DropperArenaGameMode gameMode,
|
||||
@NotNull Map<UUID,
|
||||
SummableArenaRecord<K>> combinedRecords,
|
||||
@NotNull Map<UUID, Integer> recordsFound,
|
||||
@NotNull BiFunction<DropperArena, DropperArenaGameMode,
|
||||
Set<SummableArenaRecord<K>>> recordSupplier) {
|
||||
for (DropperArena arena : arenas) {
|
||||
Set<SummableArenaRecord<K>> existingRecords = recordSupplier.apply(arena, gameMode);
|
||||
// For each arena's record registry, calculate the combined records
|
||||
for (SummableArenaRecord<K> value : existingRecords) {
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
UUID userId = value.getUserId();
|
||||
|
||||
// Bump the number of records found for the user
|
||||
if (!recordsFound.containsKey(userId)) {
|
||||
recordsFound.put(userId, 0);
|
||||
}
|
||||
recordsFound.put(userId, recordsFound.get(userId) + 1);
|
||||
|
||||
// Put the value, or the sum with the existing value, into combined records
|
||||
if (!combinedRecords.containsKey(userId)) {
|
||||
combinedRecords.put(value.getUserId(), value);
|
||||
} else {
|
||||
combinedRecords.put(userId, combinedRecords.get(userId).sum(value.getRecord()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
/**
|
||||
* A helper class for validating whether given input is valid
|
||||
*/
|
||||
public final class InputValidationHelper {
|
||||
|
||||
private InputValidationHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given location is valid
|
||||
*
|
||||
* @param location <p>The location to validate</p>
|
||||
* @return <p>False if the location is valid</p>
|
||||
*/
|
||||
public static boolean isInvalid(Location location) {
|
||||
World world = location.getWorld();
|
||||
return world == null || !world.getWorldBorder().isInside(location);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* A helper class for teleporting players
|
||||
*/
|
||||
public final class PlayerTeleporter {
|
||||
|
||||
private PlayerTeleporter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Teleports the given player to the given location
|
||||
*
|
||||
* <p>Forcing teleport should only be used inside an arena, to prevent the player from becoming stuck.</p>
|
||||
*
|
||||
* @param player <p>The player about to teleport</p>
|
||||
* @param location <p>The location the player should be teleported to</p>
|
||||
* @param force <p>Whether to force a player teleport, even in a vehicle or a passenger</p>
|
||||
* @param immediately <p>Whether to to the teleportation immediately, not using any timers</p>
|
||||
* @return <p>True if the player was successfully teleported</p>
|
||||
*/
|
||||
public static boolean teleportPlayer(Player player, Location location, boolean force, boolean immediately) {
|
||||
if (!player.getPassengers().isEmpty()) {
|
||||
if (force) {
|
||||
for (Entity passenger : player.getPassengers()) {
|
||||
passenger.eject();
|
||||
passenger.teleport(location);
|
||||
}
|
||||
} else {
|
||||
player.sendMessage("You cannot be teleported with a passenger!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (player.isInsideVehicle()) {
|
||||
if (force && player.getVehicle() != null) {
|
||||
Entity vehicle = player.getVehicle();
|
||||
player.eject();
|
||||
vehicle.teleport(location);
|
||||
} else {
|
||||
player.sendMessage("You cannot be teleported while in a vehicle");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Stop the existing player velocity to prevent unevenness between players
|
||||
player.setVelocity(new Vector(0, 0, 0));
|
||||
player.setInvulnerable(true);
|
||||
player.teleport(location);
|
||||
player.setVelocity(new Vector(0, 0, 0));
|
||||
//When teleporting a player out of the arena, sometimes the move listener is slow to react, giving the player
|
||||
// lethal velocity, and causing damage. That's why the player is given 5 ticks of invulnerability
|
||||
if (!immediately) {
|
||||
Bukkit.getScheduler().runTaskLater(MiniGames.getInstance(), () -> player.setInvulnerable(false), 5);
|
||||
} else {
|
||||
player.setInvulnerable(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.container.SerializableContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A converter for converting between normal and serializable classes
|
||||
*/
|
||||
public final class SerializableConverter {
|
||||
|
||||
private SerializableConverter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given collection into a collection of serializable objects
|
||||
*
|
||||
* @param values <p>The values to make serializable</p>
|
||||
* @param targetCollection <p>The collection to store the converted objects to</p>
|
||||
* @param target <p>An instance of the target serializable container</p>
|
||||
* @param <T> <p>The type of the value to make serializable</p>
|
||||
*/
|
||||
public static <T> void makeSerializable(@NotNull Collection<T> values,
|
||||
@NotNull Collection<SerializableContainer<T>> targetCollection,
|
||||
@NotNull SerializableContainer<T> target) {
|
||||
for (T item : values) {
|
||||
targetCollection.add(target.getSerializable(item));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given collection of serializable containers into a collection of normal objects
|
||||
*
|
||||
* @param values <p>The values to convert to normal</p>
|
||||
* @param targetCollection <p>The collection to store the converted objects to</p>
|
||||
* @param <T> <p>The type of the value to convert to normal</p>
|
||||
*/
|
||||
public static <T> void getRawValue(@NotNull Collection<SerializableContainer<T>> values,
|
||||
@NotNull Collection<T> targetCollection) {
|
||||
for (SerializableContainer<T> item : values) {
|
||||
targetCollection.add(item.getRawValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given collection into a collection of serializable objects
|
||||
*
|
||||
* @param values <p>The values to make serializable</p>
|
||||
* @param targetMap <p>The map to store the converted objects to</p>
|
||||
* @param target <p>An instance of the target serializable container</p>
|
||||
* @param <T> <p>The type of the value to make serializable</p>
|
||||
*/
|
||||
public static <S, T> void makeSerializable(@NotNull Map<S, Set<T>> values,
|
||||
@NotNull Map<S, Set<SerializableContainer<T>>> targetMap,
|
||||
@NotNull SerializableContainer<T> target) {
|
||||
for (Map.Entry<S, Set<T>> item : values.entrySet()) {
|
||||
Set<SerializableContainer<T>> conversionCollection = new HashSet<>();
|
||||
makeSerializable(item.getValue(), conversionCollection, target);
|
||||
targetMap.put(item.getKey(), conversionCollection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given collection of serializable containers into a collection of normal objects
|
||||
*
|
||||
* @param values <p>The values to convert to normal</p>
|
||||
* @param targetMap <p>The map to store the converted objects to</p>
|
||||
* @param <S> <p>The type of the map's key</p>
|
||||
* @param <T> <p>The type of the value to convert to normal</p>
|
||||
*/
|
||||
public static <S, T> void getRawValue(@NotNull Map<S, Set<SerializableContainer<T>>> values,
|
||||
@NotNull Map<S, Set<T>> targetMap) {
|
||||
for (Map.Entry<S, Set<SerializableContainer<T>>> item : values.entrySet()) {
|
||||
Set<T> conversionCollection = new HashSet<>();
|
||||
getRawValue(item.getValue(), conversionCollection);
|
||||
targetMap.put(item.getKey(), conversionCollection);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A helper-class for sanitizing strings
|
||||
*/
|
||||
public final class StringSanitizer {
|
||||
|
||||
private StringSanitizer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unwanted characters from a string
|
||||
*
|
||||
* <p>This basically removes character that have a special meaning in YML, or ones that cannot be used in the
|
||||
* chat.</p>
|
||||
*
|
||||
* @param input <p>The string to remove from</p>
|
||||
* @return <p>The string with the unwanted characters removed</p>
|
||||
*/
|
||||
public static @NotNull String removeUnwantedCharacters(@NotNull String input) {
|
||||
return input.replaceAll("[§ :=&]", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes an arena name for usage as a YAML key
|
||||
*
|
||||
* @param arenaName <p>The arena name to sanitize</p>
|
||||
* @return <p>The sanitized arena name</p>
|
||||
*/
|
||||
public static @NotNull String sanitizeArenaName(@NotNull String arenaName) {
|
||||
return arenaName.toLowerCase().trim().replaceAll(" ", "_");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A helper-class for common tab-completions
|
||||
*/
|
||||
public final class TabCompleteHelper {
|
||||
|
||||
private TabCompleteHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of all current arenas
|
||||
*
|
||||
* @return <p>All arena names</p>
|
||||
*/
|
||||
public static @NotNull List<String> getArenas() {
|
||||
List<String> arenaNames = new ArrayList<>();
|
||||
for (DropperArena dropperArena : MiniGames.getInstance().getDropperArenaHandler().getArenas().values()) {
|
||||
arenaNames.add(dropperArena.getArenaName());
|
||||
}
|
||||
return arenaNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the argument strings of all arena properties
|
||||
*
|
||||
* @return <p>All arena properties</p>
|
||||
*/
|
||||
public static @NotNull List<String> getArenaProperties() {
|
||||
List<String> arenaProperties = new ArrayList<>();
|
||||
for (DropperArenaEditableProperty property : DropperArenaEditableProperty.values()) {
|
||||
arenaProperties.add(property.getArgumentString());
|
||||
}
|
||||
return arenaProperties;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user