Jail Plugin

Discussion in 'Plugin Development' started by mehboss, Dec 28, 2016.

Thread Status:
Not open for further replies.
  1. Offline

    Drkmaster83

    The following code that I'm posting is functional in its entirety through the use of a HashMap system (because we need to store the player with their jailtime value) that stores the player's UUID as well as an Integer which defines the duration of time they're going to spend in jail. First, we create a task that starts when the plugin is enabled, which ticks every second; this is how we will understand how a player has served their time. Every second, we will update the player's time served in the HashMap by looping through the HashMap's keys and checking various things, such as their online status, whether or not they can be freed, and if they're still serving. You may add implementation to the jail and unjail methods respectively. When the server is started up and shut down, the config values are loaded into the HashMap for quick access, and then stored back in the file (JailTimes.yml, created in the onEnable()) every 2 minutes (denoted by backupPeriod) as well as a soft shutdown of the server. The command for splitting the parts of time utilizes regex, but could use native String methods that don't require regex as well, it'd just make the program longer. I was going to add a system for the duration of the period of the jail time, but I got lazy. As for my utility methods, I've broken up the saving and loading to and from the file into two methods, and also created a helper method for making a String into a number. I also created an non-deprecated version of the getPlayer() method that is not static and makes getting to a player by their name easy in the onCommand. Again, if you have any questions or don't understand why I did something specific, or don't even know the meaning of one of the words, let me know. Normally, I'd have more comments, but this is my second go at this. To further clarify, I have changed nothing from the OP's code since there was not much (at least legible code) to go off of. I have detailed the functionality and why I've structureded the program as it is in the above paragraph.
    Code:
    public static HashMap<UUID, Integer> jailTimes;
    private File jailFile;
    private FileConfiguration jailConfig;
    
    @Override
    public void onEnable() {
        jailTimes = new HashMap<UUID, Integer>();
        jailFile = new File(getDataFolder(), "JailTimes.yml");
        jailConfig = YamlConfiguration.loadConfiguration(jailFile);
     
        loadJailTimes();
     
        final int backupPeriod = 120;
        new BukkitRunnable() {
            int i = 0;
            @Override
            public void run() {
                i++;
                if(i >= backupPeriod) {
                    saveJailTimes();
                    i = 0;
                }
             
                for(UUID u : jailTimes.keySet()) {
                    Player p = getServer().getPlayer(u);
                    if(p == null || !p.isOnline()) {
                        continue;
                    }
                 
                    if(jailTimes.get(p.getUniqueId()) <= 0) {
                        unjailPlayer(p);
                    }
                    else {
                        jailTimes.put(p.getUniqueId(), jailTimes.get(p.getUniqueId()) - 1);
                    }
                }
            }
        }.runTaskTimer(this, 20, 20);
    }
    
    @Override
    public void onDisable() {
        saveJailTimes();
    }
    
    public void loadJailTimes() {
        for(String s : jailConfig.getKeys(false)) {
            UUID u = UUID.fromString(s);
            jailPlayer(getServer().getPlayer(u), jailConfig.getInt(s));
        }
    }
    
    public void saveJailTimes() {
        for(UUID u : jailTimes.keySet()) {
            jailConfig.set(u.toString(), jailTimes.get(u));
        }
        try {
            jailConfig.save(jailFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public void jailPlayer(Player p, int durationSecs) {
        if(p == null || !p.isOnline()) return;
        jailTimes.put(p.getUniqueId(), durationSecs); //Debating whether to set it in config
        p.sendMessage(ChatColor.RED + "Unfortunately, you've been jailed!");
    }
    
    public void unjailPlayer(Player p) {
        jailTimes.remove(p.getUniqueId());
        jailConfig.set(p.getUniqueId().toString(), null);
        try {
            jailConfig.save(jailFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        p.sendMessage(ChatColor.GREEN + "You're free to go.");
    }
    
    public Player getPlayer(String name) {
        for(Player p : getServer().getOnlinePlayers()) {
            if(p.getName().equalsIgnoreCase(name)) return p;
        }
        return null;
    }
    
    public int getNumber(String num) {
        try {
            return Integer.parseInt(num);
        }
        catch (NumberFormatException e) {
            return 0;
        }
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
        if(cmd.getName().equalsIgnoreCase("Jail")) {
            if(args.length == 0) {
                sender.sendMessage(ChatColor.RED + "A player and time duration is needed to jail someone.");
                sender.sendMessage(ChatColor.RED + "Command format: /jail <player> <time>");
            }
            else if(args.length == 1) {
                if(getPlayer(args[0]) == null || !getPlayer(args[0]).isOnline()) {
                    sender.sendMessage(ChatColor.RED + "Sorry, but " + args[0] + " is not online.");
                    return true;
                }
                if(jailTimes.containsKey(getPlayer(args[0]).getUniqueId())) {
                    unjailPlayer(getPlayer(args[0]));
                    sender.sendMessage(ChatColor.GREEN + args[0] + " has been unjailed.");
                    return true;
                }
                sender.sendMessage(ChatColor.RED + "A time duration is needed to jail " + args[0] + ".");
            }
            else if(args.length == 2) {
                // /jail <person> 1h(or 1m, or 1s) or /jail <person> 1h29m44s[
                if(getPlayer(args[0]) == null || !getPlayer(args[0]).isOnline()) {
                    sender.sendMessage(ChatColor.RED + "Sorry, but " + args[0] + " is not online.");
                    return true;
                }
                String parse = args[1].replaceAll("[\\.,]", "").replaceAll("([hmsHMS]){1}", "$1'");
                String[] times = parse.split("'");
                int totalSecs = 0;
                for(String s : times) {
                    if(s.contains("h")) totalSecs += getNumber(s.replace("h", "")) * 3600;
                    else if(s.contains("m")) totalSecs += getNumber(s.replace("m", "")) * 60;
                    else if(s.contains("s")) totalSecs += getNumber(s.replace("s", ""));
                    else {
                        if(getNumber(s) == 0) {
                            sender.sendMessage(ChatColor.RED + "Could not parse jail time, as " + s + " is an invalid argument.");
                            return true;
                        }
                        else totalSecs += getNumber(s);
                    }
                }
                jailPlayer(getPlayer(args[0]), totalSecs);
            }
            else { // > 2
                // /jail <person> 1h 29m 44s
                if(getPlayer(args[0]) == null || !getPlayer(args[0]).isOnline()) {
                    sender.sendMessage(ChatColor.RED + "Sorry, but " + args[0] + " is not online.");
                    return true;
                }
                String parse = String.join("", args).replaceAll("[\\.,]", "").replaceAll("([hmsHMS]){1}", "$1'");
                String[] times = parse.split("'");
                int totalSecs = 0;
                for(String s : times) {
                    if(s.contains("h")) totalSecs += getNumber(s.replace("h", "")) * 3600;
                    else if(s.contains("m")) totalSecs += getNumber(s.replace("m", "")) * 60;
                    else if(s.contains("s")) totalSecs += getNumber(s.replace("s", ""));
                    else {
                        if(getNumber(s) == 0) {
                            sender.sendMessage(ChatColor.RED + "Could not parse jail time, as " + s + " is an invalid argument.");
                            return true;
                        }
                        else totalSecs += getNumber(s);
                    }
                }
                jailPlayer(getPlayer(args[0]), totalSecs);
            }
            return true;
        }
        return false;
    }
    
     
  2. Offline

    WolfMage1

    Essentials actually had a nice util for doing things like in your second solution, give me a minute and I can find it.

    EDIT:
    Code:
    private static Pattern timePattern = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
    
        public static long parseDateDiff(String time, boolean future) throws Exception
        {
            Matcher m = timePattern.matcher(time);
            int years = 0;
            int months = 0;
            int weeks = 0;
            int days = 0;
            int hours = 0;
            int minutes = 0;
            int seconds = 0;
            boolean found = false;
            while (m.find())
            {
                if (m.group() == null || m.group().isEmpty())
                {
                    continue;
                }
                for (int i = 0; i < m.groupCount(); i++)
                {
                    if (m.group(i) != null && !m.group(i).isEmpty())
                    {
                        found = true;
                        break;
                    }
                }
                if (found)
                {
                    if (m.group(1) != null && !m.group(1).isEmpty())
                    {
                        years = Integer.parseInt(m.group(1));
                    }
                    if (m.group(2) != null && !m.group(2).isEmpty())
                    {
                        months = Integer.parseInt(m.group(2));
                    }
                    if (m.group(3) != null && !m.group(3).isEmpty())
                    {
                        weeks = Integer.parseInt(m.group(3));
                    }
                    if (m.group(4) != null && !m.group(4).isEmpty())
                    {
                        days = Integer.parseInt(m.group(4));
                    }
                    if (m.group(5) != null && !m.group(5).isEmpty())
                    {
                        hours = Integer.parseInt(m.group(5));
                    }
                    if (m.group(6) != null && !m.group(6).isEmpty())
                    {
                        minutes = Integer.parseInt(m.group(6));
                    }
                    if (m.group(7) != null && !m.group(7).isEmpty())
                    {
                        seconds = Integer.parseInt(m.group(7));
                    }
                    break;
                }
            }
            if (!found)
            {
                throw new Exception(tl("illegalDate"));
            }
            Calendar c = new GregorianCalendar();
            if (years > 0)
            {
                c.add(Calendar.YEAR, years * (future ? 1 : -1));
            }
            if (months > 0)
            {
                c.add(Calendar.MONTH, months * (future ? 1 : -1));
            }
            if (weeks > 0)
            {
                c.add(Calendar.WEEK_OF_YEAR, weeks * (future ? 1 : -1));
            }
            if (days > 0)
            {
                c.add(Calendar.DAY_OF_MONTH, days * (future ? 1 : -1));
            }
            if (hours > 0)
            {
                c.add(Calendar.HOUR_OF_DAY, hours * (future ? 1 : -1));
            }
            if (minutes > 0)
            {
                c.add(Calendar.MINUTE, minutes * (future ? 1 : -1));
            }
            if (seconds > 0)
            {
                c.add(Calendar.SECOND, seconds * (future ? 1 : -1));
            }
            Calendar max = new GregorianCalendar();
            max.add(Calendar.YEAR, 10);
            if (c.after(max))
            {
                return max.getTimeInMillis();
            }
            return c.getTimeInMillis();
        }
     
    Last edited: Jan 31, 2017
Thread Status:
Not open for further replies.

Share This Page