Java tutorial
/* * 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) { } } } }