/* * Copyright (c) 2010 SimpleServer authors (see CONTRIBUTORS) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package simpleserver.config.data; import static simpleserver.lang.Translations.t; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import simpleserver.Coordinate; import simpleserver.Player; import simpleserver.config.LegacyChestList; import simpleserver.nbt.NBT; import simpleserver.nbt.NBTCompound; import simpleserver.nbt.NBTList; import simpleserver.nbt.NBTString; public class Chests { private final static String CHESTS = "chests"; private NBTCompound root; private final ConcurrentMap<Coordinate, Chest> locations; public Chests() { locations = new ConcurrentHashMap<Coordinate, Chest>(); } void load(NBTCompound data) { root = data; locations.clear(); NBTList<NBTCompound> node; if (data.containsKey(CHESTS)) { try { node = data.getList(CHESTS).cast(); loadChests(node); return; } catch (Exception e) { System.out.println("[WARNING] Chest list is corrupt. Replacing it with empty list..."); } finally { freeMemory(); } } loadOldConfig(); } private void loadChests(NBTList<NBTCompound> node) { for (int i = 0; i < node.size(); i++) { NBTCompound tag = node.get(i); Coordinate coord; try { coord = new Coordinate(tag.getCompound("coordinate")); } catch (Exception e) { System.out.println("Skipping corrupt chest"); continue; } Chest chest; if (!tag.containsKey("owner")) { chest = new Chest(coord); } else { String owner = tag.getString("owner").get(); if (!tag.containsKey("name")) { chest = new Chest(owner, coord); } else { chest = new Chest(owner, coord, tag.getString("name").get()); } } locations.put(coord, chest); } } private void loadOldConfig() { LegacyChestList old = new LegacyChestList(); old.load(); for (Coordinate coord : old.locations.keySet()) { simpleserver.config.LegacyChestList.Chest chest = old.locations.get(coord); if (chest.isOpen()) { locations.put(coord, new Chest(coord)); } else if (chest.name().equals("Locked chest") || chest.name().length() == 0) { locations.put(coord, new Chest(chest.owner(), coord)); } else { locations.put(coord, new Chest(chest.owner(), coord, chest.name())); } } old.save(); } void save() { NBTList<NBTCompound> node = new NBTList<NBTCompound>(CHESTS, NBT.COMPOUND); for (Chest chest : locations.values()) { NBTCompound tag = new NBTCompound(); tag.put(chest.coordinate.tag()); if (!chest.isOpen()) { tag.put(new NBTString("owner", chest.owner.toLowerCase())); if (chest.name != null) { tag.put(new NBTString("name", chest.name)); } } node.add(tag); } root.put(node); } void freeMemory() { if (root.containsKey(CHESTS)) { root.remove(CHESTS); } } public Chest get(Coordinate coordinate) { if (isChest(coordinate)) { return locations.get(coordinate); } else { return null; } } public boolean isLocked(Coordinate coordinate) { return isChest(coordinate) && !get(coordinate).isOpen(); } public void releaseLock(Coordinate coordinate) { locations.remove(coordinate); } public boolean isChest(Coordinate coordinate) { return locations.containsKey(coordinate); } public Chest adjacentChest(Coordinate coordinate) { Chest chest = get(coordinate.add(1, 0, 0)); if (chest == null) { chest = get(coordinate.add(-1, 0, 0)); } if (chest == null) { chest = get(coordinate.add(0, 0, 1)); } if (chest == null) { chest = get(coordinate.add(0, 0, -1)); } return chest; } public boolean canOpen(Player player, Coordinate coordinate) { return !isLocked(coordinate) || get(coordinate).ownedBy(player); } public void unlock(Coordinate coordinate) { if (isChest(coordinate)) { get(coordinate).unlock(); Chest adjacent = adjacentChest(coordinate); if (adjacent != null) { adjacent.unlock(); } } } public String chestName(Coordinate coordinate) { if (isLocked(coordinate)) { if (get(coordinate).name != null) { return get(coordinate).name; } else { return t("Locked Chest"); } } else { return t("Open Chest"); } } public void giveLock(String owner, Coordinate coordinate, String name) { if (isChest(coordinate)) { Chest chest = get(coordinate); chest.name = name; chest.owner = owner; } else { locations.put(coordinate, new Chest(owner, coordinate, name)); } } public void giveLock(Player player, Coordinate coordinate, String name) { giveLock(player.getName().toLowerCase(), coordinate, name); } public void addOpenChest(Coordinate coordinate) { locations.put(coordinate, new Chest(coordinate)); } public Map<String, Integer> chestList(Player player) { Map<String, Integer> list = new HashMap<String, Integer>(); for (Chest chest : locations.values()) { if (chest.ownedBy(player)) { if (list.containsKey(chest.name)) { list.put(chest.name, list.get(chest.name) + 1); } else { list.put(chest.name, 1); } } } if (list.containsKey(null)) { list.put(t("Locked Chest"), list.get(null)); list.remove(null); } return list; } public List<Chest> getChestsByName(String name) { List<Chest> chests = new ArrayList<Chest>(); for (Chest chest : locations.values()) { if (chest.name != null && chest.name.equals(name)) { chests.add(chest); } } return chests; } public static final class Chest { public String owner; public final Coordinate coordinate; public String name; private Chest(String player, Coordinate coordinate, String name) { owner = player; this.coordinate = coordinate; this.name = name; } private Chest(String player, Coordinate coordinate) { owner = player; this.coordinate = coordinate; } private Chest(Coordinate coordinate) { this.coordinate = coordinate; } public boolean isOpen() { return owner == null; } public void lock(Player player) { owner = player.getName().toLowerCase(); } public void unlock() { owner = null; name = null; } public boolean ownedBy(Player player) { return owner != null && owner.equals(player.getName().toLowerCase()); } } }