package net.knarcraft.placeholdersigns.handler; import net.knarcraft.placeholdersigns.PlaceholderSigns; import net.knarcraft.placeholdersigns.container.PlaceholderSign; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.sign.Side; 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 handler for keeping track of placeholder signs */ public class PlaceholderSignHandler { private static final File signsFile = new File(PlaceholderSigns.getInstance().getDataFolder(), "signs.yml"); private Set placeholderSigns; private Map locationLookup; private Map> signsInChunk; /** * Gets a placeholder sign from the given location * * @param location

The location of the sign

* @return

The sign at the location, or null if no such sign exists

*/ @Nullable public PlaceholderSign getFromLocation(@NotNull Location location) { return locationLookup.get(location); } /** * Registers a new placeholder sign * * @param sign

The sign to register

*/ public void registerSign(@NotNull PlaceholderSign sign) { this.placeholderSigns.add(sign); this.locationLookup.put(sign.getLocation(), sign); Chunk chunk = sign.getLocation().getChunk(); this.signsInChunk.putIfAbsent(chunk, new HashSet<>()); this.signsInChunk.get(chunk).add(sign); } /** * Un-registers a placeholder sign * * @param sign

The sign to un-register

*/ public void unregisterSign(@NotNull PlaceholderSign sign) { this.locationLookup.remove(sign.getLocation()); this.placeholderSigns.remove(sign); this.signsInChunk.get(sign.getLocation().getChunk()).remove(sign); PlaceholderSigns.getInstance().getUpdateQueueHandler().unQueueSign(sign); } /** * Gets all placeholder signs in the given chunk * * @param chunk

The chunk to check

* @return

All placeholder signs in the chunk

*/ @NotNull public Set getFromChunk(@NotNull Chunk chunk) { if (this.signsInChunk.containsKey(chunk)) { return this.signsInChunk.get(chunk); } else { return new HashSet<>(); } } /** * Loads all placeholder signs from disk */ public void load() { this.placeholderSigns = new HashSet<>(); this.locationLookup = new HashMap<>(); this.signsInChunk = new HashMap<>(); YamlConfiguration configuration = YamlConfiguration.loadConfiguration(signsFile); ConfigurationSection signSection = configuration.getConfigurationSection("signs"); if (signSection == null) { PlaceholderSigns.getInstance().getLogger().log(Level.INFO, "PlaceholderSigns found no signs to load"); return; } for (String key : signSection.getKeys(false)) { String[] locationInfo = key.split(","); World world = Bukkit.getWorld(UUID.fromString(locationInfo[0])); double x = Integer.parseInt(locationInfo[1]); double y = Integer.parseInt(locationInfo[2]); double z = Integer.parseInt(locationInfo[3]); Location signLocation = new Location(world, x, y, z); Map> allPlaceholders = new HashMap<>(); Map frontPlaceholders = new HashMap<>(); Map backPlaceholders = new HashMap<>(); loadPlaceholders(signSection, key + ".placeholders.front.", frontPlaceholders); loadPlaceholders(signSection, key + ".placeholders.back.", backPlaceholders); allPlaceholders.put(Side.FRONT, frontPlaceholders); allPlaceholders.put(Side.BACK, backPlaceholders); String updateDelayKey = key + ".updateDelay"; int updateDelay = -1; if (signSection.contains(updateDelayKey)) { updateDelay = signSection.getInt(updateDelayKey, -1); } if (updateDelay < 1) { updateDelay = PlaceholderSigns.getInstance().getSignUpdateDelay(); } registerSign(new PlaceholderSign(signLocation, allPlaceholders, updateDelay)); } } /** * Loads placeholders from one side of a sign * * @param signSection

The configuration section to read

* @param configurationKey

The configuration key pointing to the placeholders

* @param placeholderMap

The map to add read placeholders to

*/ private void loadPlaceholders(@NotNull ConfigurationSection signSection, @NotNull String configurationKey, @NotNull Map placeholderMap) { for (int i = 0; i < 4; i++) { String placeholderKey = configurationKey + i; if (!signSection.contains(placeholderKey)) { continue; } String placeholder = signSection.getString(placeholderKey); placeholderMap.put(i, placeholder); } } /** * Saves all current placeholder signs */ public void save() { try { YamlConfiguration configuration = new YamlConfiguration(); ConfigurationSection signsSection = configuration.createSection("signs"); for (PlaceholderSign sign : placeholderSigns) { saveSign(signsSection, sign); } configuration.save(signsFile); } catch (IOException exception) { PlaceholderSigns.getInstance().getLogger().log(Level.SEVERE, "Unable to save placeholder signs!"); } } /** * Saves a sign to the given configuration section * * @param section

The configuration section to save to

* @param sign

The sign to save

*/ private void saveSign(@NotNull ConfigurationSection section, @NotNull PlaceholderSign sign) { Location location = sign.getLocation(); if (location.getWorld() == null) { return; } String key = location.getWorld().getUID() + "," + location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ(); String frontKey = key + ".placeholders.front"; String backKey = key + ".placeholders.back"; Map frontPlaceholders = sign.getPlaceholders().get(Side.FRONT); if (frontPlaceholders != null) { for (Map.Entry entry : frontPlaceholders.entrySet()) { section.set(frontKey + "." + entry.getKey(), entry.getValue()); } } Map backPlaceholders = sign.getPlaceholders().get(Side.BACK); if (backPlaceholders != null) { for (Map.Entry entry : backPlaceholders.entrySet()) { section.set(backKey + "." + entry.getKey(), entry.getValue()); } } section.set(key + ".updateDelay", sign.getUpdateDelay()); } }