package com.mengcraft.protect.manager; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.InetAddress; import java.nio.charset.Charset; import java.nio.file.Files; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.bukkit.ChatColor; import com.mengcraft.protect.util.StringMap; import com.mengcraft.protect.util.TimeUtils; public class SegmentManager { private final static SegmentManager MANAGER = new SegmentManager(); private final StringMap<Segment> segments = new StringMap<>(); private SegmentManager() { File file = new File("banned-ip-segments.txt"); if (file.exists()) { initFile(file); } else { createNewFile(file); initFile(file); } } public static SegmentManager getManager() { return MANAGER; } public String[] getMessage() { List<String> strings = new ArrayList<>(); strings.add(ChatColor.RED + "===== 封禁的网段 ====="); for (Segment segment : this.segments.values()) { StringBuilder builder = new StringBuilder(); builder.append(ChatColor.RED); builder.append("地址: ").append(segment.getHost()).append(", "); builder.append("段落: ").append(segment.getLimit()).append(", "); if (segment.getUntil() < 0) { builder.append("剩余: ").append("永久封禁"); } else if (segment.getUntil() < System.currentTimeMillis()) { builder.append("剩余: ").append("已经失效"); } else { TimeUtils time = new TimeUtils(segment.getUntil() - System.currentTimeMillis()); builder.append("剩余: ").append(time.getDay()).append("日").append(time.getHour()).append("时"); } strings.add(builder.toString()); } if (strings.size() < 1) { strings.add(ChatColor.RED + ":-) 暂无"); } return strings.toArray(new String[] {}); } public void createRecord(String addr, int limit, long until) { this.segments.put(addr, new Segment(addr, limit, until)); } public boolean remove(String string) { return this.segments.remove(string) != null; } public void saveLines() { try { save(); } catch (Exception e) { e.printStackTrace(); } } public boolean contains(InetAddress addr) { for (Segment segment : this.segments.values()) { if (segment.contains(addr)) { return true; } } return false; } private void save() throws Exception { File file = new File("banned-ip-segments.txt"); FileWriter out = new FileWriter(file); BufferedWriter writer = new BufferedWriter(out); Collection<Segment> values = this.segments.values(); for (Segment segment : values) { String record = segment.toString(); writer.write(record + "\n"); } writer.close(); } private void createNewFile(File file) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } private void initFile(File file) { List<String> lines = readLines(file); parseLines(lines); } private void parseLines(List<String> lines) { for (String line : lines) { parseLine(line); } } private void parseLine(String line) { String[] split = line.split("\\|"); if (new Long(split[2]) < System.currentTimeMillis()) { return; } try { createRecord(split[0], new Integer(split[1]), new Long(split[2])); } catch (NumberFormatException e) { e.printStackTrace(); } } private List<String> readLines(File file) { try { return Files.readAllLines(file.toPath(), Charset.forName("UTF-8")); } catch (IOException e) { e.printStackTrace(); } return new ArrayList<>(); } public static byte[] getAddrByte(String addr, int limit) { String[] segment = addr.split("\\."); byte[] bs = new byte[limit]; for (int i = 0; i < bs.length; i++) { bs[i] = new Integer(segment[i]).byteValue(); } return bs; } private class Segment { private final String host; private final int limit; private final byte[] segment; private final long until; public Segment(String addr, int limit, long until) { this.host = addr; this.limit = limit; this.segment = SegmentManager.getAddrByte(addr, limit); this.until = until; } public boolean contains(InetAddress key) { if (System.currentTimeMillis() > this.getUntil()) { // TIME HAS PAST } else if (Arrays.equals(this.segment, Arrays.copyOf(key.getAddress(), this.getLimit()))) { return true; } return false; } @Override public String toString() { return getHost() + "|" + getLimit() + "|" + getUntil(); } public long getUntil() { return until; } public String getHost() { return host; } public int getLimit() { return limit; } } }