Package com.sk89q.commandbook.bans

Source Code of com.sk89q.commandbook.bans.CSVBanDatabase

package com.sk89q.commandbook.bans;

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;
import com.sk89q.commandbook.util.ChatUtil;
import com.sk89q.commandbook.util.ServerUtil;
import com.sk89q.commandbook.util.entity.player.UUIDUtil;
import org.apache.commons.lang.Validate;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import java.io.*;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.logging.*;
import java.util.logging.Formatter;

import static com.sk89q.commandbook.CommandBook.logger;

public class CSVBanDatabase implements BanDatabase {

    protected final Logger auditLogger
            = Logger.getLogger("Minecraft.CommandBook.Bans");

    protected final File storageFile;

    /**
     * Used to lookup bans by UUID
     */
    protected Map<UUID, Ban> UUIDBan = new HashMap<UUID, Ban>();

    /**
     * Used to lookup bans by name
     */
    @Deprecated
    protected Map<String, Ban> nameBan = null;

    /**
     * Used to lookup bans by ip address
     */
    protected Map<String, Ban> ipBan = new HashMap<String, Ban>();

    /**
     * A set of all bans. No ban in the lookup maps is not in here.
     */
    protected final Set<Ban> bans = new HashSet<Ban>();

    private static final SimpleDateFormat dateFormat =
            new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

    public CSVBanDatabase(File banStorageDir) {
        storageFile = new File(banStorageDir, "bans.csv");

         // Set up an audit trail
        try {
            FileHandler handler = new FileHandler(
                    (new File(banStorageDir, "bans.%g.%u.log")).getAbsolutePath()
                    .replace("\\", "/"), true);

            handler.setFormatter(new Formatter() {

                @Override
                public String format(LogRecord record) {
                    return "[" + dateFormat.format(new Date())
                            + "] " + record.getMessage() + "\r\n";
                }
            });

            auditLogger.addHandler(handler);
        } catch (SecurityException e) {
            logger().warning("Failed to setup audit log for the "
                    + "CSV ban database: " + e.getMessage());
        } catch (IOException e) {
            logger().warning("Failed to setup audit log for the "
                    + "CSV ban database: " + e.getMessage());
        }
    }

    public synchronized boolean load() {
        FileInputStream input = null;
        boolean successful = true;
        boolean needsSaved = false;

        try {
            input = new FileInputStream(storageFile);
            InputStreamReader streamReader = new InputStreamReader(input, "utf-8");
            CSVReader reader = new CSVReader(new BufferedReader(streamReader));
            String[] line;

            while ((line = reader.readNext()) != null) {
                int lineLen = line.length;
                if (lineLen < 5) {
                    logger().warning("A ban entry with < 5 fields was found!");
                    continue;
                }
                try {
                    int i = 0;
                    UUID ID = null;
                    if (lineLen > 5) {
                        String rawLine = line[i++];
                        if (!rawLine.isEmpty() && !rawLine.equals("null")) {
                            ID = UUID.fromString(rawLine);
                        }
                    }
                    String name = line[i++].toLowerCase();
                    String address = line[i++];
                    String reason = line[i++];
                    long startDate = Long.parseLong(line[i++]);
                    long endDate = Long.parseLong(line[i++]);
                    if ("".equals(name) || "null".equals(name)) name = null;
                    if ("".equals(address) || "null".equals(address)) address = null;
                    if ("".equals(reason) || "null".equals(reason)) reason = null;
                    Ban ban = new Ban(ID, name, address, reason, startDate, endDate);
                    if (ID != null) {
                        UUIDBan.put(ID, ban);
                    } else if (name != null) {
                        logger().finest("Converting " + name + "'s ban record to UUID...");
                        ID = UUIDUtil.convert(name);
                        if (ID != null) {
                            // Update the record
                            ban = new Ban(ID, name, address, reason, startDate, endDate);
                            UUIDBan.put(ID, ban);

                            // Log & request save
                            needsSaved = true;
                            logger().finest("Success!");
                        } else {
                            if (nameBan == null) {
                                nameBan = new HashMap<String, Ban>();
                            }
                            nameBan.put(name, ban);
                            logger().warning(ban.toString() + " could not be converted!");
                        }
                    }
                    if (address != null) ipBan.put(address, ban);
                    bans.add(ban);
                } catch (IllegalArgumentException i) {
                    if (i instanceof NumberFormatException) {
                        logger().warning("Non-long long field found in ban!");
                    } else {
                        logger().warning("Invalid UUID field found in ban!");
                    }
                }
            }
            logger().info(bans.size() + " banned name(s) loaded.");
        } catch (FileNotFoundException ignored) {
        } catch (IOException e) {
            nameBan = new HashMap<String, Ban>();
            ipBan = new HashMap<String, Ban>();
            logger().warning("Failed to load " + storageFile.getAbsolutePath()
                    + ": " + e.getMessage());
            successful = false;
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException ignored) {
                }
            }
        }
        if (needsSaved) save();
        return successful;
    }

    public synchronized boolean save() {
        FileOutputStream output = null;
        boolean successful = true;

        try {
            output = new FileOutputStream(storageFile);
            CSVWriter writer = new CSVWriter(new BufferedWriter(new OutputStreamWriter(output, "utf-8")));
            String[] line;

            for (Ban ban : bans) {
                line = new String[] {
                        String.valueOf(ban.getID()),
                        ban.getLastKnownAlias(),
                        ban.getAddress(),
                        ban.getReason(),
                        String.valueOf(ban.getStart()),
                        String.valueOf(ban.getEnd())
                };
                writer.writeNext(line);
            }
            writer.flush();
            writer.close();
        } catch (IOException e) {
            logger().warning("Failed to save " + storageFile.getAbsolutePath()
                    + ": " + e.getMessage());
            successful = false;
        } finally {
            if (output != null) {
                try {
                    output.close();
                } catch (IOException ignored) {
                }
            }
        }
        return successful;
    }

    public boolean unload() {
        for (Handler handler : auditLogger.getHandlers()) {
            if (handler instanceof FileHandler) {
                handler.flush();
                handler.close();
                auditLogger.removeHandler(handler);
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean isBanned(UUID ID) {
        Ban ban = UUIDBan.get(ID);
        if (ban != null) {
            if (ban.getEnd() != 0L && ban.getEnd() - System.currentTimeMillis() <= 0) {
                unban(ID, null, null, "Tempban expired");
                save();
                return false;
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean isBanned(InetAddress address) {
        Ban ban = ipBan.get(address.getHostAddress());
        if (ban != null) {
            if (ban.getEnd() != 0L && ban.getEnd() - System.currentTimeMillis() <= 0) {
                unban(null, address.getHostAddress(), null, "Tempban expired");
                save();
                return false;
            }
            return true;
        }
        return false;
    }

    @Override
    public String getBannedMessage(UUID ID) {
        Ban ban = UUIDBan.get(ID);
        if (ban == null || ban.getReason() == null) return "You are banned.";
        return ban.getReason();
    }

    @Override
    public String getBannedMessage(String address) {
        Ban ban = ipBan.get(address);
        if (ban == null || ban.getReason() == null) return "You are banned by IP.";
        return ban.getReason();
    }

    public void ban(Player player, CommandSender source, String reason, long end) {
        ban(player.getUniqueId(), player.getName(), player.getAddress().getAddress().getHostAddress(), source, reason, end);
    }

    @Override
    public void ban(UUID ID, String name, String address, CommandSender source, String reason, long end) {
        Validate.isTrue(ID != null || address != null, "You must specify either an ID, or address");
        Ban ban = new Ban(ID, name, address, reason, System.currentTimeMillis(), end);
        if (ID != null) {
            Ban oldBan = UUIDBan.remove(ID);
            if (oldBan != null) {
                bans.remove(oldBan);
            }
            UUIDBan.put(ID, ban);
        }
        if (address != null) {
            Ban oldBan = ipBan.remove(address);
            if (oldBan != null) {
                bans.remove(oldBan);
            }
            ipBan.put(address, ban);
        }
        bans.add(ban);
        auditLogger.info(String.format("BAN: %s (%s) added %s: %s",
            source == null ? "Plugin" : ChatUtil.toUniqueName(source),
            source == null ? "local" : ServerUtil.toInetAddressString(source),
            ban.toString(),
            reason));
    }

    @Override
    public boolean unbanName(String name, CommandSender source, String reason) {
        if (nameBan == null || name == null || name.isEmpty()) return false;
        Ban ban = nameBan.remove(name.toLowerCase());
        if (ban != null) {
            bans.remove(ban);
            auditLogger.info(String.format("UNBAN: %s (%s) removed %s: %s",
                    source == null ? "Plugin" : ChatUtil.toUniqueName(source),
                    source == null ? "local" : ServerUtil.toInetAddressString(source),
                    ban.toString(),
                    reason));
            return true;
        }
        return false;
    }

    @Override
    public boolean unban(Player player, CommandSender source, String reason) {
        return unban(player.getUniqueId(), null, source, reason);
    }

    @Override
    public boolean unban(UUID ID, String address, CommandSender source, String reason) {
        Ban ban = null;
        if (ID != null) {
            ban = UUIDBan.remove(ID);
        }
        if (ban == null && address != null) {
            ban = ipBan.remove(address);
        }
        if (ban != null) {
            bans.remove(ban);
            auditLogger.info(String.format("UNBAN: %s (%s) removed %s: %s",
                    source == null ? "Plugin" : ChatUtil.toUniqueName(source),
                    source == null ? "local" : ServerUtil.toInetAddressString(source),
                    ban.toString(),
                    reason));
            return true;
        }
        return false;
    }

    public void logKick(Player player, CommandSender source, String reason) {
        auditLogger.info(String.format("KICKED: %s (%s) kicked player '%s': %s",
                ChatUtil.toUniqueName(source),
                ServerUtil.toInetAddressString(source),
                player.getName(),
                reason));
    }

    public void importFrom(BanDatabase bans) {
        for (Ban ban : bans) {
            boolean set = false;
            if (ban.getID() != null) {
                set = true;
                UUIDBan.put(ban.getID(), ban);
            }
            if (ban.getAddress() != null && !ban.getAddress().isEmpty()) {
                set = true;
                ipBan.put(ban.getAddress(), ban);
            }
            if (set) {
                this.bans.add(ban);
            } else {
                logger().warning(ban.toString() + " could not be imported!");
            }
        }
    }

    @Override
    public Ban getBanned(UUID ID) {
        return UUIDBan.get(ID);
    }

    @Override
    public Ban getBanned(String address) {
        return ipBan.get(address);
    }

    public Iterator<Ban> iterator() {
        return new Iterator<Ban>() {
            private final Iterator<Ban> setIter = bans.iterator();
            private Ban next;
            public boolean hasNext() {
                return setIter.hasNext();
            }

            public Ban next() {
                return next = setIter.next();
            }

            public void remove() {
                unban(next.getID(), next.getAddress(), null, "Removed by iterator");
            }
        };
    }
}
TOP

Related Classes of com.sk89q.commandbook.bans.CSVBanDatabase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.