package net.glowstone.util.bans; import net.glowstone.GlowServer; import org.bukkit.BanEntry; import org.bukkit.BanList; import java.io.File; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; /** * Ban list implementation. */ public class GlowBanList extends JsonListFile implements BanList { // 2014-02-12 02:27:08 -0600 static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z"); static final String FOREVER = "Forever"; final Type type; private final Map<String, GlowBanEntry> entryMap = new HashMap<>(); /** * Creates a new BanList of the given type. * @param server The server this BanList belongs to. * @param type The type of BanList. */ public GlowBanList(GlowServer server, Type type) { super(getFile(server, type)); this.type = type; } private static File getFile(GlowServer server, Type type) { switch (type) { case NAME: return new File(server.getConfigDir(), "banned-players.json"); case IP: return new File(server.getConfigDir(), "banned-ips.json"); default: throw new IllegalArgumentException("Unknown BanList type " + type); } } @Override public void load() { super.load(); entryMap.clear(); for (BaseEntry entry : entries) { GlowBanEntry banEntry = ((GlowBanEntry) entry); entryMap.put(banEntry.getTarget(), banEntry); } } @Override protected BaseEntry readEntry(Map<String, String> object) { // target String target; if (type == Type.NAME) { target = object.get("name"); } else if (type == Type.IP) { target = object.get("ip"); } else { throw new RuntimeException("Invalid type in readEntry"); } // other data try { String dateString = object.get("created"); String source = object.get("source"); String expiresString = object.get("expires"); String reason = object.get("reason"); Date created = DATE_FORMAT.parse(dateString); Date expires = null; if (!expiresString.equalsIgnoreCase(FOREVER)) { expires = DATE_FORMAT.parse(expiresString); } return new GlowBanEntry(this, target, reason, created, expires, source); } catch (ParseException e) { throw new RuntimeException("Error reading ban entry", e); } } @Override protected void save() { entries.clear(); entries.addAll(entryMap.values()); super.save(); } /** * Remove expired bans. */ private void expungeBans() { boolean changed = false; Iterator<GlowBanEntry> iter = entryMap.values().iterator(); while (iter.hasNext()) { if (iter.next().isExpired()) { iter.remove(); changed = true; } } if (changed) { save(); } } /** * Save a modified GlowBanEntry back to the ban list. * @param entry The ban entry */ void putEntry(GlowBanEntry entry) { entryMap.put(entry.getTarget(), entry.clone()); save(); } @Override public BanEntry getBanEntry(String target) { expungeBans(); return entryMap.get(target).clone(); } @Override public BanEntry addBan(String target, String reason, Date expires, String source) { GlowBanEntry entry = new GlowBanEntry(this, target, reason, new Date(), expires, source); entryMap.put(target, entry); save(); return entry.clone(); } @Override public Set<BanEntry> getBanEntries() { expungeBans(); Set<BanEntry> result = new HashSet<>(entryMap.size()); for (GlowBanEntry entry : entryMap.values()) { result.add(entry.clone()); } return result; } @Override public boolean isBanned(String target) { expungeBans(); return entryMap.containsKey(target); } @Override public void pardon(String target) { entryMap.remove(target); save(); } }