001package fr.aumgn.dac2.arena; 002 003import java.io.File; 004import java.util.ArrayList; 005import java.util.Collections; 006import java.util.HashMap; 007import java.util.List; 008import java.util.Map; 009 010import org.bukkit.World; 011import org.bukkit.entity.Player; 012 013import fr.aumgn.bukkitutils.geom.Vector; 014import fr.aumgn.bukkitutils.gson.GsonLoadException; 015import fr.aumgn.bukkitutils.gson.GsonLoader; 016import fr.aumgn.dac2.DAC; 017import fr.aumgn.dac2.DACPlugin; 018import fr.aumgn.dac2.arena.regions.StartRegion; 019import fr.aumgn.dac2.exceptions.ArenaDeleteException; 020import fr.aumgn.dac2.exceptions.ArenaSaveException; 021import fr.aumgn.dac2.exceptions.ArenasFolderException; 022 023public class Arenas { 024 025 private static final String DIRECTORY = "arenas"; 026 027 private Map<String, Arena> arenas; 028 029 public Arenas(DAC dac) { 030 load(dac); 031 } 032 033 private File getFolder(DACPlugin plugin) { 034 File folder = new File(plugin.getDataFolder(), DIRECTORY); 035 036 if (folder.exists()) { 037 if (!folder.isDirectory()) { 038 throw new ArenasFolderException( 039 folder.getPath() + " is not a directory."); 040 } 041 } else if (!folder.mkdirs()) { 042 throw new ArenasFolderException( 043 "Unable to create " + folder.getPath() + " directory."); 044 } 045 046 return folder; 047 } 048 049 private String filenameFor(DAC dac, Arena arena) { 050 return getFolder(dac.getPlugin()).getName() + File.separator 051 + arena.getName() + ".json"; 052 } 053 054 private String arenaNameFor(File file) { 055 String name = file.getName(); 056 int index = name.lastIndexOf("."); 057 return name.substring(0, index); 058 } 059 060 public void load(DAC dac) { 061 arenas = new HashMap<String, Arena>(); 062 063 GsonLoader loader = dac.getPlugin().getGsonLoader(); 064 File folder = getFolder(dac.getPlugin()); 065 for (File file : folder.listFiles()) { 066 try { 067 Arena arena = loader.load(file, Arena.class); 068 String nameFromFile = arenaNameFor(file); 069 if (!nameFromFile.equals(arena.getName())) { 070 dac.getLogger().severe("Filename `" + nameFromFile 071 + "` does not match arena's name `" 072 + arena.getName() + "`. Skipping it."); 073 continue; 074 } 075 arenas.put(arena.getName(), arena); 076 } catch (GsonLoadException exc) { 077 dac.getLogger().severe( 078 "Unable to read " + file.getName() + " arena's file."); 079 } 080 } 081 } 082 083 public void saveArena(DAC dac, Arena arena) { 084 saveArena(dac, dac.getPlugin().getGsonLoader(), arena); 085 } 086 087 private void saveArena(DAC dac, GsonLoader loader, Arena arena) { 088 String filename = filenameFor(dac, arena); 089 try { 090 loader.write(filename, arena); 091 } catch (GsonLoadException _) { 092 throw new ArenaSaveException("Unable to save " + filename + "."); 093 } 094 } 095 096 public void saveAll(DAC dac) { 097 for (Arena arena : arenas.values()) { 098 saveArena(dac, dac.getPlugin().getGsonLoader(), arena); 099 } 100 } 101 102 public boolean has(String name) { 103 return arenas.containsKey(name); 104 } 105 106 public Arena get(String name) { 107 return arenas.get(name); 108 } 109 110 /** 111 * Gets the arena in whose start region the player is in. 112 * 113 * If different arena defines start regions which overlap themselves, 114 * the result is undefined. 115 * 116 * @param player 117 * @return the arena 118 */ 119 public Arena get(Player player) { 120 Vector pt = new Vector(player); 121 for (Arena arena : arenas.values()) { 122 StartRegion startRegion = arena.getStartRegion(); 123 if (startRegion != null && startRegion.contains(pt)) { 124 return arena; 125 } 126 } 127 128 return null; 129 } 130 131 public void create(DAC dac, String name, World world) { 132 Arena arena = new Arena(name, world); 133 arenas.put(name, arena); 134 saveArena(dac, arena); 135 } 136 137 public void delete(DAC dac, Arena arena) { 138 arenas.remove(arena.getName()); 139 String filename = filenameFor(dac, arena); 140 File file = new File(dac.getPlugin().getDataFolder(), filename); 141 if (!file.delete()) { 142 throw new ArenaDeleteException("Unable to delete " + filename 143 + " arena's file."); 144 } 145 } 146 147 public List<Arena> all() { 148 return Collections.unmodifiableList(new ArrayList<Arena>( 149 arenas.values())); 150 } 151 152 public int length() { 153 return arenas.values().size(); 154 } 155}