uuidupdater.DatabaseTool.java Source code

Java tutorial

Introduction

Here is the source code for uuidupdater.DatabaseTool.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package uuidupdater;

import com.mojang.api.profiles.HttpProfileRepository;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bson.types.ObjectId;

/**
 *
 * @author Jonas
 */
public class DatabaseTool {

    private Mongo mongo = null;
    private String db, collection;
    private HttpProfileRepository hpr;
    private final int MAX_THREADS;
    private HashMap<String, HashSet<ObjectId>> occurencies = new HashMap<>();
    private HashMap<ObjectId, HashSet<String>> players = new HashMap<>();

    public DatabaseTool(String host, int port, int threads) {
        this(threads);
        try {
            this.mongo = new Mongo(host, port);
            db = null;
            collection = null;
        } catch (UnknownHostException ex) {
            Logger.getLogger(DatabaseTool.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public DatabaseTool(int threads) {
        this.MAX_THREADS = threads;
        hpr = new HttpProfileRepository("minecraft", threads);
    }

    public void connect(String host, int port) throws UnknownHostException {
        this.mongo = new Mongo(host, port);
        db = null;
        collection = null;
    }

    public boolean isConnected() {
        try {
            mongo.getConnector().getDBPortPool(mongo.getAddress()).get().ensureOpen();
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    public boolean isDBValid(String db) {
        return db != null && mongo.getDatabaseNames().contains(db);
    }

    public boolean isCollectionValid(String collection) {
        if (db == null)
            throw new UnsupportedOperationException("The db needs to be set first!");
        else
            return collection != null && mongo.getDB(db).getCollectionNames().contains(collection);
    }

    public void setDB(String db) {
        if (isDBValid(db))
            this.db = db;
        else
            throw new UnsupportedOperationException("The db is not valid!");
    }

    public void setCollection(String collection) {
        if (isCollectionValid(collection))
            this.collection = collection;
        else
            throw new UnsupportedOperationException("The db is not valid!");
    }

    public void updateCollection(String playerfield, String uuidfield, boolean remove) {
        try {
            System.out.println();
            System.out.println("Settings: ");
            System.out.println("DB: " + db);
            System.out.println("Collection: " + collection);
            System.out.println("Playerfield: " + playerfield);
            System.out.println("UUIDfield: " + uuidfield);
            System.out.println("Remove playerfield: " + remove);
            System.out.println();

            long start = System.currentTimeMillis();
            long timeTaken = System.currentTimeMillis();

            HashSet<String[]> names = readCollection(playerfield);
            int count = 0;
            for (String[] n : names) {
                n = shortenArray(n);
                count += n.length;
            }
            timeTaken = System.currentTimeMillis() - timeTaken;
            System.out.println("Loaded " + count + " players from the db in " + timeTaken / 1000. + "s");
            timeTaken = System.currentTimeMillis();
            HashMap<String, String> profiles = loadProfiles(names);
            timeTaken = System.currentTimeMillis() - timeTaken;
            count = profiles.size();
            System.out.println("Loaded " + count + " UUIDs in " + timeTaken / 1000. + "s");
            timeTaken = System.currentTimeMillis();
            updateProfiles(profiles, playerfield, uuidfield, remove);
            timeTaken = System.currentTimeMillis() - timeTaken;
            count = 0;
            for (HashSet<ObjectId> set : occurencies.values()) {
                count += set.size();
            }
            System.out.println("Updated " + count + " player profiles in " + timeTaken / 1000. + "s"
                    + " (total time: " + (System.currentTimeMillis() - start) / 1000. + "s)");
        } catch (InterruptedException ex) {
            Logger.getLogger(DatabaseTool.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private HashSet<String[]> readCollection(String playerfield) {
        DBCursor dbc = mongo.getDB(db).getCollection(collection).find();
        HashSet<String> playernames = new HashSet<>();
        HashSet<String[]> lookupArrays = new HashSet<>();
        boolean isList = mongo.getDB(db).getCollection(collection)
                .findOne(new BasicDBObject(playerfield, new BasicDBObject("$exists", true)))
                .get(playerfield) instanceof BasicDBList;

        while (dbc.hasNext()) {
            DBObject dbo = dbc.next();
            ObjectId oid = (ObjectId) dbo.get("_id");
            if (!dbo.containsField(playerfield))
                continue;
            if (!isList) {
                String playername = (String) dbo.get(playerfield);
                if (!playernames.contains(playername)) {
                    playernames.add(playername);
                    occurencies.put(playername, new HashSet<ObjectId>());
                }
                if (!players.containsKey(oid)) {
                    players.put(oid, new HashSet<String>());
                }
                players.get(oid).add(playername);
                occurencies.get(playername).add(oid);
            } else {
                for (Object object : (BasicDBList) dbo.get(playerfield)) {
                    String playername = (String) object;
                    if (!playernames.contains(playername)) {
                        playernames.add(playername);
                        occurencies.put(playername, new HashSet<ObjectId>());
                    }
                    if (!players.containsKey(oid)) {
                        players.put(oid, new HashSet<String>());
                    }
                    players.get(oid).add(playername);
                    occurencies.get(playername).add(oid);
                }
            }
        }
        Iterator iterator = playernames.iterator();
        while (iterator.hasNext()) {
            String[] next100 = new String[100];
            int i = 0;
            while (i < 100 && iterator.hasNext()) {
                next100[i] = (String) iterator.next();
                i++;
            }
            if (!iterator.hasNext()) {
                next100 = shortenArray(next100);
            }
            lookupArrays.add(next100);
        }
        return lookupArrays;
    }

    private void updateProfiles(HashMap<String, String> profiles, String playerfield, String uuidfield,
            boolean remove) {
        DBCollection collection = mongo.getDB(db).getCollection(this.collection);
        boolean isList = collection.findOne(new BasicDBObject(playerfield, new BasicDBObject("$exists", true)))
                .get(playerfield) instanceof BasicDBList;
        if (!isList) {
            for (String name : profiles.keySet()) {
                for (ObjectId _id : occurencies.get(name)) {
                    BasicDBObject query = new BasicDBObject();
                    query.put("_id", _id);
                    BasicDBObject updateObj = new BasicDBObject();
                    updateObj.put("$set", new BasicDBObject(uuidfield, profiles.get(name)));
                    if (remove)
                        updateObj.put("$unset", new BasicDBObject(playerfield, ""));
                    collection.update(query, updateObj, false, false);
                }
            }
        } else {
            for (ObjectId oid : players.keySet()) {
                BasicDBObject query = new BasicDBObject();
                query.put("_id", oid);
                BasicDBObject updateObj = new BasicDBObject();
                BasicDBList updateList = new BasicDBList();
                for (String name : players.get(oid)) {
                    updateList.add(profiles.get(name));

                }
                updateObj.put("$set", new BasicDBObject(uuidfield, updateList));
                if (remove)
                    updateObj.put("$unset", new BasicDBObject(playerfield, ""));
                collection.update(query, updateObj, false, false);
            }
        }
    }

    private HashMap<String, String> loadProfiles(HashSet<String[]> names) throws InterruptedException {
        return hpr.findProfilesByNames(names);
    }

    private String[] shortenArray(String[] array) {
        ArrayList<String> shortArray = new ArrayList<>();
        for (String s : array) {
            if (s != null)
                shortArray.add(s);
            else
                break;
        }
        return shortArray.toArray(new String[0]);
    }

    public void updateCollection(String db, String collection, String playerfield, String uuidfield,
            boolean remove) {
        setDB(db);
        setCollection(collection);
        updateCollection(playerfield, uuidfield, remove);
    }

    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        System.out.print("Enter max used threads: ");
        int threads = scan.nextInt();
        DatabaseTool dt = new DatabaseTool(threads);
        while (!dt.isConnected()) {
            System.out.print("Enter dbhost: ");
            String host = scan.next();

            System.out.print("Enter dbport: ");
            int port = scan.nextInt();

            try {
                dt.connect(host, port);
            } catch (Exception ex) {
                System.out.println("Could not connect to the database");
                System.exit(0);
            }
        }

        while (true) {
            try {
                final String db, collection, playerfield, uuidfield;
                final boolean deletePlayerfield;
                dt.occurencies.clear();
                dt.players.clear();

                System.out.print("Enter DB: ");
                db = scan.next();
                dt.setDB(db);

                System.out.print("Enter Collection: ");
                collection = scan.next();
                dt.setCollection(collection);

                System.out.print("Enter name of playerfield: ");
                playerfield = scan.next();

                System.out.print("Enter name of new uuidfield: ");
                uuidfield = scan.next();

                System.out.print("Delete playerfield: ");
                deletePlayerfield = scan.nextBoolean();

                dt.updateCollection(playerfield, uuidfield, deletePlayerfield);
            } catch (UnsupportedOperationException e) {

            }
        }
    }
}