DatabaseManager.java 3.92 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package emu.grasscutter.database;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.mongodb.MongoCommandException;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;

import dev.morphia.Datastore;
import dev.morphia.Morphia;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.inventory.GenshinItem;

KingRainbow44's avatar
KingRainbow44 committed
18
public final class DatabaseManager {
Melledy's avatar
Melledy committed
19
	private static MongoClient mongoClient;
20
21
	private static MongoClient dispatchMongoClient;

Melledy's avatar
Melledy committed
22
	private static Datastore datastore;
23
	private static Datastore dispatchDatastore;
Melledy's avatar
Melledy committed
24
	
KingRainbow44's avatar
KingRainbow44 committed
25
	private static final Class<?>[] mappedClasses = new Class<?>[] {
Melledy's avatar
Melledy committed
26
27
28
29
30
31
		DatabaseCounter.class, Account.class, GenshinPlayer.class, GenshinAvatar.class, GenshinItem.class, Friendship.class
	};
    
    public static MongoClient getMongoClient() {
        return mongoClient;
    }
32
33
34
35
36
37

	public static Datastore getDatastore() {
		return datastore;
	}

	public static MongoDatabase getDatabase() {
Melledy's avatar
Melledy committed
38
39
    	return getDatastore().getDatabase();
    }
40

Benjamin Elsdon's avatar
Benjamin Elsdon committed
41
42
	// Yes. I very dislike this method. However, this will be good for now.
	// TODO: Add dispatch routes for player account management
43
44
45
46
47
48
49
	public static Datastore getAccountDatastore() {
		if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
			return dispatchDatastore;
		} else {
			return datastore;
		}
	}
Melledy's avatar
Melledy committed
50
51
52
53
	
	public static void initialize() {
		// Initialize
		mongoClient = new MongoClient(new MongoClientURI(Grasscutter.getConfig().DatabaseUrl));
KingRainbow44's avatar
KingRainbow44 committed
54
		Morphia morphia = new Morphia();
Melledy's avatar
Melledy committed
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
		
		// TODO Update when migrating to Morphia 2.0
		morphia.getMapper().getOptions().setStoreEmpties(true);
		morphia.getMapper().getOptions().setStoreNulls(false);
		morphia.getMapper().getOptions().setDisableEmbeddedIndexes(true);
		
		// Map
		morphia.map(mappedClasses);
		
		// Build datastore
		datastore = morphia.createDatastore(mongoClient, Grasscutter.getConfig().DatabaseCollection);
		
		// Ensure indexes
		try {
			datastore.ensureIndexes();
		} catch (MongoCommandException e) {
			Grasscutter.getLogger().info("Mongo index error: ", e);
			// Duplicate index error
			if (e.getCode() == 85) {
				// Drop all indexes and re add them
				MongoIterable<String> collections = datastore.getDatabase().listCollectionNames();
				for (String name : collections) {
					datastore.getDatabase().getCollection(name).dropIndexes();
				}
				// Add back indexes
				datastore.ensureIndexes();
			}
		}
83

Benjamin Elsdon's avatar
Benjamin Elsdon committed
84
85
86
87
88
89
		if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
			dispatchMongoClient = new MongoClient(new MongoClientURI(Grasscutter.getConfig().getGameServerOptions().DispatchServerDatabaseUrl));
			dispatchDatastore = morphia.createDatastore(dispatchMongoClient, Grasscutter.getConfig().getGameServerOptions().DispatchServerDatabaseCollection);

			// Ensure indexes for dispatch server
			try {
90
				dispatchDatastore.ensureIndexes();
Benjamin Elsdon's avatar
Benjamin Elsdon committed
91
92
93
94
95
96
97
98
99
100
101
102
			} catch (MongoCommandException e) {
				Grasscutter.getLogger().info("Mongo index error: ", e);
				// Duplicate index error
				if (e.getCode() == 85) {
					// Drop all indexes and re add them
					MongoIterable<String> collections = dispatchDatastore.getDatabase().listCollectionNames();
					for (String name : collections) {
						dispatchDatastore.getDatabase().getCollection(name).dropIndexes();
					}
					// Add back indexes
					dispatchDatastore.ensureIndexes();
				}
103
104
			}
		}
Melledy's avatar
Melledy committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
	}
	
	public static synchronized int getNextId(Class<?> c) {
		DatabaseCounter counter = getDatastore().createQuery(DatabaseCounter.class).field("_id").equal(c.getSimpleName()).find().tryNext();
		if (counter == null) {
			counter = new DatabaseCounter(c.getSimpleName());
		}
		try {
			return counter.getNextId();
		} finally {
			getDatastore().save(counter);
		}
	}
	
	public static synchronized int getNextId(Object o) {
		return getNextId(o.getClass());
	}
}