package net.knarcraft.dropper.arena; import net.knarcraft.dropper.Dropper; import net.knarcraft.dropper.util.ArenaStorageHelper; import net.knarcraft.dropper.util.StringSanitizer; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; 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 handler that keeps track of all dropper arenas */ public class DropperArenaHandler { private Map arenas = new HashMap<>(); private Map arenaGroups = new HashMap<>(); private Map arenaNameLookup = new HashMap<>(); /** * Gets the group the given arena belongs to * * @param arenaId

The id of the arena to get the group of

* @return

The group the arena belongs to, or null if not in a group

*/ public @Nullable DropperArenaGroup getGroup(@NotNull UUID arenaId) { return this.arenaGroups.get(arenaId); } /** * Sets the group for the given arena * * @param arenaId

The id of the arena to change

* @param arenaGroup

The group to add the arena to, or null to remove the current group

*/ public void setGroup(@NotNull UUID arenaId, @Nullable DropperArenaGroup arenaGroup) { if (arenaGroup == null) { // No need to remove something non-existing if (!this.arenaGroups.containsKey(arenaId)) { return; } // Remove the existing group DropperArenaGroup oldGroup = this.arenaGroups.remove(arenaId); oldGroup.removeArena(arenaId); } else { // Make sure to remove the arena from the old group's internal tracking if (this.arenaGroups.containsKey(arenaId)) { this.arenaGroups.remove(arenaId).removeArena(arenaId); } this.arenaGroups.put(arenaId, arenaGroup); arenaGroup.addArena(arenaId); } saveGroups(); } /** * Gets the dropper arena group with the given name * * @param groupName

The name of the group to get

* @return

The group, or null if not found

*/ public @Nullable DropperArenaGroup getGroup(String groupName) { String sanitized = StringSanitizer.sanitizeArenaName(groupName); for (DropperArenaGroup arenaGroup : this.arenaGroups.values()) { if (arenaGroup.getGroupNameSanitized().equals(sanitized)) { return arenaGroup; } } return null; } /** * Replaces an arena's lookup name * * @param oldName

The arena's old sanitized lookup name

* @param newName

The arena's new sanitized lookup name

*/ public void updateLookupName(@NotNull String oldName, @NotNull String newName) { UUID arenaId = this.arenaNameLookup.remove(oldName); if (arenaId != null) { this.arenaNameLookup.put(newName, arenaId); } } /** * Adds a new arena * * @param arena

The arena to add

*/ public void addArena(@NotNull DropperArena arena) { this.arenas.put(arena.getArenaId(), arena); this.arenaNameLookup.put(arena.getArenaNameSanitized(), arena.getArenaId()); this.saveArenas(); } /** * Gets the arena with the given id * * @param arenaId

The id of the arena to get

* @return

The arena, or null if no arena could be found

*/ public @Nullable DropperArena getArena(@NotNull UUID arenaId) { return this.arenas.get(arenaId); } /** * Gets the arena with the given name * * @param arenaName

The arena to get

* @return

The arena with the given name, or null if not found

*/ public @Nullable DropperArena getArena(@NotNull String arenaName) { return this.arenas.get(this.arenaNameLookup.get(StringSanitizer.sanitizeArenaName(arenaName))); } /** * Gets all known arenas * * @return

All known arenas

*/ public @NotNull Map getArenas() { return new HashMap<>(this.arenas); } /** * Removes the given arena * * @param arena

The arena to remove

*/ public void removeArena(@NotNull DropperArena arena) { Dropper.getInstance().getPlayerRegistry().removeForArena(arena); this.arenas.remove(arena.getArenaId()); this.arenaNameLookup.remove(arena.getArenaNameSanitized()); this.arenaGroups.remove(arena.getArenaId()); this.saveArenas(); } /** * Stores the data for the given arena * * @param arenaId

The id of the arena whose data should be saved

*/ public void saveData(UUID arenaId) { 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()); } } /** * Saves all current dropper groups to disk */ public void saveGroups() { try { ArenaStorageHelper.saveDropperArenaGroups(new HashSet<>(this.arenaGroups.values())); } catch (IOException e) { Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to save current arena groups! " + "Data loss can occur!"); Dropper.getInstance().getLogger().log(Level.SEVERE, e.getMessage()); } } /** * Loads all dropper groups from disk */ public void loadGroups() { Set arenaGroups = ArenaStorageHelper.loadDropperArenaGroups(); Map arenaGroupMap = new HashMap<>(); for (DropperArenaGroup arenaGroup : arenaGroups) { for (UUID arenaId : arenaGroup.getArenas()) { arenaGroupMap.put(arenaId, arenaGroup); } } this.arenaGroups = arenaGroupMap; } /** * Saves all current arenas to disk */ public void saveArenas() { try { ArenaStorageHelper.saveArenas(this.arenas); } catch (IOException e) { Dropper.getInstance().getLogger().log(Level.SEVERE, "Unable to save current arenas! " + "Data loss can occur!"); Dropper.getInstance().getLogger().log(Level.SEVERE, e.getMessage()); } } /** * Loads all arenas from disk */ public void loadArenas() { this.arenas = ArenaStorageHelper.loadArenas(); // Save a map from arena name to arena id for improved performance this.arenaNameLookup = new HashMap<>(); for (Map.Entry arena : this.arenas.entrySet()) { String sanitizedName = arena.getValue().getArenaNameSanitized(); this.arenaNameLookup.put(sanitizedName, arena.getKey()); } } }