io.minimum.minecraft.rbclean.RedisBungeeClean.java Source code

Java tutorial

Introduction

Here is the source code for io.minimum.minecraft.rbclean.RedisBungeeClean.java

Source

// Licensed under the Unlicense; see LICENSE in the main directory.
package io.minimum.minecraft.rbclean;

import com.google.gson.Gson;
import org.apache.commons.cli.*;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.GZIPOutputStream;

public class RedisBungeeClean {
    public static void main(String... args) {
        Options options = new Options();

        Option hostOption = new Option("h", "host", true, "Sets the Redis host to use.");
        hostOption.setRequired(true);
        options.addOption(hostOption);

        Option portOption = new Option("p", "port", true, "Sets the Redis port to use.");
        options.addOption(portOption);

        Option passwordOption = new Option("w", "password", true, "Sets the Redis password to use.");
        options.addOption(passwordOption);

        Option dryRunOption = new Option("d", "dry-run", false, "Performs a dry run (no data is modified).");
        options.addOption(dryRunOption);

        CommandLine commandLine;

        try {
            commandLine = new DefaultParser().parse(options, args);
        } catch (ParseException e) {
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp("RedisBungeeClean", options);
            return;
        }

        int port = commandLine.hasOption('p') ? Integer.parseInt(commandLine.getOptionValue('p')) : 6379;

        try (Jedis jedis = new Jedis(commandLine.getOptionValue('h'), port, 0)) {
            if (commandLine.hasOption('w')) {
                jedis.auth(commandLine.getOptionValue('w'));
            }

            System.out.println("Fetching UUID cache...");
            Map<String, String> uuidCache = jedis.hgetAll("uuid-cache");
            Gson gson = new Gson();

            // Just in case we need it, compress everything in JSON format.
            if (!commandLine.hasOption('d')) {
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
                File file = new File("uuid-cache-previous-" + dateFormat.format(new Date()) + ".json.gz");
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    System.out.println("Can't write backup of the UUID cache, will NOT proceed.");
                    e.printStackTrace();
                    return;
                }

                System.out.println("Creating backup (as " + file.getName() + ")...");

                try (OutputStreamWriter bw = new OutputStreamWriter(
                        new GZIPOutputStream(new FileOutputStream(file)))) {
                    gson.toJson(uuidCache, bw);
                } catch (IOException e) {
                    System.out.println("Can't write backup of the UUID cache, will NOT proceed.");
                    e.printStackTrace();
                    return;
                }
            }

            System.out.println("Cleaning out the bird cage (this may take a while...)");
            int originalSize = uuidCache.size();
            for (Iterator<Map.Entry<String, String>> it = uuidCache.entrySet().iterator(); it.hasNext();) {
                CachedUUIDEntry entry = gson.fromJson(it.next().getValue(), CachedUUIDEntry.class);

                if (entry.expired()) {
                    it.remove();
                }
            }
            int newSize = uuidCache.size();

            if (commandLine.hasOption('d')) {
                System.out.println(
                        (originalSize - newSize) + " records would be expunged if a dry run was not conducted.");
            } else {
                System.out.println("Expunging " + (originalSize - newSize) + " records...");
                Transaction transaction = jedis.multi();
                transaction.del("uuid-cache");
                transaction.hmset("uuid-cache", uuidCache);
                transaction.exec();
                System.out.println("Expunging complete.");
            }
        }
    }

    private class CachedUUIDEntry {
        private final String name;
        private final UUID uuid;
        private final Calendar expiry;

        private CachedUUIDEntry(String name, UUID uuid, Calendar expiry) {
            this.name = name;
            this.uuid = uuid;
            this.expiry = expiry;
        }

        public boolean expired() {
            return Calendar.getInstance().after(expiry);
        }
    }
}