package net.knarcraft.blockhunt.util; import net.knarcraft.blockhunt.MemoryStorage; import net.knarcraft.blockhunt.arena.Arena; import net.knarcraft.blockhunt.arena.ArenaState; import net.knarcraft.blockhunt.config.ConfigKey; import net.knarcraft.blockhunt.config.MessageKey; import org.bukkit.Location; import org.bukkit.block.Sign; import org.bukkit.block.sign.Side; import org.bukkit.event.block.SignChangeEvent; import java.util.List; public final class SignsHelper { private SignsHelper() { } public static void createSign(SignChangeEvent event, String[] lines, Location location) { if (lines[1] != null) { if (lines[1].equalsIgnoreCase("leave")) { saveSign("leave", location); } else if (lines[1].equalsIgnoreCase("shop")) { saveSign("shop", location); } else { boolean saved = false; Arena arena = MemoryStorage.arenaMap.get(lines[1].toLowerCase()); if (arena != null) { saveSign(arena.arenaName, location); saved = true; } if (!saved) { MessageHelper.sendMessage(event.getPlayer(), MessageKey.ERROR_NO_ARENA, "name-" + lines[1]); } } } } private static void saveSign(String key, Location location) { boolean saved = false; int number = 1; while (!saved) { if (MemoryStorage.signs.getFileConfiguration().get(key + "_" + number) == null) { MemoryStorage.signs.getFileConfiguration().set(key + "_" + number + ".arenaName", key); MemoryStorage.signs.getFileConfiguration().set(key + "_" + number + ".location", location); MemoryStorage.signs.save(); saved = true; } else { number = number + 1; } } } public static void removeSign(Location location) { //TODO: This seems really inefficient for (String sign : MemoryStorage.signs.getFileConfiguration().getKeys(false)) { Location signLocation = (Location) MemoryStorage.signs.getFileConfiguration().get(sign + ".location"); if (signLocation != null && signLocation.equals(location)) { MemoryStorage.signs.getFileConfiguration().set(sign, null); MemoryStorage.signs.save(); } } } public static boolean isSign(Location location) { //TODO: This seems really inefficient for (String sign : MemoryStorage.signs.getFileConfiguration().getKeys(false)) { Location loc = (Location) MemoryStorage.signs.getFileConfiguration().get(sign + ".location"); if (loc == null) { throw new IllegalArgumentException("Sign location could not be loaded."); } if (loc.equals(location)) { return true; } } return false; } public static void updateSigns() { //TODO: Instead of this awful method of signs updating every second for no reason, it would be preferable for // sign changes to be directly triggered when its contents changes MemoryStorage.signs.load(); //TODO: This loads from disk once every second which seems unnecessary for (String sign : MemoryStorage.signs.getFileConfiguration().getKeys(false)) { Location location = (Location) MemoryStorage.signs.getFileConfiguration().get(sign + ".location"); if (location == null) { throw new IllegalArgumentException("Sign location could not be loaded."); } if (location.getWorld() == null) { throw new IllegalArgumentException("Sign world is null!"); } // check if that area is actually loaded. If not move on. if (!location.getWorld().isChunkLoaded(location.getBlockX() >> 4, location.getBlockZ() >> 4)) { continue; } if (location.getBlock().getState() instanceof Sign signBlock) { String[] lines = signBlock.getSide(Side.FRONT).getLines(); if (sign.contains("leave")) { drawSign(MemoryStorage.config.getFileConfiguration().getStringList(ConfigKey.SIGN_LEAVE.getPath()), signBlock); } else if (sign.contains("shop")) { drawSign(MemoryStorage.config.getFileConfiguration().getStringList(ConfigKey.SIGN_SHOP.getPath()), signBlock); } else { drawArenaSign(lines[1], signBlock); } } else { removeSign(location); } } } private static void drawArenaSign(String arenaName, Sign signBlock) { //TODO: Store the relationships between signs and arenas directly for (Arena arena : MemoryStorage.arenaMap.values()) { //Find the correct arena if (!arenaName.endsWith(arena.arenaName)) { continue; } if (arena.gameState.equals(ArenaState.WAITING)) { drawSign(MemoryStorage.config.getFileConfiguration().getStringList(ConfigKey.SIGN_WAITING.getPath()), signBlock, arena); } else if (arena.gameState.equals(ArenaState.STARTING)) { drawSign(MemoryStorage.config.getFileConfiguration().getStringList(ConfigKey.SIGN_STARTING.getPath()), signBlock, arena); } else if (arena.gameState.equals(ArenaState.IN_GAME)) { drawSign(MemoryStorage.config.getFileConfiguration().getStringList(ConfigKey.SIGN_IN_GAME.getPath()), signBlock, arena); } } } private static void drawSign(List signLines, Sign signBlock, Arena arena) { drawSign(signLines, signBlock, "arenaName-" + arena.arenaName, "players-" + arena.playersInArena.size(), "maxplayers-" + arena.maxPlayers, "timeleft-" + arena.timer); } private static void drawSign(List signLines, Sign signBlock, String... variables) { int lineCount = 0; for (String line : signLines) { if (lineCount <= 3) { signBlock.getSide(Side.FRONT).setLine(lineCount, MessageHelper.replaceAll(line, variables)); } lineCount = lineCount + 1; } signBlock.update(); } }